PDA

Zobacz pełną wersję : Własny plugin, problem z RSS



cyberek
28-11-2008, 11:58
Napisałem prosty plugin, który pozwala wyświetlić galerię zdjęć z wybranego katalogu, stosując w treści artykułu znacznik:
{galley}nazwa_folderu{/gallery}. W konfiguracji wybiera sie folder macieżysty z kategoriami itp. Wszystko jest ok, niestety przy generacji RSS'a zamiast wygenerowanego kodu podmieniajacego znacznik, pojawia sie oryginalny {galley}nazwa_folderu{/gallery}.

Czy ktos wystarczajaco doswiadczony, moze rzucic okiem na kod i powiedziec, co nalezy dodac, by rowniez rss (ten wbudowany w joomle) podmienial zawartosc na zdjecia, ewentualnie jesli ktos ma bardzo prosty modol (ktory robi cokolwiek), a ktory dziala rowniez z rss'em, to prosze o nazwe/link.

Poniżej kod z komentazami dla tych, ktorzy chcieli by zrozumiec jak dziala. W razie czego udostepnie rowniez plik xml, gdyby ktos chcial uzyc.
Dzialanie widac pod adresem: http://swiatlemmalowane.pl/blog
rss: http://swiatlemmalowane.pl/blog.feed?type=atom



