Вход Регистрация
Файл: gapps/src/Lib/Api/GoogleApps.php
Строк: 691
<?php

namespace LibApi;

/**
 * LibApiGoogleApps
 * 
 * __DESCRIPTION__
 *
 * @package namespace LibApi;
 * @category GoogleApps
 * @author  Anthony Pillos <dev.anthonypillos@gmail.com>
 * @copyright Copyright (c) 2017
 * @version v1
 */

use Cache;
use 
CarbonCarbon;

use 
SymfonyComponentDomCrawlerCrawler;
use 
CampoUserAgent;
use 
GuzzleHttpClient;
use 
GuzzleHttpExceptionClientException;
use 
GuzzleHttpExceptionGuzzleException;
use 
Exception;

class 
GoogleApps
{

    private 
$url      'https://play.google.com';
    private 
$appUrl   'https://play.google.com/store/apps';

    public 
$filters = [
        
'top_free' => 'topselling_free',
        
'top_paid' => 'topselling_paid',
        
'new_free' => 'topselling_new_free',
        
'new_paid' => 'topselling_new_paid',
        
'grossing' => 'topgrossing',
        
'trending' => 'movers_shakers',
    ];

    
// public $sort = [
    //     'newest'        => 0,
    //     'rating'        => 1,
    //     'helpfulness'   => 2
    // ];

    // public $age = [
    //     'five_under'    => 'AGE_RANGE1',
    //     'six_eight'     => 'AGE_RANGE2',
    //     'nine_up'       => 'AGE_RANGE3',
    // ];


    
public $opts = [
        
'lang'          => 'en',
        
'country'       => 'us',
        
'start'         => 0,
        
'max_result'    => 60
    
];

    private 
$webClient;

    
/**
    * __construct()
    * Initialize our Class Here for Dependecy Injection
    *
    * @return void
    * @access  public
    **/
    
public function __construct()
    {

        
$this->opts['lang'] = env('SET_LOCALE');
        
$this->webClient = new Client(array(
            
'headers' => array('User-Agent' => UserAgent::random())
        ));
    }

    
/**
    * setOptions()
    * 
    *
    * @return void
    * @access  public
    **/
    
public function setOptions($opt = [])
    {
        
$opts array_merge($this->opts,$opt);
        
$this->opts $opts;
        return 
$this;
    }

    
/**
    * topApps()
    * 
    *
    * @return void
    * @access  public
    **/
    
public function topApps()
    {
        
        
$this->appUrl .= '/top'.'?hl='.$this->opts['lang'].'&gl='.$this->opts['country'];

        
$that $this;
        
$content Cache::remember('top_apps'1500, function() use ($that) {
            
$response $that->webClient->get($that->appUrl);
            
$content $response->getBody()->getContents();

            
$crawler = new Crawler($content);

            
$response =  $crawler->filter('div.browse-page .cluster-container')
                            ->
each(function(Crawler $crawler,$i) use($that) {

                                
$name       trim($crawler->filter('a.title-link')->text()); 
                                
$identifier str_slug($name); 


                                
$linkUrl array_filter(explode('/'$crawler->filter('a.title-link')->attr('href')));

                                
$link route('frontend.collection',isset($linkUrl[4]) ? $linkUrl[4] : '#');

                                if( isset(
$linkUrl[5]) && isset($linkUrl[6]) )
                                    
$link route('frontend.category',[$linkUrl[4],$linkUrl[5].DIRECTORY_SEPARATOR.$linkUrl[6] ]);

                                
$topArr = [
                                    
'name' => $name,
                                    
'link' => $link
                                
];

                                
$apps $crawler->filter('div.card-content')->each(function(Crawler $node,$i)  use($that) {
                                    return 
$that->cardContent($node);
                                });

                                
$topArr['apps'] = $apps;
                                return 
$topArr;
                            });
            
            return 
$response;
        });
        return 
$content;
    }

    
/**
    * lists()
    * 
    * @return void
    * @access  public
    **/
    
public function lists($filter 'movers_shakers')
    {
        
        
$this->appUrl .= '/collection/'.$filter;
        
$this->appUrl .= '?start='.$this->opts['start'].'&num='.$this->opts['max_result'].'&hl='.$this->opts['lang'].'&gl='.$this->opts['country'];
        
        try {
            
$response $this->webClient->get($this->appUrl);
            
$content $response->getBody()->getContents();

            
$crawler = new Crawler($content);

            
$name       trim($crawler->filter('.cluster-heading h2')->text()); 

            
$content $crawler->filter('div.card-content')->each(function(Crawler $node,$i) use ($filter){
                    return 
$this->cardContent($node);
                });

            return [
                
'name' => $name,
                
'apps'  => $content
            
];

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
    }


    
/**
    * detail()
    *
    * @return void
    * @access  public
    **/
    
public function details($appId,$opts = [])
    {
        if(!
$appId)
            throw new 
Exception("No App Url Found"1);
        
        
$options array_merge($this->opts,$opts);
        
$params = [
            
'id' => $appId,
            
'hl' => $options['lang'],
            
'gl' => $options['country'],
        ];
        
$query http_build_query($params);

        
$detailUrl $this->appUrl.'/details?'.$query;

        try {

            
$that $this;
            
$content Cache::remember(str_slug(trim($appId)) , 1500, function() use ($that,$detailUrl,$query) {

                
$response $this->webClient->get($detailUrl);
                
$content $response->getBody()->getContents();

                
$crawler = new Crawler($content);


                
$detailInfo $crawler->filter('div.details-wrapper');
                
$additionalDetail $crawler->filter('.details-section-contents');


                
$currentVersion $additionalDetail->filter('div.content[itemprop="softwareVersion"]')->count() > $additionalDetail->filter('div.content[itemprop="softwareVersion"]')->text() : 0;


                
$totalInstall $additionalDetail->filter('div.content[itemprop="numDownloads"]')->count() > $additionalDetail->filter('div.content[itemprop="numDownloads"]')->text() : 0;


                
$ratingHistorgram $additionalDetail
                                    
->filter('.rating-histogram .rating-bar-container')
                                    ->
each(function(Crawler $node,$i){
                                        return [
                                            
'num'           => trim($node->filter('.bar-label')->text()),
                                            
'bar_length'    => trim($node->filter('.bar')->attr('style')),
                                            
'bar_number'    => trim($node->filter('.bar-number')->text()),
                                        ];
                                    });

                
$commentArr $additionalDetail->filter('.single-review')
                                    ->
each(function(Crawler $node,$i){

                                        
$authorImg $node->filter('.author-image')->attr('style');
                                        
preg_match('/(([^)]+))/'$authorImg$match);
                                        
                                        return [

                                            
'author'         => $node->filter('.author-name')->text(),
                                            
'published_date' => $node->filter('.review-date')->text(),
                                            
'comments'      => $node->filter('.review-body')->text(),
                                            
'image'         => @$match[1],
                                        ];
                                    });

                
$similarApps $crawler->filter('.secondary-content .recommendation .card-content')
                                ->
each(function(Crawler $node,$i)  use($that) {
                                    return 
$that->cardContent($node);
                                });

                
$moreFromDeveloper $crawler->filter('.more-from-developer .recommendation .card-content')
                                ->
each(function(Crawler $node,$i)  use($that) {
                                    return 
$that->cardContent($node);
                                });
                

                
$similarCollections collect($similarApps);
                
$similarRandom $similarCollections->count() <= $similarCollections $similarCollections->random(5)->values();


                
$developerCollections collect($moreFromDeveloper);
                
$moreFromDeveloperRandom $developerCollections->count() <= $developerCollections $developerCollections->random(5)->values();



                
$linkUrl array_filter(explode('/'$detailInfo->filter('.category')->first()->attr('href') ));
                
                
$link route('frontend.category',isset($linkUrl[4]) ? $linkUrl[4] : '#');

                
$appTitle trim($detailInfo->filter('.document-title')->text());

                
$detailArray = [
                    
'app_url'       => route('frontend.download',str_slug($appTitle)).'?token='.base64_encode($query),
                    
'app_link'      => $detailUrl,
                    
'title'         => $appTitle,
                    
'short_summary' => $crawler->filter('meta[name="description"]')->attr('content'),
                    
'description'   => $detailInfo->filter('div.show-more-content > div')->html(),
                    
'cover_image'   => $detailInfo->filter('img.cover-image')->attr('src'),
                    
'developer'  => [
                        
'link' => $this->parseDeveloperLink$detailInfo->filter('div[itemprop="author"] a.document-subtitle')->attr('href') ),
                        
'name' => $detailInfo->filter('span[itemprop="name"]')->text()
                    ],
                    
'category' => [
                        
'name' => trim($detailInfo->filter('.category')->first()->text()),
                        
'link'  => $link
                    
],

                    
'updated_at'        => trim($additionalDetail->filter('div.content[itemprop="datePublished"]')->text()),
                    
'required_android'  => trim($additionalDetail->filter('div.content[itemprop="operatingSystems"]')->text()),
                    
'current_version'   => trim($currentVersion),
                    
'installs'          => trim($totalInstall),


                    
'reviews' => [

                        
'rating_count'     => $additionalDetail->filter('.rating-box span.reviews-num')->text(),
                        
'rate_score'       => trim($additionalDetail->filter('.score-container .score')->text()),
                        
'rating_histogram' => $ratingHistorgram,
                        
'comments'         => $commentArr

                    
],

                    
'similar_apps'          => $similarRandom,
                    
'more_from_developer'   => $moreFromDeveloperRandom,
                   
                    
'screenshots' => $detailInfo->filter('.thumbnails .screenshot')->extract('src'),
                    
'price' => $detailInfo->filter('meta[itemprop=price]')->attr('content'),
                ];
                
                
// pre($detailArray);
                // exit;     
                
return $detailArray;
            });

            return 
$content;

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
    }


    
/**
    * developerLists()
    *
    * @return void
    * @access  public
    **/
    
public function developerLists($developerId)
    {

        if(!
$developerId)
            throw new 
Exception("No Developer Id Found"1);
        
        
$this->appUrl .='/developer?id='.$developerId.'&hl='.$this->opts['lang'];

        try {

            
$cacheName sprintf('%s-%s',$developerId,$this->opts['lang']);
            
$that $this;
            
$content Cache::rememberstr_slug(trim($cacheName)) , 1500, function() use ($that) {
                
$response $this->webClient->get($this->appUrl);
                
$content $response->getBody()->getContents();

                
$crawler = new Crawler($content);
                
$that $this;
                
$content $crawler->filter('div.card-content')
                                ->
each(function(Crawler $node,$i) use($that) {
                                    return 
$that->cardContent($node);
                                });
                return 
$content;
            });

            return 
$content;

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
    }


    
/**
    * byCategory()
    *
    * @return void
    * @access  public
    **/
    
public function byCategory($categoryId,$collection null,$type =null)
    {
        if(!
$categoryId)
            throw new 
Exception("No Category Id Found"1);
        

        
$this->appUrl .='/category/'.$categoryId;

        if(
$collection && $type)
        {
            
$collectionName DIRECTORY_SEPARATOR.$collection.DIRECTORY_SEPARATOR.$type;
            return 
$this->byCategoryCollection($collectionName,$categoryId);
        }
        
$cacheName sprintf('%s-%s',$categoryId,$this->opts['lang']);
        
$this->appUrl .='?hl='.$this->opts['lang'];

        try {

            
$that $this;
            
$categories Cache::rememberstr_slug(trim($cacheName)) , 1500, function() use ($that) {
                
$response $this->webClient->get($this->appUrl);
                
$content $response->getBody()->getContents();

                
$crawler = new Crawler($content);
                
$that    $this;

                
$categories $crawler->filter('div.browse-page .cluster-container')
                    ->
each(function(Crawler $crawler,$i) use($that) {

                        
$name       trim($crawler->filter('a.title-link')->text()); 
                        
$identifier str_slug($name); 

                        
$linkUrl array_filter(explode('/'$crawler->filter('a.title-link')->attr('href')));

                        
$topArr = [
                            
'name' => $name,
                            
'link' => route('frontend.collection',isset($linkUrl[4]) ? $linkUrl[4] : '#')
                        ];

                        
$apps $crawler->filter('div.card-content')->each(function(Crawler $node,$i)  use($that) {
                            return 
$that->cardContent($node);
                        });

                        
$topArr['apps'] = $apps;
                        return 
$topArr;
                    });

                return 
$categories;
            });

            return 
$categories;

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
       
    }


    
/**
    * byCategory()
    *
    * @return void
    * @access  public
    **/
    
public function byCategoryCollection($collectionName,$categoryId null)
    {
        
        try {
            
            
$this->appUrl .= $collectionName;
            
$this->appUrl .='?hl='.$this->opts['lang'];

            
$that $this;
            
$cacheName sprintf('%s-%s-%s',$categoryId,str_slug($collectionName),$this->opts['lang']);
            
            
$categories Cache::remember($cacheName 1500, function() use ($that) {

                
$response $this->webClient->get($this->appUrl);
                
$content $response->getBody()->getContents();

                
$crawler = new Crawler($content);
                
$that    $this;
               
                
$topArr = [
                    
'name' => trim($crawler->filter('.cluster-container h2')->text())
                ];

                
$apps $crawler->filter('div.card-content')->each(function(Crawler $node,$i)  use($that) {
                    return 
$that->cardContent($node);
                });

                
$topArr['apps'] = $apps;
                
// pre($topArr);
                // exit;
                
return [$topArr];
            });
            return 
$categories;

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
    }


    
/**
    * search()
    * 
    * @return void
    * @access  public
    **/
    
public function search($q)
    {
        
        try {
            
            
$this->url .= '/store/search?c=apps&q='.$q.'&hl='.$this->opts['lang'];
            
$that $this;

            
$searchResults Cache::rememberstr_slug(trim($q)) , 1, function() use ($that) {

                    
$response $this->webClient->get($this->url);
                    
$content $response->getBody()->getContents();

                    
$crawler = new Crawler($content);
                    
$topArr = [
                        
'name' => trim($crawler->filter('.cluster-container h2 a')->text())
                    ];

                    
$apps $crawler->filter('div.card-content')->each(function(Crawler $node,$i)  use($that) {
                        return 
$that->cardContent($node);
                    });

                    
$topArr['apps'] = $apps;
                    
                    return 
$topArr;

                });

            return 
$searchResults;

        } catch (
GuzzleException $e) {
            if (
$e instanceof ClientException && $e->hasResponse()) {
                throw new 
Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new 
Exception($e->getMessage(), 3);
        }
    }

    
/**
    * cardContent()
    * 
    * @return void
    * @access  private
    **/
    
private function cardContent($node)
    {

        
$title              $this->hasData($node->filter('a.title')) != false $node->filter('a.title')->attr('title') : '';
        
$description        $this->hasData($node->filter('div.description')) != false trim($node->filter('div.description')->text()) : '';
        
$link               $this->hasData($node->filter('a.title')) != false $node->filter('a.title')->attr('href') : '';
        
$developer_link     $this->hasData($node->filter('div.subtitle-container a.subtitle')) != false $node->filter('div.subtitle-container a.subtitle')->attr('href') : '';

        
$developer_name    $this->hasData($node->filter('div.subtitle-container a.subtitle')) != false $node->filter('div.subtitle-container a.subtitle')->attr('title') : '';

        
$image_l $this->hasData($node->filter('div.cover-image-container img')) != false $node->filter('div.cover-image-container img')->attr('data-cover-large') : '';
        
$image_m $this->hasData($node->filter('div.cover-image-container img')) != false $node->filter('div.cover-image-container img')->attr('data-cover-small') : '';
        
$ratings $this->hasData($node->filter('div.tiny-star')) != false $node->filter('div.tiny-star')->attr('aria-label') : 0;
        
$price   $this->hasData($node->filter('span.display-price')) != false $node->filter('span.display-price')->text() : 'Free';

        
$appId $node->attr('data-docid');




        return [
            
'title'       => $title,
            
'description' => $description,
            
'link'        => $this->url.$link,
            
'app_id'      => $appId,
            
'developer'  => [
                
'link' => $this->parseDeveloperLink($developer_link),
                
'name' => $developer_name
            
],
            
'image' => [
                
'large'  => $image_l,
                
'small' => $image_m,
            ],
            
'ratings' => numberInAString($ratings),
            
'price'   => $price,
            
'detail_url' => route('frontend.detail',str_slug($title)).'?appid='.$appId
        
];
    }

    
/**
    * hasData()
    * 
    * @return void
    * @access  private
    **/
    
private function hasData($filterNode)
    {
        if(
$filterNode->count() > 0)
            return 
$filterNode;
        return 
false;
    }

    
/**
    * parseDeveloperLink()
    * 
    * @return void
    * @access  private
    **/
    
private function parseDeveloperLink($link)
    {
        
$developerLink '#';
        
$devOpsParts parse_url($link);
        if(isset(
$devOpsParts['query']))
            
parse_str($devOpsParts['query'], $developerLink);

        return 
route('frontend.developer',$developerLink);
    }
}
Онлайн: 0
Реклама