├── envato-cache └── README.txt ├── example.php ├── README.md ├── commission-split.php └── class.envato_scraper.php /envato-cache/README.txt: -------------------------------------------------------------------------------- 1 | make this folder writable so the PHP script can cache results 2 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | do_login('username','password'); 7 | $statement = $my_scraper->get_statement('1/2013'); 8 | $items = $my_scraper->get_users_items('dtbaker',array('codecanyon','themeforest')); // doesn't work with debug enabled. 9 | 10 | echo "
"; 11 | echo "My Statement: \n"; 12 | print_r($statement); 13 | echo "My Items: \n"; 14 | print_r($items); 15 | echo ""; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | envato-scraper 2 | ============== 3 | 4 | 5 | This simple PHP class scrapes the CSV statment down from Envato. 6 | 7 | Example Usage: 8 | 9 | ```php 10 | // return all dtbaker items from ThemeForest and CodeCanyon 11 | require_once 'class.envato_scraper.php'; 12 | $my_scraper = new envato_scraper(); 13 | $my_scraper->do_login('username','password'); 14 | $statement = $my_scraper->get_statement('1/2013'); 15 | $items = $my_scraper->get_users_items('dtbaker',array('codecanyon','themeforest')); // doesn't work with debug enabled. 16 | 17 | echo "My Statement: \n"; 18 | print_r($statement); 19 | echo "My Items: \n"; 20 | print_r($items); 21 | ``` 22 | 23 | Example Output: 24 |
25 | My Statement: 26 | Array 27 | ( 28 | [0] => Array 29 | ( 30 | [type] => sale 31 | [date] => 2013-01-31 23:43:06 +1100 32 | [time] => 1359636186 33 | [item] => WordPress Email Ticket Support Plugin 34 | [item_id] => 254823 35 | [envato_item_id] => 0 36 | [earnt] => 15.40 37 | [amount] => 22.00 38 | [rate] => 70.0 39 | ) 40 | 41 | [1] => Array 42 | ( 43 | [type] => sale 44 | [date] => 2013-01-31 22:16:25 +1100 45 | [time] => 1359630985 46 | [item] => PHP Search Engine 47 | [item_id] => 89499 48 | [envato_item_id] => 0 49 | [earnt] => 7.00 50 | [amount] => 10.00 51 | [rate] => 70.0 52 | ) 53 | etc..... 54 | My Items: 55 | Array 56 | ( 57 | [0] => Array 58 | ( 59 | [item_id] => 2621629 60 | [preview_image] => http://1.s3.envato.com/files/30243603/preview-ucm-pro_renew-invoices_pdf_customer-database_emails.jpg 61 | [cost] => 60 62 | [sales] => 53 63 | [name] => Ultimate Client Manager - Pro Edition 64 | [category] => Php-scripts / Project-management-tools 65 | [thumb_image] => http://0.s3.envato.com/files/30243602/thumb-ucm-pro_open-source-php-database.png 66 | [url] => http://codecanyon.net/item/ultimate-client-manager-pro-edition/2621629 67 | [marketplace] => http://codecanyon.net 68 | ) 69 | 70 | [1] => Array 71 | ( 72 | [item_id] => 2616958 73 | [preview_image] => http://2.s3.envato.com/files/30196302/preview-customer-job-discussion-project-management-plugin.jpg 74 | [cost] => 6 75 | [sales] => 7 76 | [name] => UCM Plugin: Project Discussion / Customer Comments 77 | [category] => Php-scripts / Project-management-tools 78 | [thumb_image] => http://3.s3.envato.com/files/30196301/thumb-customer-project-comments-and-discussion.png 79 | [url] => http://codecanyon.net/item/ucm-plugin-project-discussion-customer-comments/2616958 80 | [marketplace] => http://codecanyon.net 81 | ) 82 | 83 | [2] => Array 84 | ( 85 | etc... 86 |87 | -------------------------------------------------------------------------------- /commission-split.php: -------------------------------------------------------------------------------- 1 | array( // REPLACE THIS WITH THE ITEM ID YOU WISH TO CALCULATE COMMISSION SPLITS ON 31 | 'start_date' => '2/2013', // WHAT MONTH TO START COMMISSION CALCULATIONS FROM ( in m/Y format, eg: 1/2012 or 12/2011 ) 32 | 'authors' => array( 33 | 'your_author_name_here' => array( 34 | 'split' => 0.5, // percentage here (eg: 50% is 0.5) 35 | 'total' => 0, 36 | ), 37 | 'other_author_name_here' => array( 38 | 'split' => 0.5, // percentage here (eg: 50% is 0.5) 39 | 'total' => 0, 40 | ), 41 | // add more authors here if you need to split 3 or more ways. 42 | ), 43 | ), 44 | // add more item configurations here if needed. 45 | ); 46 | 47 | 48 | /** END CONFIGURATION AREA **/ 49 | 50 | 51 | $item_id = isset($_REQUEST['item_id']) ? (int)$_REQUEST['item_id'] : false; 52 | if(!$item_id || !isset($splits[$item_id]))exit; 53 | require_once 'class.envato_scraper.php'; 54 | $my_scraper = new envato_scraper(); 55 | $my_scraper->do_login(_ENVATO_USERNAME,_ENVATO_PASSWORD); 56 | $statement = $my_scraper->get_statement($splits[$item_id]['start_date']); 57 | $menu_months = array(); 58 | foreach($statement as $item){ 59 | if(isset($item['item_id']) && $item['item_id'] == $item_id){ 60 | $key = date('Y/m',$item['time']); 61 | if(!isset($menu_months[$key]))$menu_months[$key] = array( 62 | 'sales'=> array(), 63 | 'label'=>date('F Y',$item['time']), 64 | ); 65 | $menu_months[$key]['sales'][] = $item; 66 | } 67 | } 68 | ?> 69 | 70 | 71 | 72 | 73 |
Extra comments from the buyer:
#imsU',$match,$comments)){ 653 | $this_review['review'] = trim($comments[1]); 654 | } 655 | 656 | $reviews[] = $this_review; 657 | 658 | } 659 | 660 | }else{ 661 | echo 'no matches'; 662 | } 663 | $page_number++; 664 | } 665 | 666 | return $reviews; 667 | } 668 | 669 | 670 | /** 671 | * This method handles all the remote URL gets, and caching. 672 | * 673 | * @param string $url Url to get: eg http://themeforest.net/user/dtbaker 674 | * @param array $post Any post data to send (eg: login details) 675 | * @param bool $force Force it to refresh, aka: dont read from cache. 676 | * @return string HTML data that came back from request. 677 | * @param bool $ajax adds a 'X-Requested-With: XMLHttpRequest' header to the request to mimic an ajax request. 678 | */ 679 | private $_got_url_from_cache = false; 680 | public function get_url($url,$post=array(),$force=true,$ajax=false){ 681 | 682 | $cache_key = md5(_ENVATO_SECRET . $url . serialize($post)); 683 | $data = ($force) ? false : $this->_get_cache($cache_key); 684 | if(!$data){ 685 | 686 | 687 | $ch=curl_init(); 688 | curl_setopt($ch, CURLOPT_URL, $url); 689 | curl_setopt($ch, CURLOPT_HEADER, 0); 690 | // curl_setopt($ch, CURLOPT_HEADER, _ENVATO_DEBUG_MODE); // debug 691 | curl_setopt($ch, CURLINFO_HEADER_OUT, _ENVATO_DEBUG_MODE); // debug 692 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 693 | curl_setopt($ch, CURLOPT_TIMEOUT, 20); 694 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 695 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 696 | if($ajax) curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Requested-With: XMLHttpRequest')); 697 | $cookies = _ENVATO_TMP_DIR.'cookie-'.md5(_ENVATO_SECRET.$this->username.__FILE__); 698 | curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); 699 | curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies); 700 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0); 701 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 702 | curl_setopt($ch, CURLOPT_USERAGENT, "EnvatoScraper/1.1 (compatible;)"); 703 | curl_setopt($ch, CURLOPT_VERBOSE, 0); 704 | 705 | if($post){ 706 | curl_setopt($ch, CURLOPT_POST, true); 707 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 708 | 709 | } 710 | 711 | $data = curl_exec($ch); 712 | 713 | // $last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 714 | // echo $last_url; 715 | 716 | if(_ENVATO_DEBUG_MODE){ 717 | $headers = curl_getinfo($ch, CURLINFO_HEADER_OUT); 718 | // echo '(.*)
headers for url '.$url.'
';var_dump($headers);echo '
'; 719 | file_put_contents(_ENVATO_TMP_DIR."envato_request-".preg_replace('#[^a-z]#','',$url).".html",$data); 720 | if(preg_match('#Not Allowed#',$data)){ 721 | echo "Failed with nginx not allowed on request $url with post data:
"; print_r($post); 722 | } 723 | } 724 | $this->_save_cache($cache_key,$data); 725 | $this->_got_url_from_cache=false; 726 | }else{ 727 | $this->_got_url_from_cache=true; 728 | } 729 | return $data; 730 | 731 | } 732 | /** caching so we don't hit envato too much **/ 733 | private function _get_cache($key){ 734 | if(is_file(_ENVATO_TMP_DIR.'cache-'.basename($key))){ 735 | return @unserialize(file_get_contents(_ENVATO_TMP_DIR.'cache-'.basename($key))); 736 | } 737 | return false; 738 | } 739 | private function _save_cache($key,$data){ 740 | file_put_contents(_ENVATO_TMP_DIR.'cache-'.basename($key),serialize($data)); 741 | return true; 742 | } 743 | // wack everything on 1 line for easier regex scraping 744 | private function _clean($data){ 745 | $data = preg_replace("/\r|\n/","",$data); 746 | $data = preg_replace("/\s+/"," ",$data); 747 | return $data; 748 | } 749 | 750 | /** 751 | * 752 | * This method will return the current authenticity_token of the given marketplace. 753 | * 754 | * @param string $marketplace 755 | * 756 | * @return token 757 | */ 758 | public function get_authenticity_token($marketplace = ''){ 759 | 760 | if(empty($marketplace)) $marketplace = $this->main_marketplace; 761 | 762 | $marketplace_tag = str_replace('.net','',str_replace('http://','',$marketplace)); 763 | 764 | return isset($this->authenticity_tokens[$marketplace_tag]) ? $this->authenticity_tokens[$marketplace_tag] : false; 765 | } 766 | 767 | 768 | } 769 | --------------------------------------------------------------------------------