<?php
/**
* @version $Id: blog_gallery.php 2008.11.04 Marcin Bobowski $
* @package -
* @copyright Copyright (C) 2005 - 2008 SwiatlemMalowane.pl. All rights reserved.
* @license GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

$mainframe->registerEvent( 'onPrepareContent', 'plgBlogGallery' );
//$mainframe->addCustomHeadTag( 'onPrepareContent');


function plgBlogGallery( &$row, &$params, $page=0 )
{
//if no tag in text present, do nothing
if ( JString::strpos( $row->text, 'gallery' ) === false ) {
return true;
}

//import plugin settings
$plugin =& JPluginHelper::getPlugin('content', 'blog_gallery');
$pluginParams = new JParameter( $plugin->params );

// check whether plugin has been deactivated
if ( !$params->get( 'enabled', 1 ) ) {
$row->text = preg_replace( $regex, '', $row->text );
return true;
}
//set rootfolder of the galleries
$rootfolder = $pluginParams->get('rootfolder','/images/stories/');
//set some parameters
$mosConfig_absolute_path = JPATH_SITE;
$mosConfig_live_site = JURI :: base();

//main finction starts here
if (preg_match_all("#{gallery}(.*?){/gallery}#s", $row->text, $matches, PREG_PATTERN_ORDER) > 0) {

//loop on every plugin callout in text
foreach ($matches[0] as $match) {
//remove {gallery}{/gallery} from callout
$_temp = preg_replace("/{.+?}/", "", $match);
unset($_params);
//explode parameters - first directory, second is hidden, third text to show
$_params = explode(":",$_temp);
$_images_dir_ = $_params[0];
unset($images);
$noimage = 0;
//read directory, get filenames to $images[] table, sort
if ($dh = opendir($mosConfig_absolute_path.$rootfolder.$_ima ges_dir_)) {
while (($f = readdir($dh)) !== false) {
if((substr(strtolower($f),-3) == 'jpg') || (substr(strtolower($f),-3) == 'gif') || (substr(strtolower($f),-3) == 'png')) {
$noimage++;
$images[] = trim(strtolower($f));
switch ($order) {
case 0: sort($images); break;
case 1: natsort($images); break;
case 2: natcasesort($images); break;
case 3: rsort($images); break;
case 4: shuffle($images); break;
} //end switch
}//end if
} //end while
closedir($dh);
}//end if

//if any image found
if($noimage) {

$html = '
';

//if gallery is set to be hidden
if(@$_params[1]) {
//add a link to show div, add js handlers
$html .= "
<a id=\"".$_images_dir_."_slideBtn\" >".$_params[1]."</a>
**********
window.addEvent('domready', function() {
var my".$_images_dir_."slide = new Fx.Slide('".$_images_dir_."_slideDiv');
$('".$_images_dir_."_slideBtn').addEvent('click', function(e){
my".$_images_dir_."slide.toggle();
});
my".$_images_dir_."slide.hide();
});
***********
";
}
//add wharparound div to gallery and center images
$html .= '
<div id="'.$_images_dir_.'_slideDiv" class="blog_gallery_class" style="width: 100%; text-align: center;">
';

//loop on all images and display them one below other
for($a = 0;$a<$noimage;$a++) {

$html .= '<img class="blog_image" src="'.$mosConfig_live_site.$rootfolder.$_images_dir_.'/'.$images[$a].'" /><br />';
}//end for
$html .= '
</div>
';

}//end if
//change plugin callout to producet output
$row->text = preg_replace( "#{gallery}$_temp{/gallery}#s", $html , $row->text );

} //end foreach
}//end iif
}

cyberek
01-12-2008, 10:48
Po kilku dniach kopanai po forach okazuje się, że ootb joomla nie pozwala używać pluginów w kanałach rss (rss, atom). Aby było to możliwe, potrzebna jest poprawka bibliotekowych plików joomli (a zatem jednocześnie nie da się użyć możliwości nadpisywania niektórych obiektów przez umieszczenie odpowiednich plików w templatce strony). Trzeba również pamiętać, by po aktualizacji dokonać ponownie zmian.

Zacznę od plików do zmodyfikowania:
/libraries/joomla/document/feed/render/atom.php
/libraries/joomla/document/feed/render/rss.php

Poprawka do /libraries/joomla/document/feed/render/atom.php

$feed.= " <generator uri=\"http://joomla.org\" version=\"1.5\">".$data->getGenerator()."</generator>\n";
$feed.= "<link rel=\"self\" type=\"application/atom+xml\" href=\"". $data->syndicationURL . "\" />\n";

$dispatcher =& JDispatcher::getInstance();
JPluginHelper::importPlugin('content');

for ($i=0;$i<count($data->items);$i++)
{

$results=$dispatcher->trigger('onPrepareContent', array(&$data->items[$i], array(), 'rss'));

$feed.= " <entry>\n";

Dodane linijki to:

$dispatcher =& JDispatcher::getInstance();
JPluginHelper::importPlugin('content');
oraz:

$results=$dispatcher->trigger('onPrepareContent', array(&$data->items[$i], array(), 'rss'));

Poprawka sprowadza się do wykonania pluginów z grupy content podczas eventu onPrepareContent, oraz wysłąnie do niego aktualnych danych treściowych, oraz opcjonalnego parametru rss.

Podobna poprawka dla /libraries/joomla/document/feed/render/rss.php

if ($data->skipDays!="") {
$feed.= " <skipDays>".htmlspecialchars($data->skipDays, ENT_COMPAT, 'UTF-8')."</skipDays>\n";
}

$dispatcher =& JDispatcher::getInstance();
JPluginHelper::importPlugin('content');

for ($i=0; $i<count($data->items); $i++)
{
$results=$dispatcher->trigger('onPrepareContent', array(&$data->items[$i], array(), 'rss'));

if ((strpos($data->items[$i]->link, 'http://') === false) and (strpos($data->items[$i]->link, 'https://') === false)) {
$data->items[$i]->link = $url.$data->items[$i]->link;
}
Linijki te same.

Powyższe poprawki niestety nie rozwiązują problemu, gdyż joomla w przypadku kanałów rss treść wiadomości przesyła nie jako $row->text. Używane jest $row->description.

Stąd użyty dodatkowy prametr rss, który pozwala w finalnym kodzie pluginu obsłużyć odpowiedni obiekt:

<?php
/**
* @version $Id: blog_gallery.php 2008.11.04 Marcin Bobowski $
* @package -
* @copyright Copyright (C) 2005 - 2008 SwiatlemMalowane.pl. All rights reserved.
* @license GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/

defined( '_JEXEC' ) or die( 'Restricted access' );

// Import library dependencies
jimport('joomla.event.plugin');


class plgContentBloggallery extends JPlugin
{
//Constructor
function plgContentBloggallery( &$subject )
{
parent::__construct( $subject );
// load plugin parameters
$this->_plugin = JPluginHelper::getPlugin( 'content', 'bloggallery' );
$this->_params = new JParameter( $this->_plugin->params );
$this->_rootfolder = $this->_params->get('rootfolder','/images/stories/blog/');
$this->_order = $this->_params->get('order', 0);
$this->_mosConfig_absolute_path = JPATH_SITE;
$this->_mosConfig_live_site = JURI :: base();
}

function onPrepareContent(&$row, &$params, $limitstart) {

global $mainframe;
//depending on kind of resource, assign _target to source object by reference, so changes may be done on _target
if ($limitstart === 'rss') {
$this->_target = &$row->description;
}
else {
$this->_target = &$row->text;
}

$regex = '#{gallery}(.*?){/gallery}#s';

//if no tag in text present, do nothing
if ( JString::strpos( $this->_target, 'gallery' ) === false ) {
return true;
}

// check whether plugin has been deactivated
if ( !$this->_params->get( 'enabled', 1 ) ) {
$this->_target = preg_replace( $regex, '', $this->_target );
return true;
}

//main finction starts here
if (preg_match_all($regex, $this->_target, $matches, PREG_PATTERN_ORDER) > 0) {

//loop on every plugin callout in text
foreach ($matches[0] as $match) {
//remove {gallery}{/gallery} from callout
$_temp = preg_replace("/{.+?}/", "", $match);
unset($_params);
//explode parameters - first directory, second is hidden, third text to show
$_params = explode(":",$_temp);
$_images_dir_ = $_params[0];
unset($images);
$noimage = 0;
//read directory, get filenames to $images[] table, sort
if ($dh = opendir($this->_mosConfig_absolute_path.$this->_rootfolder.$_images_dir_)) {
while (($f = readdir($dh)) !== false) {
if((substr(strtolower($f),-3) == 'jpg') || (substr(strtolower($f),-3) == 'gif') || (substr(strtolower($f),-3) == 'png')) {
$noimage++;
$images[] = trim(strtolower($f));
switch ($this->_order) {
case 0: sort($images); break;
case 1: natsort($images); break;
case 2: natcasesort($images); break;
case 3: rsort($images); break;
case 4: shuffle($images); break;
} //end switch
}//end if
} //end while
closedir($dh);
}//end if

//if any image found
if($noimage) {

$html = '
';

//if gallery is set to be hidden
if(@$_params[1]) {
//add a link to show div, add js handlers
$html .= "
<a id=\"".$_images_dir_."_slideBtn\" >".$_params[1]."</a>
**********
window.addEvent('domready', function() {
var my".$_images_dir_."slide = new Fx.Slide('".$_images_dir_."_slideDiv');
$('".$_images_dir_."_slideBtn').addEvent('click', function(e){
my".$_images_dir_."slide.toggle();
});
my".$_images_dir_."slide.hide();
});
***********
";
}
//add wharparound div to gallery and center images
$html .= '
<div id="'.$_images_dir_.'_slideDiv" class="blog_gallery_class">
';

//loop on all images and display them one below other
for($a = 0;$a<$noimage;$a++) {

$html .= '<img class="blog_image" src="'.$this->_mosConfig_live_site.$this->_rootfolder.$_images_dir_.'/'.$images[$a].'" /><br />';
}//end for
$html .= '
</div>
';

}//end if
//change plugin callout to producet output

$this->_target = preg_replace( "#{gallery}$_temp{/gallery}#s", $html , $this->_target );


} //end foreach
}//end iif

return true;
}

}

?>

Dodatkowo przepisałem plugin tak, by działał i wyglądał bardziej obiektowo ;).

zwiastun
01-12-2008, 15:08
Ślij swe uwagi i zmiany do Core!

cyberek
01-12-2008, 15:13
Niestety te poprawki nie są dobrze napisane, gdyż nadal nie rozwiązują problemu różnego umieszczania treści w obiekcie $row. Dla rss jest to description, dla html $text, stąd plugin nie jest uniwersalny i musi uwzględniać te rozbieżności, aczkolwiek, gdyby znalazł się ktoś, kto poprawi kod wyżej, tak by dowolne medium używało tych samych obiektów trzymających dane, poprawka mogłą by przejść :).

Tak czy owak proszę o info, gdzie pisać poprawki do core ;)

zwiastun
01-12-2008, 16:24
http://docs.joomla.org/Parti****************ting_in_the_community