Last active
February 23, 2018 08:29
-
-
Save wiratama/7b7a63e18a1687683a34f86f6711f891 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Movent\ContentBundle\Twig; | |
use Movent\ContentBundle\Permalink\PermalinkInterface; | |
use Movent\ContentBundle\Entity\Interfaces\ContentInterface; | |
use Movent\ContentBundle\Entity\Interfaces\ArticleInterface; | |
use Movent\ContentBundle\Entity\Interfaces\RecipeInterface; | |
use Movent\ContentBundle\Entity\Interfaces\ProductInterface; | |
use Movent\CategoryBundle\Entity\CategoryInterface; | |
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
use GuzzleHttp\Client; | |
use GuzzleHttp\Exception\RequestException; | |
use Symfony\Component\DomCrawler\Crawler; | |
class ContentExtension extends \Twig_Extension { | |
const FACEBOOK_SHARE_URL = 'https://graph.facebook.com'; | |
const TWITTER_SHARE_URL = 'https://cdn.api.twitter.com'; | |
protected $permalinkGenerator; | |
protected $generator; | |
protected $container; | |
protected $environment; | |
public function __construct(PermalinkInterface $permalinkGenerator, UrlGeneratorInterface $generator) { | |
$this->permalinkGenerator = $permalinkGenerator; | |
$this->generator = $generator; | |
} | |
public function initRuntime(\Twig_Environment $environment) | |
{ | |
$this->environment = $environment; | |
} | |
/** | |
* set Service Container | |
* | |
* @param Symfony\Component\DependencyInjection\Container | |
*/ | |
public function setContainer($container) { | |
$this->container = $container; | |
} | |
public function getFunctions() { | |
return array( | |
new \Twig_SimpleFunction('movent_content_path', array($this, 'contentPathFunction')), | |
new \Twig_SimpleFunction('movent_content_canonical_path', array($this, 'canonicalPathFunction')), | |
new \Twig_SimpleFunction('movent_content_canonical_slug_path', array($this, 'canonicalSlugPathFunction')), | |
new \Twig_SimpleFunction('movent_content_slug_path', array($this, 'contentPathFromSlugFunction')), | |
new \Twig_SimpleFunction('isArticle', array($this, 'isArticleFunction')), | |
new \Twig_SimpleFunction('isRecipe', array($this, 'isRecipeFunction')), | |
new \Twig_SimpleFunction('isProduct', array($this, 'isProductFunction')), | |
new \Twig_SimpleFunction('isContent', array($this, 'isContentFunction')), | |
new \Twig_SimpleFunction('getFBShareCount', array($this, 'getContentsFunction')), | |
new \Twig_SimpleFunction('getTWShareCount', array($this, 'getTWContentsFunction')), | |
new \Twig_SimpleFunction('bitly_short_url', array($this, 'getBitlyShortUrl')), | |
); | |
} | |
public function getFilters() | |
{ | |
return array( | |
new \Twig_SimpleFilter('render_widgets', array($this, 'renderWidgets'),array('is_safe' => array('html'))), | |
new \Twig_SimpleFilter('shuffle', array($this, 'shuffle')), | |
); | |
} | |
public function getBitlyShortUrl($url) | |
{ | |
if ($this->container->hasParameter('bitly_access_token')) { | |
$bitlyAccessToken = $this->container->getParameter('bitly_access_token'); | |
} | |
if (!empty($bitlyAccessToken)) { | |
$client = new Client(); | |
try { | |
$bitlyUrl = sprintf('https://api-ssl.bitly.com/v3/shorten?access_token=%s&longUrl=%s', $bitlyAccessToken, urlencode($url)); | |
$response = $client->get($bitlyUrl); | |
if ($response->getStatusCode() == 200) { | |
$obj = $response->json(); | |
return (isset($obj['data']['url']) ? $obj['data']['url'] : $url); | |
} | |
} catch (Exception $ex) { | |
return 0; | |
} | |
} | |
return $url; | |
} | |
public function contentPathFunction(ContentInterface $content, CategoryInterface $category = null, $absolute = false) { | |
if (!$category) { | |
return $this->canonicalPathFunction($content, null, $absolute); | |
} | |
return $this->generator->generate('movent_content_content_view', array('permalink' => $this->permalinkGenerator->generate($content, $category), | |
'_format' => 'html'), $absolute); | |
} | |
public function canonicalSlugPathFunction($slug = '', $absolute = false) { | |
return $this->generator->generate('movent_content_view_canonical', array('permalink' => $slug, | |
'_format' => 'html'), $absolute); | |
} | |
public function canonicalPathFunction(ContentInterface $content, CategoryInterface $category = null, $absolute = false) { | |
return $this->generator->generate('movent_content_view_canonical', array('permalink' => $this->permalinkGenerator->generate($content, $category), | |
'_format' => 'html'), $absolute); | |
} | |
public function contentPathFromSlugFunction($slug = '', CategoryInterface $category = null, $absolute = false) { | |
$routeName = 'movent_content_content_view'; | |
if (!$category) { | |
$routeName = 'movent_content_view_canonical'; | |
} | |
return $this->generator->generate($routeName, array('permalink' => $this->permalinkGenerator->generateFromSlug($slug, $category), | |
'_format' => 'html'), $absolute); | |
} | |
public function isArticleFunction(ContentInterface $content) { | |
return (bool) ($content instanceof ArticleInterface); | |
} | |
public function isRecipeFunction(ContentInterface $content) { | |
return (bool) ($content instanceof RecipeInterface); | |
} | |
public function isProductFunction(ContentInterface $content) { | |
return (bool) ($content instanceof ProductInterface); | |
} | |
public function isContentFunction(ContentInterface $content) { | |
return (bool) ($content instanceof ContentInterface); | |
} | |
public function getName() { | |
return 'movent_content_extension'; | |
} | |
public function getContentsFunction($url) { | |
$client = new Client(); | |
try { | |
$shareUrl = sprintf("%s/fql?q=SELECT%%20like_count,%%20total_count,%%20share_count,%%20click_count,%%20comment_count%%20FROM%%20link_stat%%20WHERE%%20url%%20=%%20%%27%s%%27", self::FACEBOOK_SHARE_URL, $url); | |
$response = $client->get($shareUrl); | |
if ($response->getStatusCode() == 200) { | |
$obj = $response->json(); | |
return ((isset($obj['data']) && isset($obj['data'][0]) && isset($obj['data'][0]['share_count'])) ? $obj['data'][0]['share_count'] : null); | |
} | |
return 0; | |
} catch (RequestException $e) { | |
return 0; | |
} | |
} | |
public function getTWContentsFunction($url) { | |
$client = new Client(); | |
try { | |
$shareUrl = sprintf("%s/1/urls/count.json?url=%s", self::TWITTER_SHARE_URL, $url); | |
$response = $client->get($shareUrl); | |
if ($response->getStatusCode() == 200) { | |
$obj = $response->json(); | |
return (isset($obj['count']) ? $obj['count'] : 0); | |
} | |
return 0; | |
} catch (RequestException $e) { | |
return 0; | |
} | |
} | |
public function renderWidgets($contents,$params = []) | |
{ | |
$request = $this->container->get('request'); | |
if(!$contents){ | |
return ""; | |
} | |
$crawler = new Crawler($contents); | |
try { | |
/* div.related-content by category */ | |
$pNode = $crawler->filter('p')->count(); | |
$pNode = ($pNode>2) ? round($pNode/2) : $pNode; | |
$request = $this->container->get('request'); | |
$parameters = explode('/', $request->getRequestURI()); | |
$permalink = $this->permalinkGenerator->getParameters($request->getRequestURI()); | |
$catId = $contentId = $contetnType = 0; | |
$relatedArticle = []; | |
if(count($parameters) > 4) { | |
$categoryData = $this->container->get('doctrine')->getRepository('MoventCategoryBundle:Category')->findOneBy(array('slug' => (string)$parameters[3])); | |
$catId = $categoryData->getId(); | |
$paramSlug = explode('.',$parameters[4]); | |
$contentData = $this->container->get('doctrine')->getRepository('MoventContentBundle:Content')->findOneBy(array('slug' => (string)$paramSlug[0])); | |
$contentId = $contentData->getId(); | |
$contentType = $contentData->getContentType(); | |
} else { | |
$categoryData = $this->container->get('doctrine')->getRepository('MoventCategoryBundle:Category')->findOneBy(array('slug' => (string)$parameters[2])); | |
$catId = $categoryData->getId(); | |
$paramSlug = explode('.',$parameters[3]); | |
$contentData = $this->container->get('doctrine')->getRepository('MoventContentBundle:Content')->findOneBy(array('slug' => (string)$paramSlug[0])); | |
$contentId = $contentData->getId(); | |
$contentType = $contentData->getContentType(); | |
} | |
$entityManager = $this->container->get('doctrine')->getManager(); | |
$connection = $entityManager->getConnection(); | |
$statement = $connection->prepare("SELECT ctr.*, c.* FROM movent__content_entity_content_category ctr JOIN movent__content_entity_content c ON ctr.content_id=c.id WHERE ctr.content_id <> :content_id AND c.content_type = :content_type AND ctr.category_id = :category_id AND c.status = :status ORDER BY RAND() LIMIT 1"); | |
$statement->bindValue('content_id', $contentId); | |
$statement->bindValue('content_type', 'Article'); | |
$statement->bindValue('category_id', $catId); | |
$statement->bindValue('status', 'published'); | |
$statement->execute(); | |
$relatedArticle = $statement->fetchAll(); | |
$content = $this->container->get('movent_content.content.entity.manager')->findOneBy(array('id' => $relatedArticle[0]['content_id'])); | |
/* /. div.related-content by category */ | |
$widgetHelper = $this->container->get("movent_content.widget.helper"); | |
//$crawler->filter("widget.inline-related-content")->each(function (Crawler $node, $i) use ($params,$widgetHelper){ | |
$crawler->filter("p")->eq($pNode)->each(function (Crawler $node, $i) use ($params,$widgetHelper, $relatedArticle, $content){ | |
$limit = 1; | |
$type = 'related-article'; | |
$params['related_article'] = $content; //$relatedArticle; | |
$templateContent = $widgetHelper->setParameters($params)->setType($type)->setLimit($limit)->render(); | |
$tmpDoc = new \DOMDocument(); | |
$internalErrors = libxml_use_internal_errors(true); | |
$tmpDoc->loadHTML($templateContent?$templateContent:"<span/>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); | |
libxml_use_internal_errors($internalErrors); | |
if($tmpDoc->documentElement) { | |
$node->getNode(0)->parentNode->insertBefore($node->getNode(0)->ownerDocument->importNode($tmpDoc->documentElement,true), $node->getNode(0)); | |
} | |
}); | |
} | |
catch(Exception $e){ | |
// make sure to throw exception on debug mode. | |
if ($this->environment->isDebug()) { | |
throw $e; | |
} | |
} | |
if($crawler->count() < 1){ | |
return; | |
} | |
$html = ""; | |
if (!count($crawler)) { | |
// make sure to throw exception on debug mode. | |
if ($this->environment->isDebug()) { | |
throw new \InvalidArgumentException('The current node list is empty.'); | |
} | |
} | |
foreach ($crawler->getNode(0)->childNodes as $child) { | |
$html .= $child->ownerDocument->saveHTML(); | |
} | |
//Remove extra body tag | |
preg_match("/<body[^>]*>(.*?)<\/body>/is", $html, $matches); | |
return $matches[1]; | |
} | |
public function shuffle($data = []) | |
{ | |
shuffle($data); | |
return $data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
path