Last active
June 5, 2018 01:12
-
-
Save hissy/bd6d21a080072d48891d107b267e603c to your computer and use it in GitHub Desktop.
#concrete5 SmartFormat RSS (An example to customize Zend Feed with Extension)
This file contains hidden or 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 | |
// application/bootstrap/app.php | |
$app->make('Concrete\Core\Routing\RouterInterface')->register('/feed/smartnews', function() use ($app) { | |
/** | |
* Registering Extension for Zend Feed | |
*/ | |
/** @var \Zend\ServiceManager\AbstractPluginManager $manager */ | |
$manager = \Zend\Feed\Writer\Writer::getExtensionManager(); | |
$manager->setInvokableClass( | |
'SmartNewsRendererFeed', | |
'Application\Src\Feed\Writer\Extension\SmartNews\Renderer\Feed' | |
); | |
$manager->setInvokableClass( | |
'SmartNewsEntry', | |
'Application\Src\Feed\Writer\Extension\SmartNews\Entry' | |
); | |
$manager->setInvokableClass( | |
'SmartNewsRendererEntry', | |
'Application\Src\Feed\Writer\Extension\SmartNews\Renderer\Entry' | |
); | |
\Zend\Feed\Writer\Writer::registerExtension('SmartNews'); | |
/** | |
* Get pages | |
*/ | |
$pl = new \Concrete\Core\Page\PageList(); | |
$pl->sortByPublicDateDescending(); | |
$vp = \Concrete\Core\Permission\Key\Key::getByHandle('view_page'); | |
$guest = \Concrete\Core\User\Group\Group::getByID(GUEST_GROUP_ID); | |
$access = \Concrete\Core\Permission\Access\Entity\GroupEntity::getOrCreate($guest); | |
// we set page permissions to be Guest group only, because | |
// authentication won't work with RSS feeds | |
$pl->setPermissionsChecker(function($page) use ($vp, $access) { | |
$vp->setPermissionObject($page); | |
$pa = $vp->getPermissionAccessObject($page); | |
if (!is_object($pa)) { | |
return false; | |
} | |
return $pa->validateAccessEntities(array($access)); | |
}); | |
// Filter By Page Type | |
$pl->filterByPageTypeHandle('article'); | |
$pagination = $pl->getPagination(); | |
if ($pagination->getTotalResults() > 0) { | |
$request = \Concrete\Core\Http\Request::getInstance(); | |
/** | |
* Retrieve site information | |
*/ | |
$site = $app->make('site')->getSite(); | |
$home = $site->getSiteHomePageObject('ACTIVE'); | |
$description = ($site->getAttribute('description')) ? $site->getAttribute('description') : t('No Description'); | |
$thumbnail = $site->getAttribute('thumbnail'); | |
/** | |
* Setup Feed Object | |
*/ | |
$writer = new \Zend\Feed\Writer\Feed(); | |
$writer->setTitle($site->getSiteName()); | |
$writer->setLink($site->getSiteCanonicalURL()); | |
$writer->setDescription($description); | |
if (is_object($thumbnail) { | |
$writer->setImage(array( | |
'uri' => $thumbnail->getURL(), | |
'title' => $site->getSiteName(), | |
'link' => $site->getSiteCanonicalURL() | |
)); | |
} | |
$writer->setDateCreated(new DateTime()); | |
/** @var \Concrete\Core\Page\Page|\Concrete\Core\Page\Collection\Collection|\Page $p */ | |
foreach($pagination->getCurrentPageResults() as $p) { | |
$entry = $writer->createEntry(); | |
$entry->setTitle($p->getCollectionName()); | |
if ($description = $p->getCollectionDescription()) { | |
$entry->setDescription($description); | |
} | |
$entry->setDateCreated(strtotime($p->getCollectionDatePublic())); | |
$entry->setLink($p->getCollectionLink(true)); | |
$uid = $p->getCollectionUserID(); | |
/** @var \Concrete\Core\User\UserInfo $ui */ | |
$ui = $app->make('Concrete\Core\User\UserInfoFactory')->getByID($uid); | |
if ($ui !== null) { | |
$entry->addAuthor(array( | |
'name' => $ui->getUserDisplayName(), | |
'uri' => (string) $ui->getUserPublicProfileUrl() | |
)); | |
} | |
$thumbnail = $p->getAttribute('thumbnail'); | |
if (is_object($thumbnail)) { | |
$entry->setSmartNewsThumbnail((string) $thumbnail->getURL()); | |
} | |
if ($tracking_id = $site->getAttribute('tracking_id')) | |
$entry->setSmartNewsAnalytics(array( | |
'trackingid' => $tracking_id, | |
'uri' => $p->getCollectionLink(true) | |
)); | |
} | |
$a = \Concrete\Core\Area\Area::get($p, 'Main'); | |
$blocks = $a->getAreaBlocksArray(); | |
$request->setCurrentPage($p); | |
ob_start(); | |
foreach($blocks as $b) { | |
$bv = new \Concrete\Core\Block\View\BlockView($b); | |
$bv->render('view'); | |
} | |
$content = ob_get_contents(); | |
ob_end_clean(); | |
if (!$content) { | |
$content = t('No Content.'); | |
} | |
$entry->setContent($content); | |
$writer->addEntry($entry); | |
} | |
return \Concrete\Core\Http\Response::create( | |
$writer->export('rss'), | |
200, | |
array('Content-Type' => 'text/xml') | |
); | |
} | |
} |
This file contains hidden or 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 | |
// application/src/Feed/Writer/Extension/SmartNews/Entry.php | |
namespace Application\Src\Feed\Writer\Extension\SmartNews; | |
use Zend\Feed\Exception\InvalidArgumentException; | |
use Zend\Feed\Uri; | |
use Zend\Feed\Writer\Exception\BadMethodCallException; | |
use Zend\Stdlib\StringUtils; | |
use Zend\Stdlib\StringWrapper\StringWrapperInterface; | |
class Entry | |
{ | |
/** | |
* Array of Feed data for rendering by Extension's renderers | |
* | |
* @var array | |
*/ | |
protected $data = array(); | |
/** | |
* Encoding of all text values | |
* | |
* @var string | |
*/ | |
protected $encoding = 'UTF-8'; | |
/** | |
* The used string wrapper supporting encoding | |
* | |
* @var StringWrapperInterface | |
*/ | |
protected $stringWrapper; | |
public function __construct() | |
{ | |
$this->stringWrapper = StringUtils::getWrapper($this->encoding); | |
} | |
/** | |
* Set feed encoding | |
* | |
* @param string $enc | |
* @return Entry | |
*/ | |
public function setEncoding($enc) | |
{ | |
$this->stringWrapper = StringUtils::getWrapper($enc); | |
$this->encoding = $enc; | |
return $this; | |
} | |
/** | |
* Get feed encoding | |
* | |
* @return string | |
*/ | |
public function getEncoding() | |
{ | |
return $this->encoding; | |
} | |
/** | |
* Set a thumbnail of this entry | |
* | |
* @param string $url | |
* @throws InvalidArgumentException | |
* @return $this | |
*/ | |
public function setSmartNewsThumbnail($url) | |
{ | |
if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) { | |
throw new InvalidArgumentException('Invalid parameter: parameter must be a non-empty string and valid URI/IRI'); | |
} | |
$this->data['thumbnail'] = $url; | |
return $this; | |
} | |
/** | |
* Set the analytics code | |
* | |
* @param array $data | |
* @throws InvalidArgumentException | |
* @return $this | |
*/ | |
public function setSmartNewsAnalytics(array $data) | |
{ | |
if (!array_key_exists('trackingid', $data) | |
|| empty($data['trackingid']) | |
|| !is_string($data['trackingid']) | |
) { | |
throw new InvalidArgumentException('Invalid parameter: Tracking ID must be a non-empty string'); | |
} | |
if (!array_key_exists('uri', $data) | |
|| empty($data['uri']) | |
|| !is_string($data['uri']) | |
|| !Uri::factory($data['uri'])->isValid() | |
) { | |
throw new InvalidArgumentException('Invalid parameter: path must be a non-empty string and valid URI'); | |
} | |
$this->data['analytics'] = $data; | |
return $this; | |
} | |
/** | |
* Overloading to SmartNews specific setters | |
* | |
* @param string $method | |
* @param array $params | |
* @throws BadMethodCallException | |
* @return mixed | |
*/ | |
public function __call($method, array $params) | |
{ | |
$point = lcfirst(substr($method, 12)); | |
if (!method_exists($this, 'setSmartNews' . ucfirst($point)) | |
&& !method_exists($this, 'addSmartNews' . ucfirst($point)) | |
) { | |
throw new BadMethodCallException( | |
'invalid method: ' . $method | |
); | |
} | |
if (!array_key_exists($point, $this->data) | |
|| empty($this->data[$point]) | |
) { | |
return null; | |
} | |
return $this->data[$point]; | |
} | |
} |
This file contains hidden or 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 | |
// application/src/Feed/Writer/Extension/SmartNews/Renderer/Entry.php | |
namespace Application\Src\Feed\Writer\Extension\SmartNews\Renderer; | |
use Zend\Feed\Uri; | |
use Zend\Feed\Writer\Extension\AbstractRenderer; | |
class Entry extends AbstractRenderer | |
{ | |
/** | |
* Set to TRUE if a rendering method actually renders something. This | |
* is used to prevent premature appending of a XML namespace declaration | |
* until an element which requires it is actually appended. | |
* | |
* @var bool | |
*/ | |
protected $called = false; | |
/** | |
* @inheritDoc | |
*/ | |
public function render() | |
{ | |
$this->_setThumbnail($this->dom, $this->base); | |
$this->_setAnalytics($this->dom, $this->base); | |
if ($this->called) { | |
$this->_appendNamespaces(); | |
} | |
} | |
protected function _setThumbnail(\DOMDocument $dom, \DOMElement $root) | |
{ | |
$url = $this->getDataContainer()->getSmartNewsThumbnail(); | |
if (!$url) { | |
return; | |
} | |
$thumbnail = $dom->createElement('media:thumbnail'); | |
$thumbnail->setAttribute('url', $url); | |
$root->appendChild($thumbnail); | |
$this->called = true; | |
} | |
protected function _setAnalytics(\DOMDocument $dom, \DOMElement $root) | |
{ | |
$data = $this->getDataContainer()->getSmartNewsAnalytics(); | |
if (!is_array($data)) { | |
return; | |
} | |
$uri = Uri::factory($data['uri']); | |
$code = sprintf("<script> | |
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | |
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | |
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | |
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); | |
ga('create', '%s', '%s'); | |
ga('require', 'displayfeatures'); | |
ga('set', 'referrer', 'http://www.smartnews.com/'); | |
ga('send', 'pageview', '%s'); | |
</script>", $data['trackingid'], $uri->getHost(), $uri->getPath()); | |
$analytics = $dom->createElement('snf:analytics'); | |
$root->appendChild($analytics); | |
$cdata = $dom->createCDATASection($code); | |
$analytics->appendChild($cdata); | |
$this->called = true; | |
} | |
/** | |
* @inheritDoc | |
*/ | |
protected function _appendNamespaces() | |
{ | |
$this->getRootElement()->setAttribute('xmlns:media', | |
'http://search.yahoo.com/mrss/'); | |
$this->getRootElement()->setAttribute('xmlns:snf', | |
'http://www.smartnews.be/snf'); | |
} | |
} |
This file contains hidden or 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 | |
// application/src/Feed/Writer/Extension/SmartNews/Renderer/Feed.php | |
namespace Application\Src\Feed\Writer\Extension\SmartNews\Renderer; | |
use Zend\Feed\Writer\Extension\AbstractRenderer; | |
class Feed extends AbstractRenderer | |
{ | |
/** | |
* Set to TRUE if a rendering method actually renders something. This | |
* is used to prevent premature appending of a XML namespace declaration | |
* until an element which requires it is actually appended. | |
* | |
* @var bool | |
*/ | |
protected $called = false; | |
/** | |
* @inheritDoc | |
*/ | |
public function render() | |
{ | |
$this->_setFeedLogo($this->dom, $this->base); | |
if ($this->called) { | |
$this->_appendNamespaces(); | |
} | |
} | |
protected function _setFeedLogo(\DOMDocument $dom, \DOMElement $root) | |
{ | |
$image = $this->getDataContainer()->getImage(); | |
if (!$image) { | |
return; | |
} | |
$logo = $dom->createElement('snf:logo'); | |
$url = $dom->createElement('url'); | |
$text = $dom->createTextNode($image['uri']); | |
$url->appendChild($text); | |
$logo->appendChild($url); | |
$root->appendChild($logo); | |
$this->called = true; | |
} | |
/** | |
* @inheritDoc | |
*/ | |
protected function _appendNamespaces() | |
{ | |
$this->getRootElement()->setAttribute('xmlns:snf', | |
'http://www.smartnews.be/snf'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment