Subversion Repositories eFlore/Applications.cel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 3864 → Rev 3865

/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss1.php
New file
0,0 → 1,267
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS1.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS1.0 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Find a Relax NG URI we can use
*/
class XmlFeedParserRss1 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss10.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss1Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'textinput' => array('TextInput'),
'updatePeriod' => array('Text'),
'updateFrequency' => array('Text'),
'updateBase' => array('Date'),
'rights' => array('Text'), # dc:rights
'description' => array('Text'), # dc:description
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date') # dc:contributor
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'),
'author' => array('creator'),
'updated' => array('date'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rss' => 'http://purl.org/rss/1.0/',
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/',
'sy' => 'http://web.resource.org/rss/1.0/modules/syndication/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Allows retrieval of an entry by ID where the rdf:about attribute is used
*
* This is not really something that will work with RSS1 as it does not have
* clear restrictions on the global uniqueness of IDs. We will employ the
* _very_ hit and miss method of selecting entries based on the rdf:about
* attribute. If DOMXPath::evaluate is available, we also use that to store
* a reference to the entry in the array used by getEntryByOffset so that
* method does not have to seek out the entry if it's requested that way.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//rss:item[@rdf:about='$id']");
if ($entries->length > 0) {
$classname = $this->itemClass;
$entry = new $classname($entries->item(0), $this);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::rss:item)", $entries->item(0));
$this->entries[$offset] = $entry;
}
$this->idMappings[$id] = $entry;
return $entry;
}
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'link' => $image->getElementsByTagName('link')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details, array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) and
$input->attributes->getNamedItem('resource')) {
$results['link'] =
$input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
 
/**
* Employs various techniques to identify the author
*
* Dublin Core provides the dc:creator, dc:contributor, and dc:publisher
* elements for defining authorship in RSS1. We will try each of those in
* turn in order to simulate the atom author element and will return it
* as text.
*
* @return array|false
*/
function getAuthor() {
$options = array('creator', 'contributor', 'publisher');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length > 0) {
return $test->item(0)->value;
}
}
return false;
}
/**
* Retrieve a link
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss11.php
New file
0,0 → 1,266
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1.1 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS11.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS1.1 feeds. RSS1.1 is documented at:
* http://inamidst.com/rss1.1/
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Support for RDF:List
* @todo Ensure xml:lang is accessible to users
*/
class XmlFeedParserRss11 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss11.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss11Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'updatePeriod' => array('Text'),
'updateFrequency' => array('Text'),
'updateBase' => array('Date'),
'rights' => array('Text'), # dc:rights
'description' => array('Text'), # dc:description
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date') # dc:contributor
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'),
'author' => array('creator'),
'updated' => array('date'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together. We will retain support for some common RSS1.0 modules
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rss' => 'http://purl.org/net/rss1.1#',
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/',
'sy' => 'http://web.resource.org/rss/1.0/modules/syndication/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Attempts to identify an element by ID given by the rdf:about attribute
*
* This is not really something that will work with RSS1.1 as it does not have
* clear restrictions on the global uniqueness of IDs. We will employ the
* _very_ hit and miss method of selecting entries based on the rdf:about
* attribute. Please note that this is even more hit and miss with RSS1.1 than
* with RSS1.0 since RSS1.1 does not require the rdf:about attribute for items.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//rss:item[@rdf:about='$id']");
if ($entries->length > 0) {
$classname = $this->itemClass;
$entry = new $classname($entries->item(0), $this);
return $entry;
}
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
if ($image->getElementsByTagName('link')->length > 0) {
$details['link'] =
$image->getElementsByTagName('link')->item(0)->value;
}
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details,
array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) and
$input->attributes->getNamedItem('resource')) {
$results['link'] = $input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
 
/**
* Attempts to discern authorship
*
* Dublin Core provides the dc:creator, dc:contributor, and dc:publisher
* elements for defining authorship in RSS1. We will try each of those in
* turn in order to simulate the atom author element and will return it
* as text.
*
* @return array|false
*/
function getAuthor() {
$options = array('creator', 'contributor', 'publisher');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length > 0) {
return $test->item(0)->value;
}
}
return false;
}
/**
* Retrieve a link
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss2.php
New file
0,0 → 1,323
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Class representing feed-level data for an RSS2 feed
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS2.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS2 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss2 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss20.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 2.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss2Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'ttl' => array('Text'),
'pubDate' => array('Date'),
'lastBuildDate' => array('Date'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'),
'language' => array('Text'),
'copyright' => array('Text'),
'managingEditor' => array('Text'),
'webMaster' => array('Text'),
'category' => array('Text'),
'generator' => array('Text'),
'docs' => array('Text'),
'ttl' => array('Text'),
'image' => array('Image'),
'skipDays' => array('skipDays'),
'skipHours' => array('skipHours'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'rights' => array('copyright'),
'updated' => array('lastBuildDate'),
'subtitle' => array('description'),
'date' => array('pubDate'),
'author' => array('managingEditor'));
 
protected $namespaces = array(
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XmlFeedParserException('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($this->model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Retrieves an entry by ID, if the ID is specified with the guid element
*
* This is not really something that will work with RSS2 as it does not have
* clear restrictions on the global uniqueness of IDs. But we can emulate
* it by allowing access based on the 'guid' element. If DOMXPath::evaluate
* is available, we also use that to store a reference to the entry in the array
* used by getEntryByOffset so that method does not have to seek out the entry
* if it's requested that way.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS2Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//item[guid='$id']");
if ($entries->length > 0) {
$entry = new $this->itemElement($entries->item(0), $this);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::item)", $entries->item(0));
$this->entries[$offset] = $entry;
}
$this->idMappings[$id] = $entry;
return $entry;
}
}
 
/**
* Get a category from the element
*
* The category element is a simple text construct which can occur any number
* of times. We allow access by offset or access to an array of results.
*
* @param string $call for compatibility with our overloading
* @param array $arguments - arg 0 is the offset, arg 1 is whether to return as array
* @return string|array|false
*/
function getCategory($call, $arguments = array()) {
$categories = $this->model->getElementsByTagName('category');
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$array = empty($arguments[1]) ? false : true;
if ($categories->length <= $offset) {
return false;
}
if ($array) {
$list = array();
foreach ($categories as $category) {
array_push($list, $category->nodeValue);
}
return $list;
}
return $categories->item($offset)->nodeValue;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->xpath->query("//image");
if ($images->length > 0) {
$image = $images->item(0);
$desc = $image->getElementsByTagName('description');
$description = $desc->length ? $desc->item(0)->nodeValue : false;
$heigh = $image->getElementsByTagName('height');
$height = $heigh->length ? $heigh->item(0)->nodeValue : false;
$widt = $image->getElementsByTagName('width');
$width = $widt->length ? $widt->item(0)->nodeValue : false;
return array(
'title' => $image->getElementsByTagName('title')->item(0)->nodeValue,
'link' => $image->getElementsByTagName('link')->item(0)->nodeValue,
'url' => $image->getElementsByTagName('url')->item(0)->nodeValue,
'description' => $description,
'height' => $height,
'width' => $width);
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness...
*
* @return array|false
*/
function getTextInput() {
$inputs = $this->model->getElementsByTagName('input');
if ($inputs->length > 0) {
$input = $inputs->item(0);
return array(
'title' => $input->getElementsByTagName('title')->item(0)->value,
'description' =>
$input->getElementsByTagName('description')->item(0)->value,
'name' => $input->getElementsByTagName('name')->item(0)->value,
'link' => $input->getElementsByTagName('link')->item(0)->value);
}
return false;
}
 
/**
* Utility function for getSkipDays and getSkipHours
*
* This is a general function used by both getSkipDays and getSkipHours. It simply
* returns an array of the values of the children of the appropriate tag.
*
* @param string $tagName The tag name (getSkipDays or getSkipHours)
* @return array|false
*/
protected function getSkips($tagName) {
$hours = $this->model->getElementsByTagName($tagName);
if ($hours->length == 0) {
return false;
}
$skipHours = array();
foreach($hours->item(0)->childNodes as $hour) {
if ($hour instanceof DOMElement) {
array_push($skipHours, $hour->nodeValue);
}
}
return $skipHours;
}
 
/**
* Retrieve skipHours data
*
* The skiphours element provides a list of hours on which this feed should
* not be checked. We return an array of those hours (integers, 24 hour clock)
*
* @return array
*/
function getSkipHours() {
return $this->getSkips('skipHours');
}
 
/**
* Retrieve skipDays data
*
* The skipdays element provides a list of days on which this feed should
* not be checked. We return an array of those days.
*
* @return array
*/
function getSkipDays() {
return $this->getSkips('skipDays');
}
 
/**
* Return content of the little-used 'cloud' element
*
* The cloud element is rarely used. It is designed to provide some details
* of a location to update the feed.
*
* @return array an array of the attributes of the element
*/
function getCloud() {
$cloud = $this->model->getElementsByTagName('cloud');
if ($cloud->length == 0) {
return false;
}
$cloudData = array();
foreach ($cloud->item(0)->attributes as $attribute) {
$cloudData[$attribute->name] = $attribute->value;
}
return $cloudData;
}
/**
* Get link URL
*
* In RSS2 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them. We maintain the
* parameter used by the atom getLink method, though we only use the offset
* parameter.
*
* @param int $offset The position of the link within the feed. Starts from 0
* @param string $attribute The attribute of the link element required
* @param array $params An array of other parameters. Not used.
* @return string
*/
function getLink($offset, $attribute = 'href', $params = array()) {
$links = $this->model->getElementsByTagName('link');
 
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserAtomElement.php
New file
0,0 → 1,254
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* AtomElement class for XML_Feed_Parser package
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: AtomElement.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class provides support for atom entries. It will usually be called by
* XML_Feed_Parser_Atom with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserAtomElement extends XmlFeedParserAtom {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_Atom
*/
protected $parent;
 
/**
* When performing XPath queries we will use this prefix
* @var string
*/
private $xpathPrefix = '';
/**
* xml:base values inherited by the element
* @var string
*/
protected $xmlBase;
 
/**
* Here we provide a few mappings for those very special circumstances in
* which it makes sense to map back to the RSS2 spec or to manage other
* compatibilities (eg. with the Univeral Feed Parser). Key is the other version's
* name for the command, value is an array consisting of the equivalent in our atom
* api and any attributes needed to make the mapping.
* @var array
*/
protected $compatMap = array(
'guid' => array('id'),
'links' => array('link'),
'tags' => array('category'),
'contributors' => array('contributor'));
/**
* Our specific element map
* @var array
*/
protected $map = array(
'author' => array('Person', 'fallback'),
'contributor' => array('Person'),
'id' => array('Text', 'fail'),
'published' => array('Date'),
'updated' => array('Date', 'fail'),
'title' => array('Text', 'fail'),
'rights' => array('Text', 'fallback'),
'summary' => array('Text'),
'content' => array('Content'),
'link' => array('Link'),
'enclosure' => array('Enclosure'),
'category' => array('Category'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_Atom $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
$this->xmlBase = $xmlBase;
$this->xpathPrefix = "//atom:entry[atom:id='" . $this->id . "']/";
$this->xpath = $this->parent->xpath;
}
 
/**
* Provides access to specific aspects of the author data for an atom entry
*
* Author data at the entry level is more complex than at the feed level.
* If atom:author is not present for the entry we need to look for it in
* an atom:source child of the atom:entry. If it's not there either, then
* we look to the parent for data.
*
* @param array
* @return string
*/
function getAuthor($arguments) {
/* Find out which part of the author data we're looking for */
if (isset($arguments['param'])) {
$parameter = $arguments['param'];
} else {
$parameter = 'name';
}
$test = $this->model->getElementsByTagName('author');
if ($test->length > 0) {
$item = $test->item(0);
return $item->getElementsByTagName($parameter)->item(0)->nodeValue;
}
$source = $this->model->getElementsByTagName('source');
if ($source->length > 0) {
$test = $this->model->getElementsByTagName('author');
if ($test->length > 0) {
$item = $test->item(0);
return $item->getElementsByTagName($parameter)->item(0)->nodeValue;
}
}
return $this->parent->getAuthor($arguments);
}
 
/**
* Returns the content of the content element or info on a specific attribute
*
* This element may or may not be present. It cannot be present more than
* once. It may have a 'src' attribute, in which case there's no content
* If not present, then the entry must have link with rel="alternate".
* If there is content we return it, if not and there's a 'src' attribute
* we return the value of that instead. The method can take an 'attribute'
* argument, in which case we return the value of that attribute if present.
* eg. $item->content("type") will return the type of the content. It is
* recommended that all users check the type before getting the content to
* ensure that their script is capable of handling the type of returned data.
* (data carried in the content element can be either 'text', 'html', 'xhtml',
* or any standard MIME type).
*
* @return string|false
*/
protected function getContent($method, $arguments = array()) {
$attribute = empty($arguments[0]) ? false : $arguments[0];
$tags = $this->model->getElementsByTagName('content');
 
if ($tags->length == 0) {
return false;
}
 
$content = $tags->item(0);
 
if (! $content->hasAttribute('type')) {
$content->setAttribute('type', 'text');
}
if (! empty($attribute)) {
return $content->getAttribute($attribute);
}
 
$type = $content->getAttribute('type');
 
if (! empty($attribute)) {
if ($content->hasAttribute($attribute))
{
return $content->getAttribute($attribute);
}
return false;
}
 
if ($content->hasAttribute('src')) {
return $content->getAttribute('src');
}
 
return $this->parseTextConstruct($content);
}
 
/**
* For compatibility, this method provides a mapping to access enclosures.
*
* The Atom spec doesn't provide for an enclosure element, but it is
* generally supported using the link element with rel='enclosure'.
*
* @param string $method - for compatibility with our __call usage
* @param array $arguments - for compatibility with our __call usage
* @return array|false
*/
function getEnclosure($method, $arguments = array()) {
$offset = isset($arguments[0]) ? $arguments[0] : 0;
$query = "//atom:entry[atom:id='" . $this->getText('id', false) .
"']/atom:link[@rel='enclosure']";
 
$encs = $this->parent->xpath->query($query);
if ($encs->length > $offset) {
try {
if (! $encs->item($offset)->hasAttribute('href')) {
return false;
}
$attrs = $encs->item($offset)->attributes;
$length = $encs->item($offset)->hasAttribute('length') ?
$encs->item($offset)->getAttribute('length') : false;
return array(
'url' => $attrs->getNamedItem('href')->value,
'type' => $attrs->getNamedItem('type')->value,
'length' => $length);
} catch (Exception $e) {
return false;
}
}
return false;
}
/**
* Get details of this entry's source, if available/relevant
*
* Where an atom:entry is taken from another feed then the aggregator
* is supposed to include an atom:source element which replicates at least
* the atom:id, atom:title, and atom:updated metadata from the original
* feed. Atom:source therefore has a very similar structure to atom:feed
* and if we find it we will return it as an XML_Feed_Parser_Atom object.
*
* @return XML_Feed_Parser_Atom|false
*/
function getSource() {
$test = $this->model->getElementsByTagName('source');
if ($test->length == 0) {
return false;
}
$source = new XML_Feed_Parser_Atom($test->item(0));
}
 
/**
* Get the entry as an XML string
*
* Return an XML serialization of the feed, should it be required. Most
* users however, will already have a serialization that they used when
* instantiating the object.
*
* @return string XML serialization of element
*/
function __toString() {
$simple = simplexml_import_dom($this->model);
return $simple->asXML();
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss09Element.php
New file
0,0 → 1,59
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS0.9 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS09Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 0.9 entries. It will usually be called by
* XML_Feed_Parser_RSS09 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss09Element extends XmlFeedParserRss09 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS09
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Link'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserException.php
New file
0,0 → 1,36
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Keeps the exception class for XML_Feed_Parser.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL
* @version CVS: $Id: Exception.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
/**
* XML_Feed_Parser_Exception is a simple extension of PEAR_Exception, existing
* to help with identification of the source of exceptions.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserException extends Exception {
 
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserAtom.php
New file
0,0 → 1,358
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Atom feed class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: Atom.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This is the class that determines how we manage Atom 1.0 feeds
*
* How we deal with constructs:
* date - return as unix datetime for use with the 'date' function unless specified otherwise
* text - return as is. optional parameter will give access to attributes
* person - defaults to name, but parameter based access
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserAtom extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'atom.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
public $xpath;
 
/**
* When performing XPath queries we will use this prefix
* @var string
*/
private $xpathPrefix = '//';
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'Atom 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserAtomElement';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'entry';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'author' => array('Person'),
'contributor' => array('Person'),
'icon' => array('Text'),
'logo' => array('Text'),
'id' => array('Text', 'fail'),
'rights' => array('Text'),
'subtitle' => array('Text'),
'title' => array('Text', 'fail'),
'updated' => array('Date', 'fail'),
'link' => array('Link'),
'generator' => array('Text'),
'category' => array('Category'),
'content' => array('Text'));
 
/**
* Here we provide a few mappings for those very special circumstances in
* which it makes sense to map back to the RSS2 spec. Key is RSS2 version
* value is an array consisting of the equivalent in atom and any attributes
* needed to make the mapping.
* @var array
*/
protected $compatMap = array(
'guid' => array('id'),
'links' => array('link'),
'tags' => array('category'),
'contributors' => array('contributor'));
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($this->model);
$this->xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$this->numberEntries = $this->count('entry');
}
 
/**
* Implement retrieval of an entry based on its ID for atom feeds.
*
* This function uses XPath to get the entry based on its ID. If DOMXPath::evaluate
* is available, we also use that to store a reference to the entry in the array
* used by getEntryByOffset so that method does not have to seek out the entry
* if it's requested that way.
*
* @param string $id any valid Atom ID.
* @return XML_Feed_Parser_AtomElement
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//atom:entry[atom:id='$id']");
 
if ($entries->length > 0) {
$xmlBase = $entries->item(0)->baseURI;
$entry = new $this->itemClass($entries->item(0), $this, $xmlBase);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::atom:entry)", $entries->item(0));
$this->entries[$offset] = $entry;
}
 
$this->idMappings[$id] = $entry;
 
return $entry;
}
}
 
/**
* Retrieves data from a person construct.
*
* Get a person construct. We default to the 'name' element but allow
* access to any of the elements.
*
* @param string $method The name of the person construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string|false
*/
protected function getPerson($method, $arguments) {
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$parameter = empty($arguments[1]['param']) ? 'name' : $arguments[1]['param'];
$section = $this->model->getElementsByTagName($method);
if ($parameter == 'url') {
$parameter = 'uri';
}
 
if ($section->length <= $offset) {
return false;
}
 
$param = $section->item($offset)->getElementsByTagName($parameter);
if ($param->length == 0) {
return false;
}
return $param->item(0)->nodeValue;
}
 
/**
* Retrieves an element's content where that content is a text construct.
*
* Get a text construct. When calling this method, the two arguments
* allowed are 'offset' and 'attribute', so $parser->subtitle() would
* return the content of the element, while $parser->subtitle(false, 'type')
* would return the value of the type attribute.
*
* @todo Clarify overlap with getContent()
* @param string $method The name of the text construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string
*/
protected function getText($method, $arguments = Array()) {
$offset = empty($arguments[0]) ? 0: $arguments[0];
$attribute = empty($arguments[1]) ? false : $arguments[1];
$tags = $this->model->getElementsByTagName($method);
 
if ($tags->length <= $offset) {
return false;
}
 
$content = $tags->item($offset);
 
if (! $content->hasAttribute('type')) {
$content->setAttribute('type', 'text');
}
$type = $content->getAttribute('type');
 
if (! empty($attribute) and
! ($method == 'generator' and $attribute == 'name')) {
if ($content->hasAttribute($attribute)) {
return $content->getAttribute($attribute);
} else if ($attribute == 'href' and $content->hasAttribute('uri')) {
return $content->getAttribute('uri');
}
return false;
}
 
return $this->parseTextConstruct($content);
}
/**
* Extract content appropriately from atom text constructs
*
* Because of different rules applied to the content element and other text
* constructs, they are deployed as separate functions, but they share quite
* a bit of processing. This method performs the core common process, which is
* to apply the rules for different mime types in order to extract the content.
*
* @param DOMNode $content the text construct node to be parsed
* @return String
* @author James Stewart
**/
protected function parseTextConstruct(DOMNode $content) {
if ($content->hasAttribute('type')) {
$type = $content->getAttribute('type');
} else {
$type = 'text';
}
 
if (strpos($type, 'text/') === 0) {
$type = 'text';
}
 
switch ($type) {
case 'text':
case 'html':
return $content->textContent;
break;
case 'xhtml':
$container = $content->getElementsByTagName('div');
if ($container->length == 0) {
return false;
}
$contents = $container->item(0);
if ($contents->hasChildNodes()) {
/* Iterate through, applying xml:base and store the result */
$result = '';
foreach ($contents->childNodes as $node) {
$result .= $this->traverseNode($node);
}
return $result;
}
break;
case preg_match('@^[a-zA-Z]+/[a-zA-Z+]*xml@i', $type) > 0:
return $content;
break;
case 'application/octet-stream':
default:
return base64_decode(trim($content->nodeValue));
break;
}
return false;
}
/**
* Get a category from the entry.
*
* A feed or entry can have any number of categories. A category can have the
* attributes term, scheme and label.
*
* @param string $method The name of the text construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string
*/
function getCategory($method, $arguments) {
$offset = empty($arguments[0]) ? 0: $arguments[0];
$attribute = empty($arguments[1]) ? 'term' : $arguments[1];
$categories = $this->model->getElementsByTagName('category');
if ($categories->length <= $offset) {
$category = $categories->item($offset);
if ($category->hasAttribute($attribute)) {
return $category->getAttribute($attribute);
}
}
return false;
}
 
/**
* This element must be present at least once with rel="feed". This element may be
* present any number of further times so long as there is no clash. If no 'rel' is
* present and we're asked for one, we follow the example of the Universal Feed
* Parser and presume 'alternate'.
*
* @param int $offset the position of the link within the container
* @param string $attribute the attribute name required
* @param array an array of attributes to search by
* @return string the value of the attribute
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
if (is_array($params) and !empty($params)) {
$terms = array();
$alt_predicate = '';
$other_predicate = '';
 
foreach ($params as $key => $value) {
if ($key == 'rel' && $value == 'alternate') {
$alt_predicate = '[not(@rel) or @rel="alternate"]';
} else {
$terms[] = "@$key='$value'";
}
}
if (!empty($terms)) {
$other_predicate = '[' . join(' and ', $terms) . ']';
}
$query = $this->xpathPrefix . 'atom:link' . $alt_predicate . $other_predicate;
$links = $this->xpath->query($query);
} else {
$links = $this->model->getElementsByTagName('link');
}
if ($links->length > $offset) {
if ($links->item($offset)->hasAttribute($attribute)) {
$value = $links->item($offset)->getAttribute($attribute);
if ($attribute == 'href') {
$value = $this->addBase($value, $links->item($offset));
}
return $value;
} else if ($attribute == 'rel') {
return 'alternate';
}
}
return false;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss09.php
New file
0,0 → 1,215
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS0.9 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS09.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS0.9 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Find a Relax NG URI we can use
*/
class XmlFeedParserRss09 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = '';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 0.9';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss09Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'textinput' => array('TextInput'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
 
/**
* Our constructor does nothing more than its parent.
*
* @todo RelaxNG validation
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Included for compatibility -- will not work with RSS 0.9
*
* This is not something that will work with RSS0.9 as it does not have
* clear restrictions on the global uniqueness of IDs.
*
* @param string $id any valid ID.
* @return false
*/
function getEntryById($id) {
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'link' => $image->getElementsByTagName('link')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details,
array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) &&
$input->attributes->getNamedItem('resource')) {
$results['link'] = $input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
/**
* Get details of a link from the feed.
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
 
/**
* Not implemented - no available validation.
*/
public function relaxNGValidate() {
return true;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserType.php
New file
0,0 → 1,455
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Abstract class providing common methods for XML_Feed_Parser feeds.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: Type.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This abstract class provides some general methods that are likely to be
* implemented exactly the same way for all feed types.
*
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
*/
abstract class XmlFeedParserType {
/**
* Where we store our DOM object for this feed
* @var DOMDocument
*/
public $model;
 
/**
* For iteration we'll want a count of the number of entries
* @var int
*/
public $numberEntries;
 
/**
* Where we store our entry objects once instantiated
* @var array
*/
public $entries = array();
 
/**
* Store mappings between entry IDs and their position in the feed
*/
public $idMappings = array();
 
/**
* Proxy to allow use of element names as method names
*
* We are not going to provide methods for every entry type so this
* function will allow for a lot of mapping. We rely pretty heavily
* on this to handle our mappings between other feed types and atom.
*
* @param string $call - the method attempted
* @param array $arguments - arguments to that method
* @return mixed
*/
function __call($call, $arguments = array()) {
if (! is_array($arguments)) {
$arguments = array();
}
 
if (isset($this->compatMap[$call])) {
$tempMap = $this->compatMap;
$tempcall = array_pop($tempMap[$call]);
if (! empty($tempMap)) {
$arguments = array_merge($arguments, $tempMap[$call]);
}
$call = $tempcall;
}
 
/* To be helpful, we allow a case-insensitive search for this method */
if (! isset($this->map[$call])) {
foreach (array_keys($this->map) as $key) {
if (strtoupper($key) == strtoupper($call)) {
$call = $key;
break;
}
}
}
 
if (empty($this->map[$call])) {
return false;
}
 
$method = 'get' . $this->map[$call][0];
if ($method == 'getLink') {
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$attribute = empty($arguments[1]) ? 'href' : $arguments[1];
$params = isset($arguments[2]) ? $arguments[2] : array();
return $this->getLink($offset, $attribute, $params);
}
if (method_exists($this, $method)) {
return $this->$method($call, $arguments);
}
 
return false;
}
 
/**
* Proxy to allow use of element names as attribute names
*
* For many elements variable-style access will be desirable. This function
* provides for that.
*
* @param string $value - the variable required
* @return mixed
*/
function __get($value) {
return $this->__call($value, array());
}
 
/**
* Utility function to help us resolve xml:base values
*
* We have other methods which will traverse the DOM and work out the different
* xml:base declarations we need to be aware of. We then need to combine them.
* If a declaration starts with a protocol then we restart the string. If it
* starts with a / then we add on to the domain name. Otherwise we simply tag
* it on to the end.
*
* @param string $base - the base to add the link to
* @param string $link
*/
function combineBases($base, $link) {
if (preg_match('/^[A-Za-z]+:\/\//', $link)) {
return $link;
} else if (preg_match('/^\//', $link)) {
/* Extract domain and suffix link to that */
preg_match('/^([A-Za-z]+:\/\/.*)?\/*/', $base, $results);
$firstLayer = $results[0];
return $firstLayer . "/" . $link;
} else if (preg_match('/^\.\.\//', $base)) {
/* Step up link to find place to be */
preg_match('/^((\.\.\/)+)(.*)$/', $link, $bases);
$suffix = $bases[3];
$count = preg_match_all('/\.\.\//', $bases[1], $steps);
$url = explode("/", $base);
for ($i = 0; $i <= $count; $i++) {
array_pop($url);
}
return implode("/", $url) . "/" . $suffix;
} else if (preg_match('/^(?!\/$)/', $base)) {
$base = preg_replace('/(.*\/).*$/', '$1', $base) ;
return $base . $link;
} else {
/* Just stick it on the end */
return $base . $link;
}
}
 
/**
* Determine whether we need to apply our xml:base rules
*
* Gets us the xml:base data and then processes that with regard
* to our current link.
*
* @param string
* @param DOMElement
* @return string
*/
function addBase($link, $element) {
if (preg_match('/^[A-Za-z]+:\/\//', $link)) {
return $link;
}
 
return $this->combineBases($element->baseURI, $link);
}
 
/**
* Get an entry by its position in the feed, starting from zero
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by ID.
*
* @param int $offset
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryByOffset($offset) {
if (! isset($this->entries[$offset])) {
$entries = $this->model->getElementsByTagName($this->itemElement);
if ($entries->length > $offset) {
$xmlBase = $entries->item($offset)->baseURI;
$this->entries[$offset] = new $this->itemClass(
$entries->item($offset), $this, $xmlBase);
if ($id = $this->entries[$offset]->id) {
$this->idMappings[$id] = $this->entries[$offset];
}
} else {
throw new XML_Feed_Parser_Exception('No entries found');
}
}
 
return $this->entries[$offset];
}
 
/**
* Return a date in seconds since epoch.
*
* Get a date construct. We use PHP's strtotime to return it as a unix datetime, which
* is the number of seconds since 1970-01-01 00:00:00.
*
* @link http://php.net/strtotime
* @param string $method The name of the date construct we want
* @param array $arguments Included for compatibility with our __call usage
* @return int|false datetime
*/
protected function getDate($method, $arguments) {
$time = $this->model->getElementsByTagName($method);
if ($time->length == 0 || empty($time->item(0)->nodeValue)) {
return false;
}
return strtotime($time->item(0)->nodeValue);
}
 
/**
* Get a text construct.
*
* @param string $method The name of the text construct we want
* @param array $arguments Included for compatibility with our __call usage
* @return string
*/
protected function getText($method, $arguments = array()) {
$tags = $this->model->getElementsByTagName($method);
if ($tags->length > 0) {
$value = $tags->item(0)->nodeValue;
return $value;
}
return false;
}
 
/**
* Apply various rules to retrieve category data.
*
* There is no single way of declaring a category in RSS1/1.1 as there is in RSS2
* and Atom. Instead the usual approach is to use the dublin core namespace to
* declare categories. For example delicious use both:
* <dc:subject>PEAR</dc:subject> and: <taxo:topics><rdf:Bag>
* <rdf:li resource="http://del.icio.us/tag/PEAR" /></rdf:Bag></taxo:topics>
* to declare a categorisation of 'PEAR'.
*
* We need to be sensitive to this where possible.
*
* @param string $call for compatibility with our overloading
* @param array $arguments - arg 0 is the offset, arg 1 is whether to return as array
* @return string|array|false
*/
protected function getCategory($call, $arguments) {
$categories = $this->model->getElementsByTagName('subject');
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$array = empty($arguments[1]) ? false : true;
if ($categories->length <= $offset) {
return false;
}
if ($array) {
$list = array();
foreach ($categories as $category) {
array_push($list, $category->nodeValue);
}
return $list;
}
return $categories->item($offset)->nodeValue;
}
 
/**
* Count occurrences of an element
*
* This function will tell us how many times the element $type
* appears at this level of the feed.
*
* @param string $type the element we want to get a count of
* @return int
*/
protected function count($type) {
if ($tags = $this->model->getElementsByTagName($type)) {
return $tags->length;
}
return 0;
}
 
/**
* Part of our xml:base processing code
*
* We need a couple of methods to access XHTML content stored in feeds.
* This is because we dereference all xml:base references before returning
* the element. This method handles the attributes.
*
* @param DOMElement $node The DOM node we are iterating over
* @return string
*/
function processXHTMLAttributes($node) {
$return = '';
foreach ($node->attributes as $attribute) {
if ($attribute->name == 'src' or $attribute->name == 'href') {
$attribute->value = $this->addBase(htmlentities($attribute->value, NULL, 'utf-8'), $attribute);
}
if ($attribute->name == 'base') {
continue;
}
$return .= $attribute->name . '="' . htmlentities($attribute->value, NULL, 'utf-8') .'" ';
}
if (! empty($return)) {
return ' ' . trim($return);
}
return '';
}
 
/**
* Convert HTML entities based on the current character set.
*
* @param String
* @return String
*/
function processEntitiesForNodeValue($node) {
if (function_exists('iconv')) {
$current_encoding = $node->ownerDocument->encoding;
$value = iconv($current_encoding, 'UTF-8', $node->nodeValue);
} else if ($current_encoding == 'iso-8859-1') {
$value = utf8_encode($node->nodeValue);
} else {
$value = $node->nodeValue;
}
 
$decoded = html_entity_decode($value, NULL, 'UTF-8');
return htmlentities($decoded, NULL, 'UTF-8');
}
 
/**
* Part of our xml:base processing code
*
* We need a couple of methods to access XHTML content stored in feeds.
* This is because we dereference all xml:base references before returning
* the element. This method recurs through the tree descending from the node
* and builds our string.
*
* @param DOMElement $node The DOM node we are processing
* @return string
*/
function traverseNode($node) {
$content = '';
 
/* Add the opening of this node to the content */
if ($node instanceof DOMElement) {
$content .= '<' . $node->tagName .
$this->processXHTMLAttributes($node) . '>';
}
 
/* Process children */
if ($node->hasChildNodes()) {
foreach ($node->childNodes as $child) {
$content .= $this->traverseNode($child);
}
}
 
if ($node instanceof DOMText) {
$content .= $this->processEntitiesForNodeValue($node);
}
 
/* Add the closing of this node to the content */
if ($node instanceof DOMElement) {
$content .= '</' . $node->tagName . '>';
}
 
return $content;
}
 
/**
* Get content from RSS feeds (atom has its own implementation)
*
* The official way to include full content in an RSS1 entry is to use
* the content module's element 'encoded', and RSS2 feeds often duplicate that.
* Often, however, the 'description' element is used instead. We will offer that
* as a fallback. Atom uses its own approach and overrides this method.
*
* @return string|false
*/
protected function getContent($method, $arguments = array()) {
$options = array('encoded', 'description');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length == 0) {
continue;
}
if ($test->item(0)->hasChildNodes()) {
$value = '';
foreach ($test->item(0)->childNodes as $child) {
if ($child instanceof DOMText) {
$value .= $child->nodeValue;
} else {
$simple = simplexml_import_dom($child);
$value .= $simple->asXML();
}
}
return $value;
} else if ($test->length > 0) {
return $test->item(0)->nodeValue;
}
}
return false;
}
 
/**
* Checks if this element has a particular child element.
*
* @param String
* @param Integer
* @return bool
**/
function hasKey($name, $offset = 0) {
$search = $this->model->getElementsByTagName($name);
return $search->length > $offset;
}
 
/**
* Return an XML serialization of the feed, should it be required. Most
* users however, will already have a serialization that they used when
* instantiating the object.
*
* @return string XML serialization of element
*/
function __toString() {
$simple = simplexml_import_dom($this->model);
return $simple->asXML();
}
/**
* Get directory holding RNG schemas. Method is based on that
* found in Contact_AddressBook.
*
* @return string PEAR data directory.
* @access public
* @static
*/
static function getSchemaDir() {
return dirname(__FILE__).'/../schemas';
}
 
public function relaxNGValidate() {
$dir = self::getSchemaDir();
$path = $dir . '/' . $this->relax;
return $this->model->relaxNGValidate($path);
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss1Element.php
New file
0,0 → 1,111
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS1Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 1.0 entries. It will usually be called by
* XML_Feed_Parser_RSS1 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss1Element extends XmlFeedParserRss1 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS1
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'id' => array('Id'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'), # or dc:description
'category' => array('Category'),
'rights' => array('Text'), # dc:rights
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date'), # dc:date
'content' => array('Content')
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS1.
* @var array
*/
protected $compatMap = array(
'content' => array('content'),
'updated' => array('lastBuildDate'),
'published' => array('date'),
'subtitle' => array('description'),
'updated' => array('date'),
'author' => array('creator'),
'contributor' => array('contributor')
);
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* If an rdf:about attribute is specified, return it as an ID
*
* There is no established way of showing an ID for an RSS1 entry. We will
* simulate it using the rdf:about attribute of the entry element. This cannot
* be relied upon for unique IDs but may prove useful.
*
* @return string|false
*/
function getId() {
if ($this->model->attributes->getNamedItem('about')) {
return $this->model->attributes->getNamedItem('about')->nodeValue;
}
return false;
}
 
/**
* How RSS1 should support for enclosures is not clear. For now we will return
* false.
*
* @return false
*/
function getEnclosure() {
return false;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss11Element.php
New file
0,0 → 1,145
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS11Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 1.1 entries. It will usually be called by
* XML_Feed_Parser_RSS11 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss11Element extends XmlFeedParserRss11 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS1
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'id' => array('Id'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'), # or dc:description
'category' => array('Category'),
'rights' => array('Text'), # dc:rights
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date'), # dc:date
'content' => array('Content')
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS1.
* @var array
*/
protected $compatMap = array(
'content' => array('content'),
'updated' => array('lastBuildDate'),
'published' => array('date'),
'subtitle' => array('description'),
'updated' => array('date'),
'author' => array('creator'),
'contributor' => array('contributor')
);
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* If an rdf:about attribute is specified, return that as an ID
*
* There is no established way of showing an ID for an RSS1 entry. We will
* simulate it using the rdf:about attribute of the entry element. This cannot
* be relied upon for unique IDs but may prove useful.
*
* @return string|false
*/
function getId() {
if ($this->model->attributes->getNamedItem('about')) {
return $this->model->attributes->getNamedItem('about')->nodeValue;
}
return false;
}
 
/**
* Return the entry's content
*
* The official way to include full content in an RSS1 entry is to use
* the content module's element 'encoded'. Often, however, the 'description'
* element is used instead. We will offer that as a fallback.
*
* @return string|false
*/
function getContent() {
$options = array('encoded', 'description');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length == 0) {
continue;
}
if ($test->item(0)->hasChildNodes()) {
$value = '';
foreach ($test->item(0)->childNodes as $child) {
if ($child instanceof DOMText) {
$value .= $child->nodeValue;
} else {
$simple = simplexml_import_dom($child);
$value .= $simple->asXML();
}
}
return $value;
} else if ($test->length > 0) {
return $test->item(0)->nodeValue;
}
}
return false;
}
/**
* How RSS1.1 should support for enclosures is not clear. For now we will return
* false.
*
* @return false
*/
function getEnclosure() {
return false;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss2Element.php
New file
0,0 → 1,166
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Class representing entries in an RSS2 feed.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS2Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class provides support for RSS 2.0 entries. It will usually be
* called by XML_Feed_Parser_RSS2 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss2Element extends XmlFeedParserRss2 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS2
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'title' => array('Text'),
'guid' => array('Guid'),
'description' => array('Text'),
'author' => array('Text'),
'comments' => array('Text'),
'enclosure' => array('Enclosure'),
'pubDate' => array('Date'),
'source' => array('Source'),
'link' => array('Text'),
'content' => array('Content'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'id' => array('guid'),
'updated' => array('lastBuildDate'),
'published' => array('pubdate'),
'guidislink' => array('guid', 'ispermalink'),
'summary' => array('description'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS2 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* Get the value of the guid element, if specified
*
* guid is the closest RSS2 has to atom's ID. It is usually but not always a
* URI. The one attribute that RSS2 can posess is 'ispermalink' which specifies
* whether the guid is itself dereferencable. Use of guid is not obligatory,
* but is advisable. To get the guid you would call $item->id() (for atom
* compatibility) or $item->guid(). To check if this guid is a permalink call
* $item->guid("ispermalink").
*
* @param string $method - the method name being called
* @param array $params - parameters required
* @return string the guid or value of ispermalink
*/
protected function getGuid($method, $params) {
$attribute = (isset($params[0]) and $params[0] == 'ispermalink') ?
true : false;
$tag = $this->model->getElementsByTagName('guid');
if ($tag->length > 0) {
if ($attribute) {
if ($tag->hasAttribute("ispermalink")) {
return $tag->getAttribute("ispermalink");
}
}
return $tag->item(0)->nodeValue;
}
return false;
}
 
/**
* Access details of file enclosures
*
* The RSS2 spec is ambiguous as to whether an enclosure element must be
* unique in a given entry. For now we will assume it needn't, and allow
* for an offset.
*
* @param string $method - the method being called
* @param array $parameters - we expect the first of these to be our offset
* @return array|false
*/
protected function getEnclosure($method, $parameters) {
$encs = $this->model->getElementsByTagName('enclosure');
$offset = isset($parameters[0]) ? $parameters[0] : 0;
if ($encs->length > $offset) {
try {
if (! $encs->item($offset)->hasAttribute('url')) {
return false;
}
$attrs = $encs->item($offset)->attributes;
return array(
'url' => $attrs->getNamedItem('url')->value,
'length' => $attrs->getNamedItem('length')->value,
'type' => $attrs->getNamedItem('type')->value);
} catch (Exception $e) {
return false;
}
}
return false;
}
 
/**
* Get the entry source if specified
*
* source is an optional sub-element of item. Like atom:source it tells
* us about where the entry came from (eg. if it's been copied from another
* feed). It is not a rich source of metadata in the same way as atom:source
* and while it would be good to maintain compatibility by returning an
* XML_Feed_Parser_RSS2 element, it makes a lot more sense to return an array.
*
* @return array|false
*/
protected function getSource() {
$get = $this->model->getElementsByTagName('source');
if ($get->length) {
$source = $get->item(0);
$array = array(
'content' => $source->nodeValue);
foreach ($source->attributes as $attribute) {
$array[$attribute->name] = $attribute->value;
}
return $array;
}
return false;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/README
New file
0,0 → 1,9
Most of these schemas are only available in RNC (RelaxNG, Compact) format.
 
libxml (and therefor PHP) only supports RelaxNG - the XML version.
 
To update these, you will need a conversion utility, like trang (http://www.thaiopensource.com/relaxng/trang.html).
 
 
 
clockwerx@clockwerx-desktop:~/trang$ java -jar trang.jar -I rnc -O rng http://atompub.org/2005/08/17/atom.rnc atom.rng
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss10.rng
New file
0,0 → 1,113
<?xml version='1.0' encoding='UTF-8'?>
<!-- http://www.xml.com/lpt/a/2002/01/23/relaxng.html -->
<!-- http://www.oasis-open.org/committees/relax-ng/tutorial-20011203.html -->
<!-- http://www.zvon.org/xxl/XMLSchemaTutorial/Output/ser_wildcards_st8.html -->
 
<grammar xmlns='http://relaxng.org/ns/structure/1.0'
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
ns='http://purl.org/rss/1.0/'
datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'>
 
<start>
<element name='RDF' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<ref name='RDFContent'/>
</element>
</start>
 
<define name='RDFContent' ns='http://purl.org/rss/1.0/'>
<interleave>
<element name='channel'>
<ref name='channelContent'/>
</element>
<optional>
<element name='image'><ref name='imageContent'/></element>
</optional>
<oneOrMore>
<element name='item'><ref name='itemContent'/></element>
</oneOrMore>
</interleave>
</define>
 
<define name='channelContent' combine="interleave">
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<element name='description'><data type='string'/></element>
<element name='image'>
<attribute name='resource' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</element>
<element name='items'>
<ref name='itemsContent'/>
</element>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
<define name="itemsContent">
<element name="Seq" ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<oneOrMore>
<element name="li" ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<choice>
<attribute name='resource'> <!-- Why doesn't RDF/RSS1.0 ns qualify this attribute? -->
<data type='anyURI'/>
</attribute>
<attribute name='resource' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</choice>
</element>
</oneOrMore>
</element>
</define>
<define name='imageContent'>
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<element name='url'><data type='anyURI'/></element>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
 
<define name='itemContent'>
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<optional><element name='description'><data type='string'/></element></optional>
<ref name="anyThing"/>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
 
<define name='anyThing'>
<zeroOrMore>
<choice>
<text/>
<element>
<anyName>
<except>
<nsName/>
</except>
</anyName>
<ref name='anyThing'/>
<zeroOrMore>
<attribute>
<anyName/>
</attribute>
</zeroOrMore>
</element>
</choice>
</zeroOrMore>
</define>
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss11.rng
New file
0,0 → 1,218
<?xml version="1.0" encoding="UTF-8"?>
<!--
RELAX NG Compact Schema for RSS 1.1
Sean B. Palmer, inamidst.com
Christopher Schmidt, crschmidt.net
License: This schema is in the public domain
-->
<grammar xmlns:rss="http://purl.org/net/rss1.1#" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns="http://purl.org/net/rss1.1#" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<ref name="Channel"/>
</start>
<define name="Channel">
<a:documentation>http://purl.org/net/rss1.1#Channel</a:documentation>
<element name="Channel">
<ref name="Channel.content"/>
 
</element>
</define>
<define name="Channel.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<optional>
<ref name="AttrXMLBase"/>
</optional>
 
<ref name="AttrRDFAbout"/>
<interleave>
<ref name="title"/>
<ref name="link"/>
<ref name="description"/>
<optional>
<ref name="image"/>
</optional>
<zeroOrMore>
 
<ref name="Any"/>
</zeroOrMore>
<ref name="items"/>
</interleave>
</define>
<define name="title">
<a:documentation>http://purl.org/net/rss1.1#title</a:documentation>
<element name="title">
 
<ref name="title.content"/>
</element>
</define>
<define name="title.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<text/>
</define>
 
<define name="link">
<a:documentation>http://purl.org/net/rss1.1#link</a:documentation>
<element name="link">
<ref name="link.content"/>
</element>
</define>
<define name="link.content">
<data type="anyURI"/>
 
</define>
<define name="description">
<a:documentation>http://purl.org/net/rss1.1#description</a:documentation>
<element name="description">
<ref name="description.content"/>
</element>
</define>
<define name="description.content">
 
<optional>
<ref name="AttrXMLLang"/>
</optional>
<text/>
</define>
<define name="image">
<a:documentation>http://purl.org/net/rss1.1#image</a:documentation>
<element name="image">
 
<ref name="image.content"/>
</element>
</define>
<define name="image.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFResource"/>
<interleave>
 
<ref name="title"/>
<optional>
<ref name="link"/>
</optional>
<ref name="url"/>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</interleave>
 
</define>
<define name="url">
<a:documentation>http://purl.org/net/rss1.1#url</a:documentation>
<element name="url">
<ref name="url.content"/>
</element>
</define>
<define name="url.content">
 
<data type="anyURI"/>
</define>
<define name="items">
<a:documentation>http://purl.org/net/rss1.1#items</a:documentation>
<element name="items">
<ref name="items.content"/>
</element>
</define>
 
<define name="items.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFCollection"/>
<zeroOrMore>
<ref name="item"/>
</zeroOrMore>
</define>
 
<define name="item">
<a:documentation>http://purl.org/net/rss1.1#item</a:documentation>
<element name="item">
<ref name="item.content"/>
</element>
</define>
<define name="item.content">
<optional>
 
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFAbout"/>
<interleave>
<ref name="title"/>
<ref name="link"/>
<optional>
<ref name="description"/>
</optional>
 
<optional>
<ref name="image"/>
</optional>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</interleave>
</define>
<define name="Any">
 
<a:documentation>http://purl.org/net/rss1.1#Any</a:documentation>
<element>
<anyName>
<except>
<nsName/>
</except>
</anyName>
<ref name="Any.content"/>
 
</element>
</define>
<define name="Any.content">
<zeroOrMore>
<attribute>
<anyName>
<except>
<nsName/>
<nsName ns=""/>
 
</except>
</anyName>
</attribute>
</zeroOrMore>
<mixed>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</mixed>
 
</define>
<define name="AttrXMLLang">
<attribute name="xml:lang">
<data type="language"/>
</attribute>
</define>
<define name="AttrXMLBase">
<attribute name="xml:base">
<data type="anyURI"/>
 
</attribute>
</define>
<define name="AttrRDFAbout">
<attribute name="rdf:about">
<data type="anyURI"/>
</attribute>
</define>
<define name="AttrRDFResource">
<attribute name="rdf:parseType">
 
<value>Resource</value>
</attribute>
</define>
<define name="AttrRDFCollection">
<attribute name="rdf:parseType">
<value>Collection</value>
</attribute>
</define>
 
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss20.rng
New file
0,0 → 1,298
<?xml version="1.0" encoding="utf-8"?>
 
<!-- ======================================================================
* Author: Dino Morelli
* Began: 2004-Feb-18
* Build #: 0001
* Version: 0.1
* E-Mail: dino.morelli@snet.net
* URL: (none yet)
* License: (none yet)
*
* ========================================================================
*
* RSS v2.0 Relax NG schema
*
* ==================================================================== -->
 
 
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
 
<start>
<ref name="element-rss" />
</start>
 
<define name="element-title">
<element name="title">
 
<text />
</element>
</define>
 
<define name="element-description">
<element name="description">
<text />
</element>
</define>
 
<define name="element-link">
<element name="link">
<text />
</element>
</define>
 
<define name="element-category">
<element name="category">
<optional>
 
<attribute name="domain" />
</optional>
<text />
</element>
</define>
 
<define name="element-rss">
<element name="rss">
<attribute name="version">
 
<value>2.0</value>
</attribute>
<element name="channel">
<interleave>
<ref name="element-title" />
<ref name="element-link" />
<ref name="element-description" />
<optional>
 
<element name="language"><text /></element>
</optional>
<optional>
<element name="copyright"><text /></element>
</optional>
<optional>
<element name="lastBuildDate"><text /></element>
</optional>
<optional>
 
<element name="docs"><text /></element>
</optional>
<optional>
<element name="generator"><text /></element>
</optional>
<optional>
<ref name="element-category" />
</optional>
<optional>
 
<element name="managingEditor"><text /></element>
</optional>
<optional>
<element name="webMaster"><text /></element>
</optional>
<optional>
<element name="pubDate"><text /></element>
</optional>
<optional>
 
<element name="rating"><text /></element>
</optional>
<optional>
<element name="image">
<interleave>
<element name="url"><text /></element>
<ref name="element-title" />
<ref name="element-link" />
<optional>
 
<element name="width"><text /></element>
</optional>
<optional>
<element name="height"><text /></element>
</optional>
<optional>
<ref name="element-description" />
</optional>
</interleave>
 
</element>
</optional>
<optional>
<element name="cloud">
<attribute name="domain" />
<attribute name="port" />
<attribute name="path" />
<attribute name="registerProcedure" />
<attribute name="protocol" />
 
</element>
</optional>
<optional>
<element name="textInput">
<interleave>
<ref name="element-title" />
<ref name="element-description" />
<element name="name"><text /></element>
<ref name="element-link" />
 
</interleave>
</element>
</optional>
<optional>
<element name="skipHours">
<oneOrMore>
<element name="hour">
<choice>
<value>0</value>
 
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
<value>6</value>
 
<value>7</value>
<value>8</value>
<value>9</value>
<value>10</value>
<value>11</value>
<value>12</value>
 
<value>13</value>
<value>14</value>
<value>15</value>
<value>16</value>
<value>17</value>
<value>18</value>
 
<value>19</value>
<value>20</value>
<value>21</value>
<value>22</value>
<value>23</value>
</choice>
 
</element>
</oneOrMore>
</element>
</optional>
<optional>
<element name="skipDays">
<oneOrMore>
<element name="day">
<choice>
 
<value>0</value>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
 
<value>6</value>
<value>7</value>
<value>8</value>
<value>9</value>
<value>10</value>
<value>11</value>
 
<value>12</value>
<value>13</value>
<value>14</value>
<value>15</value>
<value>16</value>
<value>17</value>
 
<value>18</value>
<value>19</value>
<value>20</value>
<value>21</value>
<value>22</value>
<value>23</value>
 
<value>24</value>
<value>25</value>
<value>26</value>
<value>27</value>
<value>28</value>
<value>29</value>
 
<value>30</value>
<value>31</value>
</choice>
</element>
</oneOrMore>
</element>
</optional>
<optional>
 
<element name="ttl"><text /></element>
</optional>
<zeroOrMore>
<element name="item">
<interleave>
<choice>
<ref name="element-title" />
<ref name="element-description" />
<interleave>
 
<ref name="element-title" />
<ref name="element-description" />
</interleave>
</choice>
<optional>
<ref name="element-link" />
</optional>
<optional>
<element name="author"><text /></element>
 
</optional>
<optional>
<ref name="element-category" />
</optional>
<optional>
<element name="comments"><text /></element>
</optional>
<optional>
<element name="enclosure">
 
<attribute name="url" />
<attribute name="length" />
<attribute name="type" />
<text />
</element>
</optional>
<optional>
<element name="guid">
<optional>
 
<attribute name="isPermaLink">
<choice>
<value>true</value>
<value>false</value>
</choice>
</attribute>
</optional>
<text />
 
</element>
</optional>
<optional>
<element name="pubDate"><text /></element>
</optional>
<optional>
<element name="source">
<attribute name="url" />
<text />
 
</element>
</optional>
</interleave>
</element>
</zeroOrMore>
</interleave>
</element>
</element>
</define>
 
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/atom.rng
New file
0,0 → 1,598
<?xml version="1.0" encoding="UTF-8"?>
<!--
-*- rnc -*-
RELAX NG Compact Syntax Grammar for the
Atom Format Specification Version 11
-->
<grammar ns="http://www.w3.org/1999/xhtml" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:s="http://www.ascc.net/xml/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<choice>
<ref name="atomFeed"/>
<ref name="atomEntry"/>
</choice>
</start>
<!-- Common attributes -->
<define name="atomCommonAttributes">
<optional>
<attribute name="xml:base">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="xml:lang">
<ref name="atomLanguageTag"/>
</attribute>
</optional>
<zeroOrMore>
<ref name="undefinedAttribute"/>
</zeroOrMore>
</define>
<!-- Text Constructs -->
<define name="atomPlainTextConstruct">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<choice>
<value>text</value>
<value>html</value>
</choice>
</attribute>
</optional>
<text/>
</define>
<define name="atomXHTMLTextConstruct">
<ref name="atomCommonAttributes"/>
<attribute name="type">
<value>xhtml</value>
</attribute>
<ref name="xhtmlDiv"/>
</define>
<define name="atomTextConstruct">
<choice>
<ref name="atomPlainTextConstruct"/>
<ref name="atomXHTMLTextConstruct"/>
</choice>
</define>
<!-- Person Construct -->
<define name="atomPersonConstruct">
<ref name="atomCommonAttributes"/>
<interleave>
<element name="atom:name">
<text/>
</element>
<optional>
<element name="atom:uri">
<ref name="atomUri"/>
</element>
</optional>
<optional>
<element name="atom:email">
<ref name="atomEmailAddress"/>
</element>
</optional>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</define>
<!-- Date Construct -->
<define name="atomDateConstruct">
<ref name="atomCommonAttributes"/>
<data type="dateTime"/>
</define>
<!-- atom:feed -->
<define name="atomFeed">
<element name="atom:feed">
<s:rule context="atom:feed">
<s:assert test="atom:author or not(atom:entry[not(atom:author)])">An atom:feed must have an atom:author unless all of its atom:entry children have an atom:author.</s:assert>
</s:rule>
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<optional>
<ref name="atomGenerator"/>
</optional>
<optional>
<ref name="atomIcon"/>
</optional>
<ref name="atomId"/>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomLogo"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSubtitle"/>
</optional>
<ref name="atomTitle"/>
<ref name="atomUpdated"/>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
<zeroOrMore>
<ref name="atomEntry"/>
</zeroOrMore>
</element>
</define>
<!-- atom:entry -->
<define name="atomEntry">
<element name="atom:entry">
<s:rule context="atom:entry">
<s:assert test="atom:link[@rel='alternate'] or atom:link[not(@rel)] or atom:content">An atom:entry must have at least one atom:link element with a rel attribute of 'alternate' or an atom:content.</s:assert>
</s:rule>
<s:rule context="atom:entry">
<s:assert test="atom:author or ../atom:author or atom:source/atom:author">An atom:entry must have an atom:author if its feed does not.</s:assert>
</s:rule>
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<optional>
<ref name="atomContent"/>
</optional>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<ref name="atomId"/>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomPublished"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSource"/>
</optional>
<optional>
<ref name="atomSummary"/>
</optional>
<ref name="atomTitle"/>
<ref name="atomUpdated"/>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</element>
</define>
<!-- atom:content -->
<define name="atomInlineTextContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<choice>
<value>text</value>
<value>html</value>
</choice>
</attribute>
</optional>
<zeroOrMore>
<text/>
</zeroOrMore>
</element>
</define>
<define name="atomInlineXHTMLContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<attribute name="type">
<value>xhtml</value>
</attribute>
<ref name="xhtmlDiv"/>
</element>
</define>
<define name="atomInlineOtherContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="atomOutOfLineContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<attribute name="src">
<ref name="atomUri"/>
</attribute>
<empty/>
</element>
</define>
<define name="atomContent">
<choice>
<ref name="atomInlineTextContent"/>
<ref name="atomInlineXHTMLContent"/>
<ref name="atomInlineOtherContent"/>
<ref name="atomOutOfLineContent"/>
</choice>
</define>
<!-- atom:author -->
<define name="atomAuthor">
<element name="atom:author">
<ref name="atomPersonConstruct"/>
</element>
</define>
<!-- atom:category -->
<define name="atomCategory">
<element name="atom:category">
<ref name="atomCommonAttributes"/>
<attribute name="term"/>
<optional>
<attribute name="scheme">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="label"/>
</optional>
<ref name="undefinedContent"/>
</element>
</define>
<!-- atom:contributor -->
<define name="atomContributor">
<element name="atom:contributor">
<ref name="atomPersonConstruct"/>
</element>
</define>
<!-- atom:generator -->
<define name="atomGenerator">
<element name="atom:generator">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="uri">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="version"/>
</optional>
<text/>
</element>
</define>
<!-- atom:icon -->
<define name="atomIcon">
<element name="atom:icon">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:id -->
<define name="atomId">
<element name="atom:id">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:logo -->
<define name="atomLogo">
<element name="atom:logo">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:link -->
<define name="atomLink">
<element name="atom:link">
<ref name="atomCommonAttributes"/>
<attribute name="href">
<ref name="atomUri"/>
</attribute>
<optional>
<attribute name="rel">
<choice>
<ref name="atomNCName"/>
<ref name="atomUri"/>
</choice>
</attribute>
</optional>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<optional>
<attribute name="hreflang">
<ref name="atomLanguageTag"/>
</attribute>
</optional>
<optional>
<attribute name="title"/>
</optional>
<optional>
<attribute name="length"/>
</optional>
<ref name="undefinedContent"/>
</element>
</define>
<!-- atom:published -->
<define name="atomPublished">
<element name="atom:published">
<ref name="atomDateConstruct"/>
</element>
</define>
<!-- atom:rights -->
<define name="atomRights">
<element name="atom:rights">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:source -->
<define name="atomSource">
<element name="atom:source">
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<optional>
<ref name="atomGenerator"/>
</optional>
<optional>
<ref name="atomIcon"/>
</optional>
<optional>
<ref name="atomId"/>
</optional>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomLogo"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSubtitle"/>
</optional>
<optional>
<ref name="atomTitle"/>
</optional>
<optional>
<ref name="atomUpdated"/>
</optional>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</element>
</define>
<!-- atom:subtitle -->
<define name="atomSubtitle">
<element name="atom:subtitle">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:summary -->
<define name="atomSummary">
<element name="atom:summary">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:title -->
<define name="atomTitle">
<element name="atom:title">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:updated -->
<define name="atomUpdated">
<element name="atom:updated">
<ref name="atomDateConstruct"/>
</element>
</define>
<!-- Low-level simple types -->
<define name="atomNCName">
<data type="string">
<param name="minLength">1</param>
<param name="pattern">[^:]*</param>
</data>
</define>
<!-- Whatever a media type is, it contains at least one slash -->
<define name="atomMediaType">
<data type="string">
<param name="pattern">.+/.+</param>
</data>
</define>
<!-- As defined in RFC 3066 -->
<define name="atomLanguageTag">
<data type="string">
<param name="pattern">[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*</param>
</data>
</define>
<!--
Unconstrained; it's not entirely clear how IRI fit into
xsd:anyURI so let's not try to constrain it here
-->
<define name="atomUri">
<text/>
</define>
<!-- Whatever an email address is, it contains at least one @ -->
<define name="atomEmailAddress">
<data type="string">
<param name="pattern">.+@.+</param>
</data>
</define>
<!-- Simple Extension -->
<define name="simpleExtensionElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<text/>
</element>
</define>
<!-- Structured Extension -->
<define name="structuredExtensionElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<choice>
<group>
<oneOrMore>
<attribute>
<anyName/>
</attribute>
</oneOrMore>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</group>
<group>
<zeroOrMore>
<attribute>
<anyName/>
</attribute>
</zeroOrMore>
<group>
<optional>
<text/>
</optional>
<oneOrMore>
<ref name="anyElement"/>
</oneOrMore>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</group>
</group>
</choice>
</element>
</define>
<!-- Other Extensibility -->
<define name="extensionElement">
<choice>
<ref name="simpleExtensionElement"/>
<ref name="structuredExtensionElement"/>
</choice>
</define>
<define name="undefinedAttribute">
<attribute>
<anyName>
<except>
<name>xml:base</name>
<name>xml:lang</name>
<nsName ns=""/>
</except>
</anyName>
</attribute>
</define>
<define name="undefinedContent">
<zeroOrMore>
<choice>
<text/>
<ref name="anyForeignElement"/>
</choice>
</zeroOrMore>
</define>
<define name="anyElement">
<element>
<anyName/>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="anyForeignElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<!-- XHTML -->
<define name="anyXHTML">
<element>
<nsName/>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyXHTML"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="xhtmlDiv">
<element name="xhtml:div">
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyXHTML"/>
</choice>
</zeroOrMore>
</element>
</define>
</grammar>
<!-- EOF -->
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/XmlFeedParser.php
New file
0,0 → 1,304
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Key gateway class for XML_Feed_Parser package
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL
* @version CVS: $Id: Parser.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This is the core of the XML_Feed_Parser package. It identifies feed types
* and abstracts access to them. It is an iterator, allowing for easy access
* to the entire feed.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParser implements Iterator {
/**
* This is where we hold the feed object
* @var Object
*/
private $feed;
 
/**
* To allow for extensions, we make a public reference to the feed model
* @var DOMDocument
*/
public $model;
/**
* A map between entry ID and offset
* @var array
*/
protected $idMappings = array();
 
/**
* A storage space for Namespace URIs.
* @var array
*/
private $feedNamespaces = array(
'rss2' => array(
'http://backend.userland.com/rss',
'http://backend.userland.com/rss2',
'http://blogs.law.harvard.edu/tech/rss'));
/**
* Detects feed types and instantiate appropriate objects.
*
* Our constructor takes care of detecting feed types and instantiating
* appropriate classes. For now we're going to treat Atom 0.3 as Atom 1.0
* but raise a warning. I do not intend to introduce full support for
* Atom 0.3 as it has been deprecated, but others are welcome to.
*
* @param string $feed XML serialization of the feed
* @param bool $strict Whether or not to validate the feed
* @param bool $suppressWarnings Trigger errors for deprecated feed types?
* @param bool $tidy Whether or not to try and use the tidy library on input
*/
function __construct($feed, $strict = false, $suppressWarnings = true, $tidy = true) {
$this->model = new DOMDocument;
if (! $this->model->loadXML($feed)) {
if (extension_loaded('tidy') && $tidy) {
$tidy = new tidy;
$tidy->parseString($feed, array('input-xml' => true, 'output-xml' => true));
$tidy->cleanRepair();
if (! $this->model->loadXML((string) $tidy)) {
throw new XmlFeedParserException("Entrée invalide : le flux n'est pas du XML valide");
}
} else {
throw new XmlFeedParserException("Entrée invalide : le flux n'est pas du XML valide");
}
}
 
/* detect feed type */
$doc_element = $this->model->documentElement;
$error = false;
 
switch (true) {
case ($doc_element->namespaceURI == 'http://www.w3.org/2005/Atom'):
$class = 'XmlFeedParserAtom';
break;
case ($doc_element->namespaceURI == 'http://purl.org/atom/ns#'):
$class = 'XmlFeedParserAtom';
$error = "Atom 0.3 est déprécié, le parseur en version 1.0 sera utilisé mais toutes les options ne seront pas disponibles.";
break;
case ($doc_element->namespaceURI == 'http://purl.org/rss/1.0/'
|| ($doc_element->hasChildNodes() && $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://purl.org/rss/1.0/')):
$class = 'XmlFeedParserRss1';
break;
case ($doc_element->namespaceURI == 'http://purl.org/rss/1.1/'
|| ($doc_element->hasChildNodes()
&& $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://purl.org/rss/1.1/')):
$class = 'XmlFeedParserRss11';
break;
case (($doc_element->hasChildNodes()
&& $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://my.netscape.com/rdf/simple/0.9/')
|| $doc_element->namespaceURI == 'http://my.netscape.com/rdf/simple/0.9/'):
$class = 'XmlFeedParserRss09';
break;
case ($doc_element->tagName == 'rss'
and $doc_element->hasAttribute('version')
&& $doc_element->getAttribute('version') == 0.91):
$error = 'RSS 0.91 has been superceded by RSS2.0. Using RSS2.0 parser.';
$class = 'XmlFeedParserRss2';
break;
case ($doc_element->tagName == 'rss'
and $doc_element->hasAttribute('version')
&& $doc_element->getAttribute('version') == 0.92):
$error = 'RSS 0.92 has been superceded by RSS2.0. Using RSS2.0 parser.';
$class = 'XmlFeedParserRss2';
break;
case (in_array($doc_element->namespaceURI, $this->feedNamespaces['rss2'])
|| $doc_element->tagName == 'rss'):
if (! $doc_element->hasAttribute('version') || $doc_element->getAttribute('version') != 2) {
$error = 'RSS version not specified. Parsing as RSS2.0';
}
$class = 'XmlFeedParserRss2';
break;
default:
throw new XmlFeedParserException('Type de flux de syndicaton inconnu');
break;
}
 
if (! $suppressWarnings && ! empty($error)) {
trigger_error($error, E_USER_WARNING);
}
 
/* Instantiate feed object */
$this->feed = new $class($this->model, $strict);
}
 
/**
* Proxy to allow feed element names to be used as method names
*
* For top-level feed elements we will provide access using methods or
* attributes. This function simply passes on a request to the appropriate
* feed type object.
*
* @param string $call - the method being called
* @param array $attributes
*/
function __call($call, $attributes) {
$attributes = array_pad($attributes, 5, false);
list($a, $b, $c, $d, $e) = $attributes;
return $this->feed->$call($a, $b, $c, $d, $e);
}
 
/**
* Proxy to allow feed element names to be used as attribute names
*
* To allow variable-like access to feed-level data we use this
* method. It simply passes along to __call() which in turn passes
* along to the relevant object.
*
* @param string $val - the name of the variable required
*/
function __get($val) {
return $this->feed->$val;
}
 
/**
* Provides iteration functionality.
*
* Of course we must be able to iterate... This function simply increases
* our internal counter.
*/
function next() {
if (isset($this->current_item) &&
$this->current_item <= $this->feed->numberEntries - 1) {
++$this->current_item;
} else if (! isset($this->current_item)) {
$this->current_item = 0;
} else {
return false;
}
}
 
/**
* Return XML_Feed_Type object for current element
*
* @return XML_Feed_Parser_Type Object
*/
function current() {
return $this->getEntryByOffset($this->current_item);
}
 
/**
* For iteration -- returns the key for the current stage in the array.
*
* @return int
*/
function key() {
return $this->current_item;
}
 
/**
* For iteration -- tells whether we have reached the
* end.
*
* @return bool
*/
function valid() {
return $this->current_item < $this->feed->numberEntries;
}
 
/**
* For iteration -- resets the internal counter to the beginning.
*/
function rewind() {
$this->current_item = 0;
}
 
/**
* Provides access to entries by ID if one is specified in the source feed.
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by offset. This method can be quite slow
* if dealing with a large feed that hasn't yet been processed as it
* instantiates objects for every entry until it finds the one needed.
*
* @param string $id Valid ID for the given feed format
* @return XML_Feed_Parser_Type|false
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->getEntryByOffset($this->idMappings[$id]);
}
 
/*
* Since we have not yet encountered that ID, let's go through all the
* remaining entries in order till we find it.
* This is a fairly slow implementation, but it should work.
*/
return $this->feed->getEntryById($id);
}
 
/**
* Retrieve entry by numeric offset, starting from zero.
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by ID.
*
* @param int $offset The position of the entry within the feed, starting from 0
* @return XML_Feed_Parser_Type|false
*/
function getEntryByOffset($offset) {
if ($offset < $this->feed->numberEntries) {
if (isset($this->feed->entries[$offset])) {
return $this->feed->entries[$offset];
} else {
try {
$this->feed->getEntryByOffset($offset);
} catch (Exception $e) {
return false;
}
$id = $this->feed->entries[$offset]->getID();
$this->idMappings[$id] = $offset;
return $this->feed->entries[$offset];
}
} else {
return false;
}
}
 
/**
* Retrieve version details from feed type class.
*
* @return void
* @author James Stewart
*/
function version() {
return $this->feed->version;
}
/**
* Returns a string representation of the feed.
*
* @return String
**/
function __toString() {
return $this->feed->__toString();
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v3.01-serpe/widget/modules/photo/bibliotheque/Cache.php
New file
0,0 → 1,128
<?php
class Cache {
private $actif = null;
private $dossier_stockage = null;
private $duree_de_vie = null;
public function __construct($dossier_stockage = null, $duree_de_vie = null, $activation = true) {
$this->actif = ($activation) ? true : false;
if ($this->actif) {
$this->dossier_stockage = $dossier_stockage;
if (is_null($dossier_stockage)) {
$this->dossier_stockage = self::getDossierTmp();
}
$this->duree_de_vie = $duree_de_vie;
if (is_null($duree_de_vie)) {
$this->duree_de_vie = 3600*24;
}
}
}
public function charger($id) {
$contenu = false;
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (file_exists($chemin_fichier_cache ) && (time() - @filemtime($chemin_fichier_cache) < $this->duree_de_vie)) {
$contenu = file_get_contents($chemin_fichier_cache);
}
}
return $contenu;
}
public function sauver($id, $contenu) {
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (!file_exists($chemin_fichier_cache) || (time() - @filemtime($chemin_fichier_cache) > $this->duree_de_vie)) {
$fh = fopen($chemin_fichier_cache,'w+');
if ($fh) {
fputs($fh, $contenu);
fclose($fh);
}
}
}
}
/**
* Détermine le dossier système temporaire et détecte si nous y avons accès en lecture et écriture.
*
* Inspiré de Zend_File_Transfer_Adapter_Abstract & Zend_Cache
*
* @return string|false le chemine vers le dossier temporaire ou false en cas d'échec.
*/
private static function getDossierTmp() {
$dossier_tmp = false;
foreach (array($_ENV, $_SERVER) as $environnement) {
foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $cle) {
if (isset($environnement[$cle])) {
if (($cle == 'windir') or ($cle == 'SystemRoot')) {
$dossier = realpath($environnement[$cle] . '\\temp');
} else {
$dossier = realpath($environnement[$cle]);
}
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
break 2;
}
}
}
}
if ( ! $dossier_tmp) {
$dossier_televersement_tmp = ini_get('upload_tmp_dir');
if ($dossier_televersement_tmp) {
$dossier = realpath($dossier_televersement_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
if (function_exists('sys_get_temp_dir')) {
$dossier = sys_get_temp_dir();
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
// Tentative de création d'un fichier temporaire
$fichier_tmp = tempnam(md5(uniqid(rand(), TRUE)), '');
if ($fichier_tmp) {
$dossier = realpath(dirname($fichier_tmp));
unlink($fichier_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('/tmp')) {
$dossier_tmp = '/tmp';
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('\\temp')) {
$dossier_tmp = '\\temp';
}
return $dossier_tmp;
}
/**
* Vérifie si le fichier ou dossier est accessible en lecture et écriture.
*
* @param $ressource chemin vers le dossier ou fichier à tester
* @return boolean true si la ressource est accessible en lecture et écriture.
*/
protected static function etreAccessibleEnLectureEtEcriture($ressource){
$accessible = false;
if (is_readable($ressource) && is_writable($ressource)) {
$accessible = true;
}
return $accessible;
}
}
?>
/branches/v3.01-serpe/widget/modules/photo/squelettes/photo_nl.tpl.html
New file
0,0 → 1,208
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Publieke foto's CEL - Tela Botanica</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Tela Botanica" />
<meta name="keywords" content="Tela Botanica, foto, CEL" />
<meta name="description" content="Presentatiewidget van de meest recente foto’s die op de ‘Carnet en Ligne’ van Tela Botanica werden gepubliceerd" />
 
<!-- OpenGraph pour Facebook, Pinterest, Google+ -->
<meta property="og:type" content="website" />
<meta property="og:title" content="Widgetfoto CeL" />
<meta property="og:site_name" content="Tela Botanica" />
<meta property="og:description" content="Minifotoreeks publieke waarnemingen van de ‘Carnet en Ligne’" />
<?php
if (isset($items[0])) {
$iz = $items[0];
$izUrl = sprintf($iz['url_tpl'], 'CRS');
echo '<meta property="og:image" content="' . $izUrl . '" />';
} else {
echo '<meta property="og:image" content="https://resources.tela-botanica.org/tb/img/256x256/carre_englobant.png" />'
.'<meta property="og:image:type" content="image/png" />'
.'<meta property="og:image:width" content="256" />'
.'<meta property="og:image:height" content="256" />';
}
?>
<meta property="og:locale" content="fr_FR" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="https://resources.tela-botanica.org/tb/img/16x16/favicon.png" />
<link rel="shortcut icon" type="image/x-icon" href="https://resources.tela-botanica.org/tb/img/16x16/favicon.ico" />
<!-- Feuilles de styles -->
<link rel="stylesheet" type="text/css" href="https://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" media="screen" />
<link rel="stylesheet" type="text/css" href="<?=$url_css?>photo.css" media="screen" />
<style type="text/css">
html {
overflow:hidden;
}
body{
overflow:hidden;
padding:0;
margin:0;
width:100%;
height:100%;
background-color:#DDDDDD;
color:black;
}
#cel-photo-contenu<?=$id?>, #cel-galerie-photo<?=$id?>{
width:<?=(($colonne * 69))?>px;
}
#cel-galerie-photo<?=$id?> #cel-photo-extra<?=$id?> img{
width:<?=(($colonne * 69)-6)?>px;
}
</style>
<!-- Javascript : bibliothèques -->
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6/jquery-1.6.min.js"></script>
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.js"></script>
 
<!-- Google Analytics -->
<?php if($prod): ?>
<?php include "analytics.html"; ?>
<?php endif; ?>
</head>
<body>
<!-- WIDGET:CEL:PHOTO - DEBUT -->
<div id="cel-photo-contenu<?=$id?>" class="cel-photo-contenu">
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Fouten en informatie</h1>
<p>Kan flow niet weergeven</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
<? if (!empty($titre)) : ?>
<?=$titre?>
<? endif ; ?>
<? if($icone_rss) : ?>
<a href="<?=$flux_rss_url?>"
class="cel-photo-flux"
title="Afbeeldingen volgen"
onclick="window.open(this.href);return false;">
<img src="https://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Afbeeldingen volgen" />
</a>
<? endif; ?>
</h1>
<div id="cel-galerie-photo<?=$id?>">
<?php foreach ($items as $item) : ?>
<div class="cel-photo">
<a href="<?=sprintf($item['url_tpl'], 'XL')?>" class="cel-img" title="<?=$item['titre']?> - Gepubliceerd op <?=$item['date']?> - GUID : <?=$item['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($item['url_tpl'], 'CRX2S')?>" alt="<?=$item['titre']?>"/>
</a>
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<strong>
<?php if ($item['eflore_url'] != '#' && $item['eflore_url'] != '') { ?>
<a class="cel-img-titre" href="<?=$item['eflore_url']?>"
onclick="window.open(this.href);return false;"
title="Klik hier om toegang te krijgen tot de eFlore fiche">
<?=$item['infos']['nom_sci']?>
</a> door
<a class="cel-img-contact"
href="?mode=contact&nn=<?= urlencode($item['infos']['nn']) ;?>&nom_sci=<?= urlencode($item['infos']['nom_sci']) ;?>&date=<?= urlencode($item['infos']['date']) ;?>&id_image=<?= $item['guid']; ?>&lang=nl"
title="Klik hier om contact op te nemen met de auteur van de foto">
<?=$item['infos']['auteur']?>
</a>
te <?= $item['infos']['localite'] ?>
op <?=$item['infos']['date']?>
<?php } else { ?>
<?=$item['titre']?>
<?php } ?>
</strong><br />
<span class="cel-img-date">Gepubliceerd op <?=$item['date']?></span>
</div>
</div>
<?php endforeach; ?>
<?php if ($extra_actif) : ?>
<div id="cel-photo-extra<?=$id?>" class="cel-photo-extra cel-photo">
<a href="<?=sprintf($extra['url_tpl'], 'XL')?>" class="cel-img" title="<?=$extra['titre']?> - Gepubliceerd op <?=$extra['date']?> - GUID : <?=$extra['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($extra['url_tpl'], 'CRS')?>" alt="<?=$extra['titre']?>"/>
</a>
</div>
</div>
<?php endif ?>
<p class="cel-photo-pieds discretion nettoyage">
<span class="cel-photo-source">
Bron :
<a href="http://www.tela-botanica.org/page:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
</span>
<span class="cel-photo-date-generation">Au <?=strftime('%A %d %B %Y te %H:%M:%S')?></span>
</p>
<script type="text/Javascript">
//<![CDATA[
var utiliseFancybox = "<?= $utilise_fancybox; ?>";
if(utiliseFancybox) {
$('a.cel-img').attr('rel', 'galerie-princ<?=$id?>').fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /GUID : ([0-9]+)$/;
motif.exec(titre);
var guid = RegExp.$1;
var info = $('#cel-info-'+guid).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Beeld nr.' + (currentIndex + 1) + ' op ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
});
} else {
$('a.cel-img').click(function(event) {
ouvrirFenetrePopup($(this));
event.preventDefault();
});
}
$(document).ready(function() {
$('a.cel-img-contact').live('click', function(event) {
event.preventDefault();
ouvrirFenetreContact($(this));
});
});
function ouvrirFenetrePopup(lienImage) {
var url = "?mode=popup&url_image="+lienImage.attr('href')+'&galerie_id=<?= $galerie_id ?>';
window.open(url, '', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(700)+', height='+(650));
}
function ouvrirFenetreContact(lienImage) {
var url = lienImage.attr("href");
window.open(url, '_blank', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(400)+', height='+(550));
}
//]]>
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:PHOTO - FIN -->
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/squelettes/popup.tpl.html
New file
0,0 → 1,145
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="<?=$url_css?>popup.css" media="screen" />
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6/jquery-1.6.min.js"></script>
</head>
<body>
<script type="text/javascript">
//<![CDATA[
var urls = [<?= '"'.implode($urls, '","').'"'; ?>];
var infos_images = <?= json_encode($infos_images); ?>;
var indexImage = 0;
var urlImage = "<?= $url_image; ?>";
var tailleMax = 580;
function redimensionnerImage(objet) {
objet.removeAttr("width");
objet.removeAttr("height");
var hauteurImage = objet.height();
var largeurImage = objet.width();
var rapport = 1;
if(hauteurImage > largeurImage && hauteurImage > tailleMax) {
rapport = largeurImage/hauteurImage;
hauteurImage = 580;
largeurImage = hauteurImage*rapport;
$('#illustration').attr("height", hauteurImage);
$('#illustration').attr("width", largeurImage);
}
hauteurFleches = ((hauteurImage+90)/2);
$('#info-img-galerie .conteneur-precedent').attr("top", hauteurFleches);
$('#info-img-galerie .conteneur-suivant').attr("top", hauteurFleches);
window.resizeTo(largeurImage+120,hauteurImage+120);
}
function imageSuivante() {
indexImage++;
if(indexImage >= urls.length) {
indexImage = 0;
}
afficherTitreImage();
$('#illustration').attr('src', urls[indexImage]);
}
function imagePrecedente() {
indexImage--;
if(indexImage <= 0) {
indexImage = urls.length - 1;
}
afficherTitreImage();
$('#illustration').attr('src', urls[indexImage]);
}
function afficherTitreImage() {
item = infos_images[urls[indexImage]];
var titre = item['titre'];
var infos = decouperTitre(titre);
var lienContact = '<?= $url_widget ?>?mode=contact&nn='+infos.nn+
'&nom_sci='+infos.nom_sci+
'&date='+infos.date+
'&id_image='+item['guid'];
titre = '<a href="'+item['lien']+'">'+infos.nom_sci+'</a> '+
' par <a class="lien_contact" href="'+lienContact+'">'+infos.auteur+'</a> '+
' le '+infos.date+' ';
$('#bloc-infos-img').html(titre);
}
function decouperTitre(titre) {
var tab_titre = titre.split('[nn');
var nom_sci = tab_titre[0];
var tab_titre_suite = tab_titre[1].split(' par ');
var nn = '[nn'+tab_titre_suite[0];
var tab_titre_fin = tab_titre_suite[1].split(' le ');
var utilisateur = tab_titre_fin[0];
var date = tab_titre_fin[1];
var titre_decoupe = {'nom_sci' : nom_sci, 'nn' : nn, 'date' : date, 'auteur' : utilisateur};
return titre_decoupe;
}
function ouvrirFenetreContact(lienImage) {
var url = lienImage.attr("href");
window.open(url, '_blank', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(400)+', height='+(550));
}
$(document).ready(function() {
$('#precedent').click(function() {
imagePrecedente();
});
$('#suivant').click(function() {
imageSuivante();
});
if(urlImage != "null" && urlImage != "") {
indexImage = Array.indexOf(urls, urlImage);
$('#illustration').attr('src', urls[indexImage]);
afficherTitreImage();
}
$('#illustration').load(function() {
redimensionnerImage($(this));
});
$("body").keydown(function(e) {
if(e.keyCode == 37) { // gauche
imagePrecedente();
}
else if(e.keyCode == 39) { // droite
imageSuivante();
}
});
$('.lien_contact').live('click', function(event) {
event.preventDefault();
ouvrirFenetreContact($(this));
});
});
//]]>
</script>
 
<div id="info-img-galerie">
<div class="conteneur-precedent">
<a id="precedent" href="#" title="cliquez ici ou utilisez la flèche gauche pour afficher l'image précédente">
<img style="border:none" src="https://www.tela-botanica.org/sites/commun/generique/images/flecheGauche.jpg" alt="&lt;" />
</a>
</div>
<div class="img-cadre">
<img id="illustration" src="<?=$urls[0]?>" alt="" /><br />
</div>
<div class="conteneur-suivant">
<a id="suivant" href="#" title="cliquez ici ou utilisez la flèche droite pour afficher l'image suivante">
<img style="border:none" src="https://www.tela-botanica.org/sites/commun/generique/images/flecheDroite.jpg" alt="&gt;" />
</a>
</div>
<hr class="nettoyage" />
<div id="bloc-infos-img"></div>
</div>
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/squelettes/contact_nl.tpl.html
New file
0,0 → 1,131
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Neem contact op met de auteur van de afbeelding</title>
<link rel="stylesheet" type="text/css" href="<?=$url_css?>contact.css" media="screen" />
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6.2/jquery-1.6.2.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.tela-botanica.org/commun/bootstrap/2.0.2/css/bootstrap.css">
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/validate/1.8.1/jquery.validate.min.js"></script>
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/validate/1.8.1/messages_fr.js"></script>
</head>
<body>
<script type="text/javascript">
//<![CDATA[
var donnees = new Array();
function envoyerCourriel() {
//console.log('Formulaire soumis');
if ($("#form-contact").valid()) {
var destinataireId = $("#fc_destinataire_id").attr('value');
var typeEnvoi = $("#fc_type_envoi").attr('value');
// l'envoi aux non inscrits passe par le service intermédiaire du cel
// qui va récupérer le courriel associé à l'image indiquée
var urlMessage = "https://www.tela-botanica.org/service:cel:celMessage/image/"+destinataireId;
var erreurMsg = "";
console.log($(this));
$.each($("#form-contact").serializeArray(), function (index, champ) {
var cle = champ.name;
cle = cle.replace(/^fc_/, '');
if (cle == 'sujet') {
champ.value += " - Carnet en ligne - Tela Botanica";
}
if (cle == 'message') {
champ.value += "\n--\n"+
"Dit bericht wordt u toegestuurd via de fotowidget van de ‘Carnet en Ligne’ van het Tela Botanica netwerk.\n"+
"http://www.tela-botanica.org/widget:cel:photo";
}
donnees[index] = {'name':cle,'value':champ.value};
});
$.ajax({
type : "POST",
cache : false,
url : urlMessage,
data : donnees,
beforeSend : function() {
$(".msg").remove();
},
success : function(data) {
$("#fc-zone-dialogue").append('<pre class="msg info">'+data.message+'</pre>');
},
error : function(jqXHR, textStatus, errorThrown) {
erreurMsg += "Erreur Ajax :\ntype : "+textStatus+' '+errorThrown+"\n";
reponse = jQuery.parseJSON(jqXHR.responseText);
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "\n";
});
}
},
complete : function(jqXHR, textStatus) {
var debugMsg = '';
if (jqXHR.getResponseHeader("X-DebugJrest-Data") != '') {
debugInfos = jQuery.parseJSON(jqXHR.getResponseHeader("X-DebugJrest-Data"));
if (debugInfos != null) {
$.each(debugInfos, function (cle, valeur) {
debugMsg += valeur + "\n";
});
}
}
if (erreurMsg != '') {
$("#fc-zone-dialogue").append('<p class="msg">'+
'Er is een fout opgetreden bij het versturen van uw bericht.'+'<br />'+
'U kunt de storing melden bij <a href="'+
'mailto:cel@tela-botanica.org'+'?'+
'subject=Disfonctionnement du widget carto'+
"&body="+erreurMsg+"\nDébogage :\n"+debugMsg+
'">cel@tela-botanica.org</a>.'+
'</p>');
}
}
});
}
return false;
}
function initialiserFormulaireContact() {
$("#form-contact").validate({
rules: {
fc_sujet : "required",
fc_message : "required",
fc_utilisateur_courriel : {
required : true,
email : true}
}
});
$("#form-contact").live("submit", function(event) {
event.preventDefault();
envoyerCourriel();
});
$("#fc_annuler").live("click", function() {window.close();});
}
$(document).ready(function() {
initialiserFormulaireContact();
});
//]]>
</script>
<!-- Squelette du formulaire de contact -->
<div id="tpl-form-contact">
<form id="form-contact" method="post" action="">
<div id="fc-zone-dialogue"></div>
<div>
<div><label for="fc_sujet">Onderwerp</label></div>
<div><input id="fc_sujet" name="fc_sujet" value="<?= $donnees['sujet'] ?>"/></div>
<div><label for="fc_message">Bericht</label></div>
<div><textarea id="fc_message" name="fc_message"><?= $donnees['message'] ?></textarea></div>
<div><label for="fc_utilisateur_courriel" title="Gebruik het e-mailadres waarmee u bent aangemeld bij Tela Botanica">Jouw e-mailadres</label></div>
<div><input id="fc_utilisateur_courriel" name="fc_utilisateur_courriel"/></div>
</div>
<p>
<input id="fc_destinataire_id" name="fc_destinataire_id" type="hidden" value="<?= $donnees['id_image'] ?>" />
<input type="hidden" name="fc_type_envoi" id="fc_type_envoi" value="non-inscrit" />
<input id="fc_annuler" type="button" value="Annuleren">
<input id="fc_effacer" type="reset" value="Wissen">
<input id="fc_envoyer" type="submit" value="Verzenden" />
</form>
</div>
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/squelettes/css/popup.css
New file
0,0 → 1,85
@CHARSET "UTF-8";
 
body {
color: black !important;
font-size: 16px !important;
font-weight: bold;
font-family: Arial,verdana,sans-serif;
}
 
hr.nettoyage {
visibility:hidden;
}
 
/*----------------------------------------------------------------------------------------------------------*/
/* Disposition */
#zone-pied {
text-align:center;
}
#eflore_pied_page {
text-align:center;
}
#zone-debug {
background-color:grey;
color:white;
}
 
/*----------------------------------------------------------------------------------------------------------*/
/* Spécifiques popup : ILLUSTRATION */
#info-img .img-cadre {
text-align:center;
}
#info-img img {
display:inline;
vertical-align:middle;
margin:0;
border:0;
border: 1px solid lightgrey;
padding:2px;
}
 
/*----------------------------------------------------------------------------------------------------------*/
/* Spécifiques popup : GALERIE */
#info-img-galerie .conteneur-precedent {
float:left;
width:50px;
position: absolute;
top: 50%;
}
 
#info-img-galerie .conteneur-suivant {
position: absolute;
top: 50%;
right:10px;
width:50px;
float:right;
}
 
#info-img-galerie .conteneur-precedent #precedent, #info-img-galerie .conteneur-suivant #suivant {
position:relative;
top:50%;
font-size:1.3em;
border:none;
}
 
#info-img-galerie .conteneur-suivant #suivant {
float:right;
text-align:right;
}
 
#info-img-galerie .img-cadre {
float:left;
left: 60px;
position: absolute;
height:100%;
}
 
#info-img-galerie #lien-voir-meta {
text-align: center;
}
 
#bloc-infos-img {
position: absolute;
bottom: 10px;
left: 60px;
}
/branches/v3.01-serpe/widget/modules/photo/squelettes/css/photo.css
New file
0,0 → 1,112
@charset "UTF-8";
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Widget */
.cel-photo-contenu{
position:relative;
padding:0 5px;
margin:5px auto;
font-family:Arial,verdana,sans-serif;
background-color:#DDDDDD;
color:black;
}
.cel-photo-contenu h1 {
margin:5px !important;
padding:0 !important;
font-size:16px !important;
color:black !important;
background-color:transparent !important;
background-image:none !important;
text-transform:none !important;
text-align:left !important;
}
.cel-photo-contenu h1 a{
color: #AAAAAA !important
}
.cel-photo-contenu h1 a:hover {
color:#56B80E !important;
border-bottom:1px dotted #56B80E;
}
.cel-photo-contenu h1 .cel-photo-flux{
width:16px;
height:20px;
}
.cel-photo-contenu img {
border:0 !important;
padding:0 !important;
margin:0 !important;
}
.cel-photo-contenu a, .cel-photo-contenu a:active, .cel-photo-contenu a:visited {
border-bottom:1px dotted #666;
color: black;
text-decoration:none;
background-image:none;
}
.cel-photo-contenu a:active {
outline:none;
}
.cel-photo-contenu a:focus {
outline:thin dotted;
}
.cel-photo-contenu a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
.cel-photo-date-generation{
float:right;
font-size:8px;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Général */
.cel-photo-contenu .discretion {
color:grey;
font-family:arial;
font-size:11px;
font-weight:bold;
}
.cel-photo-contenu .nettoyage {
clear:both;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Galerie Photos CEL */
.cel-photo-contenu .cel-photo a{
float:left;
padding:2px;
border:1px solid white;
}
.cel-photo-contenu .cel-photo a:hover{
border:1px dotted #FD8C13;
}
.cel-photo-contenu .cel-photo a img{
float:left;
width:63px;
height:63px;
}
.cel-photo-contenu .cel-photo-extra a img{
height:auto;
}
.cel-photo-contenu .cel-infos {
display:none;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Diaporama */
.cel-legende{
text-align:left;
}
.cel-legende-vei{
float:right;
}
.cel-legende p{
color:black;
font-size:12px;
margin:5px 0;
}
.cel-legende a, .cel-legende a:active, .cel-legende a:visited {
border-bottom:1px dotted gainsboro;
color:#333;
text-decoration:none;
background-image:none;
}
.cel-legende a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/branches/v3.01-serpe/widget/modules/photo/squelettes/css/contact.css
New file
0,0 → 1,17
#tpl-form-contact {
width: 350px;
padding: 15px;
}
 
input, textarea {
max-width: 100%;
width: 100% !important;
}
 
textarea {
height: 185px !important;
}
 
.error {
color: red;
}
/branches/v3.01-serpe/widget/modules/photo/squelettes/photo.tpl.html
New file
0,0 → 1,208
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Photographies publiques du CEL - Tela Botanica</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Tela Botanica" />
<meta name="keywords" content="Tela Botanica, photographie, CEL" />
<meta name="description" content="Widget de présentation des dernières photo publiées sur le Carnet en Ligne de Tela Botanica" />
 
<!-- OpenGraph pour Facebook, Pinterest, Google+ -->
<meta property="og:type" content="website" />
<meta property="og:title" content="Widget photo du CeL" />
<meta property="og:site_name" content="Tela Botanica" />
<meta property="og:description" content="Mini-galerie photo des observations publiques du Carnet en Ligne" />
<?php
if (isset($items[0])) {
$iz = $items[0];
$izUrl = sprintf($iz['url_tpl'], 'CRS');
echo '<meta property="og:image" content="' . $izUrl . '" />';
} else {
echo '<meta property="og:image" content="https://resources.tela-botanica.org/tb/img/256x256/carre_englobant.png" />'
.'<meta property="og:image:type" content="image/png" />'
.'<meta property="og:image:width" content="256" />'
.'<meta property="og:image:height" content="256" />';
}
?>
<meta property="og:locale" content="fr_FR" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="https://resources.tela-botanica.org/tb/img/16x16/favicon.png" />
<link rel="shortcut icon" type="image/x-icon" href="https://resources.tela-botanica.org/tb/img/16x16/favicon.ico" />
<!-- Feuilles de styles -->
<link rel="stylesheet" type="text/css" href="https://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" media="screen" />
<link rel="stylesheet" type="text/css" href="<?=$url_css?>photo.css" media="screen" />
<style type="text/css">
html {
overflow:hidden;
}
body{
overflow:hidden;
padding:0;
margin:0;
width:100%;
height:100%;
background-color:#DDDDDD;
color:black;
}
#cel-photo-contenu<?=$id?>, #cel-galerie-photo<?=$id?>{
width:<?=(($colonne * 69))?>px;
}
#cel-galerie-photo<?=$id?> #cel-photo-extra<?=$id?> img{
width:<?=(($colonne * 69)-6)?>px;
}
</style>
<!-- Javascript : bibliothèques -->
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6/jquery-1.6.min.js"></script>
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.js"></script>
 
<!-- Google Analytics -->
<?php if($prod): ?>
<?php include "analytics.html"; ?>
<?php endif; ?>
</head>
<body>
<!-- WIDGET:CEL:PHOTO - DEBUT -->
<div id="cel-photo-contenu<?=$id?>" class="cel-photo-contenu">
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
<? if (!empty($titre)) : ?>
<?=$titre?>
<? endif ; ?>
<? if($icone_rss) : ?>
<a href="<?=$flux_rss_url?>"
class="cel-photo-flux"
title="Suivre les images"
onclick="window.open(this.href);return false;">
<img src="https://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les images" />
</a>
<? endif; ?>
</h1>
<div id="cel-galerie-photo<?=$id?>">
<?php foreach ($items as $item) : ?>
<div class="cel-photo">
<a href="<?=sprintf($item['url_tpl'], 'XL')?>" class="cel-img" title="<?=$item['titre']?> - Publiée le <?=$item['date']?> - GUID : <?=$item['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($item['url_tpl'], 'CRX2S')?>" alt="<?=$item['titre']?>"/>
</a>
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<strong>
<?php if ($item['eflore_url'] != '#' && $item['eflore_url'] != '') { ?>
<a class="cel-img-titre" href="<?=$item['eflore_url']?>"
onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['infos']['nom_sci']?>
</a> par
<a class="cel-img-contact"
href="?mode=contact&nn=<?= urlencode($item['infos']['nn']) ;?>&nom_sci=<?= urlencode($item['infos']['nom_sci']) ;?>&date=<?= urlencode($item['infos']['date']) ;?>&id_image=<?= $item['guid']; ?>"
title="Cliquez pour contacter l'auteur de la photo">
<?=$item['infos']['auteur']?>
</a>
à <?= $item['infos']['localite'] ?>
le <?=$item['infos']['date']?>
<?php } else { ?>
<?=$item['titre']?>
<?php } ?>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span>
</div>
</div>
<?php endforeach; ?>
<?php if ($extra_actif) : ?>
<div id="cel-photo-extra<?=$id?>" class="cel-photo-extra cel-photo">
<a href="<?=sprintf($extra['url_tpl'], 'XL')?>" class="cel-img" title="<?=$extra['titre']?> - Publiée le <?=$extra['date']?> - GUID : <?=$extra['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($extra['url_tpl'], 'CRS')?>" alt="<?=$extra['titre']?>"/>
</a>
</div>
</div>
<?php endif ?>
<p class="cel-photo-pieds discretion nettoyage">
<span class="cel-photo-source">
Source :
<a href="http://www.tela-botanica.org/page:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
</span>
<span class="cel-photo-date-generation">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></span>
</p>
<script type="text/Javascript">
//<![CDATA[
var utiliseFancybox = "<?= $utilise_fancybox; ?>";
if(utiliseFancybox) {
$('a.cel-img').attr('rel', 'galerie-princ<?=$id?>').fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /GUID : ([0-9]+)$/;
motif.exec(titre);
var guid = RegExp.$1;
var info = $('#cel-info-'+guid).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Image n°' + (currentIndex + 1) + ' sur ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
});
} else {
$('a.cel-img').click(function(event) {
ouvrirFenetrePopup($(this));
event.preventDefault();
});
}
$(document).ready(function() {
$('a.cel-img-contact').live('click', function(event) {
event.preventDefault();
ouvrirFenetreContact($(this));
});
});
function ouvrirFenetrePopup(lienImage) {
var url = "?mode=popup&url_image="+lienImage.attr('href')+'&galerie_id=<?= $galerie_id ?>';
window.open(url, '', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(700)+', height='+(650));
}
function ouvrirFenetreContact(lienImage) {
var url = lienImage.attr("href");
window.open(url, '_blank', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(400)+', height='+(550));
}
//]]>
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:PHOTO - FIN -->
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/squelettes/contact.tpl.html
New file
0,0 → 1,133
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Contacter l'auteur de l'image</title>
<link rel="stylesheet" type="text/css" href="<?=$url_css?>contact.css" media="screen" />
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6.2/jquery-1.6.2.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.tela-botanica.org/commun/bootstrap/2.0.2/css/bootstrap.css">
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/validate/1.8.1/jquery.validate.min.js"></script>
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/validate/1.8.1/messages_fr.js"></script>
</head>
<body>
<script type="text/javascript">
//<![CDATA[
var donnees = new Array();
function envoyerCourriel() {
//console.log('Formulaire soumis');
if ($("#form-contact").valid()) {
var destinataireId = $("#fc_destinataire_id").attr('value');
var typeEnvoi = $("#fc_type_envoi").attr('value');
// l'envoi aux non inscrits passe par le service intermédiaire du cel
// qui va récupérer le courriel associé à l'image indiquée
var urlMessage = "http://api.tela-botanica.org/service:cel:celMessage/image/"+destinataireId;
var erreurMsg = "";
console.log($(this));
$.each($("#form-contact").serializeArray(), function (index, champ) {
var cle = champ.name;
cle = cle.replace(/^fc_/, '');
if (cle == 'sujet') {
champ.value += " - Carnet en ligne - Tela Botanica";
}
if (cle == 'message') {
champ.value += "\n--\n"+
"Ce message vous est envoyé par l'intermédiaire du widget photo "+
"du Carnet en Ligne du réseau Tela Botanica.\n"+
"http://www.tela-botanica.org/widget:cel:photo";
}
donnees[index] = {'name':cle,'value':champ.value};
});
$.ajax({
type : "POST",
cache : false,
url : urlMessage,
data : donnees,
beforeSend : function() {
$(".msg").remove();
},
success : function(data) {
$("#fc-zone-dialogue").append('<pre class="msg info">'+data.message+'</pre>');
},
error : function(jqXHR, textStatus, errorThrown) {
erreurMsg += "Erreur Ajax :\ntype : "+textStatus+' '+errorThrown+"\n";
reponse = jQuery.parseJSON(jqXHR.responseText);
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "\n";
});
}
},
complete : function(jqXHR, textStatus) {
var debugMsg = '';
if (jqXHR.getResponseHeader("X-DebugJrest-Data") != '') {
debugInfos = jQuery.parseJSON(jqXHR.getResponseHeader("X-DebugJrest-Data"));
if (debugInfos != null) {
$.each(debugInfos, function (cle, valeur) {
debugMsg += valeur + "\n";
});
}
}
if (erreurMsg != '') {
$("#fc-zone-dialogue").append('<p class="msg">'+
'Une erreur est survenue lors de la transmission de votre message.'+'<br />'+
'Vous pouvez signaler le disfonctionnement à <a href="'+
'mailto:cel-remarques@tela-botanica.org'+'?'+
'subject=Disfonctionnement du widget carto'+
"&body="+erreurMsg+"\nDébogage :\n"+debugMsg+
'">cel-remarques@tela-botanica.org</a>.'+
'</p>');
}
}
});
}
return false;
}
function initialiserFormulaireContact() {
$("#form-contact").validate({
rules: {
fc_sujet : "required",
fc_message : "required",
fc_utilisateur_courriel : {
required : true,
email : true}
}
});
$("#form-contact").live("submit", function(event) {
event.preventDefault();
envoyerCourriel();
});
$("#fc_annuler").live("click", function() {window.close();});
}
$(document).ready(function() {
initialiserFormulaireContact();
});
//]]>
</script>
<!-- Squelette du formulaire de contact -->
<div id="tpl-form-contact">
<form id="form-contact" method="post" action="">
<div id="fc-zone-dialogue"></div>
<div>
<div><label for="fc_sujet">Sujet</label></div>
<div><input id="fc_sujet" name="fc_sujet" value="<?= $donnees['sujet'] ?>"/></div>
<div><label for="fc_message">Message</label></div>
<div><textarea id="fc_message" name="fc_message"><?= $donnees['message'] ?></textarea></div>
<div><label for="fc_utilisateur_courriel" title="Utilisez le courriel avec lequel vous êtes inscrit à Tela Botanica">Votre courriel</label></div>
<div><input id="fc_utilisateur_courriel" name="fc_utilisateur_courriel"/></div>
</div>
<p>
<input id="fc_destinataire_id" name="fc_destinataire_id" type="hidden" value="<?= $donnees['id_image'] ?>" />
<input type="hidden" name="fc_type_envoi" id="fc_type_envoi" value="non-inscrit" />
<input id="fc_annuler" type="button" value="Annuler">
<input id="fc_effacer" type="reset" value="Effacer">
<input id="fc_envoyer" type="submit" value="Envoyer" />
</p>
</form>
</div>
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/squelettes/photo_ajax.tpl.html
New file
0,0 → 1,145
<!-- WIDGET:CEL:PHOTO - DEBUT -->
<div id="cel-photo-contenu<?=$id?>" class="cel-photo-contenu">
<!-- Feuilles de styles -->
<style type="text/css">
#cel-photo-contenu<?=$id?>, #cel-galerie-photo<?=$id?>{
width:<?=(($colonne * 69))?>px;
}
#cel-galerie-photo<?=$id?> #cel-photo-extra<?=$id?> img{
width:<?=(($colonne * 69)-6)?>px;
}
</style>
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
<? if (!empty($titre)) : ?>
<?=$titre?>
<? endif ; ?>
<? if($icone_rss) : ?>
<a href="<?=$flux_rss_url?>"
class="cel-photo-flux"
title="Suivre les images"
onclick="window.open(this.href);return false;">
<img src="https://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les images" />
</a>
<? endif; ?>
</h1>
<div id="cel-galerie-photo<?=$id?>">
<?php foreach ($items as $item) : ?>
<div class="cel-photo">
<a href="<?=sprintf($item['url_tpl'], 'XL')?>" class="cel-img" title="<?=$item['titre']?> - Publiée le <?=$item['date']?> - GUID : <?=$item['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($item['url_tpl'], 'CRX2S')?>" alt="<?=$item['titre']?>"/>
</a>
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<strong>
<?php if ($item['eflore_url'] != '#' && $item['eflore_url'] != '') { ?>
<a class="cel-img-titre" href="<?=$item['eflore_url']?>"
onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['infos']['nom_sci']?>
</a> par
<a class="cel-img-contact"
href="<?= $url_widget ?>?mode=contact&nn=<?= urlencode($item['infos']['nn']) ;?>&nom_sci=<?= urlencode($item['infos']['nom_sci']) ;?>&date=<?= urlencode($item['infos']['date']) ;?>&id_image=<?= $item['guid']; ?>"
title="Cliquez pour contacter l'auteur de la photo">
<?=$item['infos']['auteur']?>
</a>
<?php if (! empty($item['infos']['localite'])): ?>
à <?= $item['infos']['localite'] ?>
<?php endif; ?>
le <?=$item['infos']['date']?>
<?php } else { ?>
<?=$item['titre']?>
<?php } ?>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span>
</div>
</div>
<?php endforeach; ?>
<?php if ($extra_actif) : ?>
<div id="cel-photo-extra<?=$id?>" class="cel-photo cel-photo-extra">
<a href="<?=sprintf($extra['url_tpl'], 'XL')?>" class="cel-img" title="<?=$extra['titre']?> - Publiée le <?=$extra['date']?> - GUID : <?=$extra['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($extra['url_tpl'], 'CRS')?>" alt="<?=$extra['titre']?>"/>
</a>
</div>
</div>
<?php endif ?>
<p class="cel-photo-pieds discretion nettoyage">
<span class="cel-photo-source">
Source :
<a href="http://www.tela-botanica.org/page:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
</span>
<span class="cel-photo-date-generation">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></span>
</p>
<script type="text/Javascript">
//<![CDATA[
var utiliseFancybox = "<?= $utilise_fancybox; ?>";
if(utiliseFancybox) {
$(document).ready(function() {
$('a.cel-img').attr('rel', 'galerie-princ<?=$id?>').fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /GUID : ([0-9]+)$/;
motif.exec(titre);
var guid = RegExp.$1;
var info = $('#cel-info-'+guid).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Image n°' + (currentIndex + 1) + ' sur ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
});
});
} else {
$('a.cel-img').click(function(event) {
ouvrirFenetrePopup($(this));
event.preventDefault();
});
}
$(document).ready(function() {
$('a.cel-img-contact').live('click', function(event) {
event.preventDefault();
ouvrirFenetreContact($(this));
});
});
function ouvrirFenetrePopup(lienImage) {
var url = "?mode=popup&url_image="+lienImage.attr('href')+'&galerie_id=<?= $galerie_id ?>';
window.open(url, '', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(700)+', height='+(650));
}
function ouvrirFenetreContact(lienImage) {
var url = lienImage.attr("href");
window.open(url, '_blank', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(400)+', height='+(550));
}
//]]>
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:PHOTO - FIN -->
/branches/v3.01-serpe/widget/modules/photo/squelettes/popup_nl.tpl.html
New file
0,0 → 1,145
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="<?=$url_css?>popup.css" media="screen" />
<script type="text/javascript" src="https://www.tela-botanica.org/commun/jquery/1.6/jquery-1.6.min.js"></script>
</head>
<body>
<script type="text/javascript">
//<![CDATA[
var urls = [<?= '"'.implode($urls, '","').'"'; ?>];
var infos_images = <?= json_encode($infos_images); ?>;
var indexImage = 0;
var urlImage = "<?= $url_image; ?>";
var tailleMax = 580;
function redimensionnerImage(objet) {
objet.removeAttr("width");
objet.removeAttr("height");
var hauteurImage = objet.height();
var largeurImage = objet.width();
var rapport = 1;
if(hauteurImage > largeurImage && hauteurImage > tailleMax) {
rapport = largeurImage/hauteurImage;
hauteurImage = 580;
largeurImage = hauteurImage*rapport;
$('#illustration').attr("height", hauteurImage);
$('#illustration').attr("width", largeurImage);
}
hauteurFleches = ((hauteurImage+90)/2);
$('#info-img-galerie .conteneur-precedent').attr("top", hauteurFleches);
$('#info-img-galerie .conteneur-suivant').attr("top", hauteurFleches);
window.resizeTo(largeurImage+120,hauteurImage+120);
}
function imageSuivante() {
indexImage++;
if(indexImage >= urls.length) {
indexImage = 0;
}
afficherTitreImage();
$('#illustration').attr('src', urls[indexImage]);
}
function imagePrecedente() {
indexImage--;
if(indexImage <= 0) {
indexImage = urls.length - 1;
}
afficherTitreImage();
$('#illustration').attr('src', urls[indexImage]);
}
function afficherTitreImage() {
item = infos_images[urls[indexImage]];
var titre = item['titre'];
var infos = decouperTitre(titre);
var lienContact = '<?= $url_widget ?>?mode=contact&nn='+infos.nn+
'&nom_sci='+infos.nom_sci+
'&date='+infos.date+
'&id_image='+item['guid'];
titre = '<a href="'+item['lien']+'">'+infos.nom_sci+'</a> '+
' door <a class="lien_contact" href="'+lienContact+'">'+infos.auteur+'</a> '+
' op '+infos.date+' ';
$('#bloc-infos-img').html(titre);
}
function decouperTitre(titre) {
var tab_titre = titre.split('[nn');
var nom_sci = tab_titre[0];
var tab_titre_suite = tab_titre[1].split(' door ');
var nn = '[nn'+tab_titre_suite[0];
var tab_titre_fin = tab_titre_suite[1].split(' op ');
var utilisateur = tab_titre_fin[0];
var date = tab_titre_fin[1];
var titre_decoupe = {'nom_sci' : nom_sci, 'nn' : nn, 'date' : date, 'auteur' : utilisateur};
return titre_decoupe;
}
function ouvrirFenetreContact(lienImage) {
var url = lienImage.attr("href");
window.open(url, '_blank', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no, width='+(400)+', height='+(550));
}
$(document).ready(function() {
$('#precedent').click(function() {
imagePrecedente();
});
$('#suivant').click(function() {
imageSuivante();
});
if(urlImage != "null" && urlImage != "") {
indexImage = Array.indexOf(urls, urlImage);
$('#illustration').attr('src', urls[indexImage]);
afficherTitreImage();
}
$('#illustration').load(function() {
redimensionnerImage($(this));
});
$("body").keydown(function(e) {
if(e.keyCode == 37) { // gauche
imagePrecedente();
}
else if(e.keyCode == 39) { // droite
imageSuivante();
}
});
$('.lien_contact').live('click', function(event) {
event.preventDefault();
ouvrirFenetreContact($(this));
});
});
//]]>
</script>
 
<div id="info-img-galerie">
<div class="conteneur-precedent">
<a id="precedent" href="#" title="Klik hier of maak gebruik van het pijltje naar links om de vorige afbeelding weer te geven">
<img style="border:none" src="https://www.tela-botanica.org/sites/commun/generique/images/flecheGauche.jpg" alt="&lt;" />
</a>
</div>
<div class="img-cadre">
<img id="illustration" src="<?=$urls[0]?>" alt="" /><br />
</div>
<div class="conteneur-suivant">
<a id="suivant" href="#" title="Klik hier of maak gebruik van het pijltje naar rechts om de volgende afbeelding weer te geven">
<img style="border:none" src="https://www.tela-botanica.org/sites/commun/generique/images/flecheDroite.jpg" alt="&gt;" />
</a>
</div>
<hr class="nettoyage" />
<div id="bloc-infos-img"></div>
</div>
</body>
</html>
/branches/v3.01-serpe/widget/modules/photo/Photo.php
New file
0,0 → 1,264
<?php
// declare(encoding='UTF-8');
/**
* Service affichant les dernières photo publiques du CEL ouvrable sous forme de diaporama.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
*
* Cas d'utilisation et documentation :
* @link http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=AideCELWidgetPhoto
*
* Paramètres :
* ===> extra = booléen (1 ou 0) [par défaut : 1]
* Affiche / Cache la vignette en taille plus importante au bas du widget.
* ===> vignette = [0-9]+,[0-9]+ [par défaut : 4,3]
* Indique le nombre de vignette par ligne et le nombre de ligne.
*
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @version $Id$
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
*/
class Photo extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const SERVICE_DEFAUT = 'photo';
private $flux_rss_url = null;
private $eflore_url_tpl = null;
 
// Suffixe de template pour la langue (vide par défaut, correspond à "fr" au français)
private $suffixeLangue = '';
 
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
unset($this->parametres['callback']);
extract($this->parametres);
 
if (!isset($mode)) {
$mode = self::SERVICE_DEFAUT;
}
$this->eflore_url_tpl = $this->config['photo']['efloreUrlTpl'];
$this->flux_rss_url = $this->config['photo']['fluxRssUrl'];
$cache_activation = $this->config['photo.cache']['activation'];
$cache_stockage = $this->config['photo.cache']['stockageDossier'];
$ddv = $this->config['photo.cache']['dureeDeVie'];
$cache = new Cache($cache_stockage, $ddv, $cache_activation);
$id_cache = 'photo-'.hash('adler32', print_r($this->parametres, true));
if (! $contenu = $cache->charger($id_cache)) {
$methode = $this->traiterNomMethodeExecuter($mode);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
 
// Suffixe de template pour la langue - fr par défaut @TODO configurer ça un jour
if (isset($this->parametres['lang']) && $this->parametres['lang'] != "fr") {
$this->suffixeLangue = "_" . $this->parametres['lang'];
}
 
$contenu = '';
if (is_null($retour)) {
$this->messages[] = 'Aucune image';
} else {
if (isset($retour['donnees'])) {
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette']. $this->suffixeLangue . '.tpl.html';
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
$cache->sauver($id_cache, $contenu);
} else {
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
}
}
}
if (isset($_GET['callback'])) {
$this->envoyerJsonp(array('contenu' => $contenu));
} else {
$this->envoyer($contenu);
}
}
private function executerAjax() {
$widget = $this->executerPhoto();
$widget['squelette'] = 'photo_ajax';
return $widget;
}
private function executerPopup() {
session_start();
$galerie_id = $_GET['galerie_id'];
$widget['donnees']['url_image'] = $_GET['url_image'];
$widget['donnees']['infos_images'] = $_SESSION[$galerie_id]['infos_images'];
$widget['donnees']['urls'] = $_SESSION[$galerie_id]['urls'];
$widget['donnees']['url_widget'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'photo');
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/js/');
$widget['squelette'] = 'popup' . $this->suffixeLangue;
return $widget;
}
private function executerContact() {
session_start();
$widget['donnees']['id_image'] = $_GET['id_image'];
$widget['donnees']['nom_sci'] = $_GET['nom_sci'];
$widget['donnees']['nn'] = $_GET['nn'];
$widget['donnees']['date'] = $_GET['date'];
if (isset($_GET['lang']) && 'nl' === $_GET['lang']) {
$widget['donnees']['sujet'] = "Afbeelding #".$_GET['id_image']." op ".$_GET['nom_sci'];
$widget['donnees']['message'] = "\n\n\n\n\n\n\n\n--\nBetreft de foto \"".$_GET['nom_sci'].'" van "'.$_GET['date'];
} else {
$widget['donnees']['sujet'] = "Image #".$_GET['id_image']." de ".$_GET['nom_sci'];
$widget['donnees']['message'] = "\n\n\n\n\n\n\n\n--\nConcerne l'image de \"".$_GET['nom_sci'].'" du "'.$_GET['date'];
}
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/js/');
$widget['squelette'] = 'contact';
return $widget;
}
private function decouperTitre($titre) {
if ('nl' === $this->suffixeLangue) {
$dic = array(' door ', ' op ');
} else {
$dic = array(' par ', ' le ');
}
 
$tab_titre = explode('[nn', $titre);
if (isset($tab_titre[1])) {
$nom_sci = $tab_titre[0];
$tab_titre_suite = explode($dic[0], $tab_titre[1]);
} else {
$nom_sci = "";
$tab_titre_suite = explode($dic[0], $tab_titre[0]);
}
$nn = '[nn'.$tab_titre_suite[0];
$tab_titre_resuite = explode($dic[1], $tab_titre_suite[1]);
$utilisateur = $tab_titre_resuite[0];
$tab_titre_fin = explode(' - ', $tab_titre_resuite[1]);
$date = $tab_titre_fin[0];
$localite = (empty($tab_titre_fin[1]) ? '' : $tab_titre_fin[1]);
$titre_decoupe = array('nom_sci' => $nom_sci, 'nn' => $nn, 'date' => $date, 'auteur' => $utilisateur, 'localite' => $localite);
return $titre_decoupe;
}
private function executerPhoto() {
session_start();
$_SESSION['urls'] = array();
$widget = null;
extract($this->parametres);
$extra = (isset($extra) && $extra == 0) ? false : ($this->config['photo']['extraActif'] ? true : false);
$vignette = (isset($vignette) && preg_match('/^[0-9]+,[0-9]+$/', $vignette)) ? $vignette : '4,3';
$id = '-'.(isset($id) ? $id : '1');
$titre = isset($titre) ? htmlentities(rawurldecode($titre)) : '';
$icone_rss = (isset($_GET['rss']) && $_GET['rss'] != 1) ? false : true;
$utilise_fancybox = (isset($_GET['mode_zoom']) && $_GET['mode_zoom'] != 'fancybox') ? false : true;
list($colonne, $ligne) = explode(',', $vignette);
$this->flux_rss_url .= $this->traiterParametres();
 
$xml = @file_get_contents($this->flux_rss_url);
//var_dump($xml);
if ($xml !== false) {
if ($xml) {
try {
$flux = new XmlFeedParser($xml);
$widget['donnees']['id'] = $id;
$widget['donnees']['titre'] = $titre;
$widget['donnees']['flux_rss_url'] = $this->flux_rss_url;
$widget['donnees']['url_widget'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'photo');
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/js/');
$widget['donnees']['colonne'] = $colonne;
$widget['donnees']['extra_actif'] = $extra;
$widget['donnees']['icone_rss'] = $icone_rss;
$widget['donnees']['utilise_fancybox'] = $utilise_fancybox;
$widget['donnees']['prod'] = ($this->config['parametres']['modeServeur'] == "prod");
 
$max_photo = $colonne * $ligne;
$num = 0;
$galerie_id = md5(http_build_query($_GET));
$widget['donnees']['galerie_id'] = $galerie_id;
foreach ($flux as $entree) {
if ($num == $max_photo) {
break;
}
$item = array();
// Formatage date
$date = $entree->updated ? $entree->updated : null;
$date = $entree->pubDate ? $entree->pubDate : $date;
$item['date'] = strftime('%A %d %B %Y', $date);
$item['lien'] = $entree->link;
$item['url_tpl'] = preg_replace('/(XS|[SML]|X(?:[23]|)L|CR(?:|X2)S|C(?:|X)S)\.jpg$/', '%s.jpg', $entree->guid);
// Formatage titre
$item['titre'] = str_replace('"', "", $entree->title);
$item['infos'] = $this->decouperTitre($item['titre']);
$item['nn'] = '';
$item['eflore_url'] = '#';
if (preg_match('/\[nn([0-9]+)\]/', $entree->title, $match)) {
$item['nn'] = $match[1];
$item['eflore_url'] = $item['lien'] ;
}
// Récupération du GUID - aaaaah c'est cracra si on change la config yatoukipett !! Satan is in this code !!!
if (preg_match($this->config['photo']['motif_guid'], $entree->guid, $match)) {
$item['guid'] = (int) $match[1];
} else {
$item['guid'] = $entree->guid;
}
// Ajout aux items et si première photo à extra
if ($num == 0) {
$widget['donnees']['extra'] = $item;
}
$widget['donnees']['items'][$num++] = $item;
//TODO: voir si l'on ne peut pas faire mieux
$url_galerie_popup = sprintf($item['url_tpl'],'XL');
$_SESSION[$galerie_id]['urls'][] = $url_galerie_popup;
$_SESSION[$galerie_id]['infos_images'][$url_galerie_popup] = array('titre' => $item['titre'],
'date' => $item['titre'],
'guid' => $item['guid'],
'lien' => $item['lien']
);
}
$widget['squelette'] = 'photo';
} catch (XmlFeedParserException $e) {
trigger_error('Flux invalide : '.$e->getMessage(), E_USER_WARNING);
}
} else {
// si on arrive ici c'est qu'il n'y a aucune image correspondant
// à la requête, mais il n'y a rien d'invalide là-dedans
//$this->messages[] = "Fichier xml invalide.";
}
} else {
$this->messages[] = "L'URI suivante est invalide : $this->flux_rss_url.\n".
"Veuillez vérifier les paramêtres indiqués et la présence d'images associées.";
}
return $widget;
}
private function traiterParametres() {
$parametres_flux = '?';
$criteres = array('utilisateur', 'commune', 'dept', 'taxon', 'commentaire', 'date', 'tag', 'motcle', 'projet', 'num_taxon', 'num_nom', 'referentiel', 'groupe_zones_geo');
foreach($this->parametres as $nom_critere => $valeur_critere) {
if (in_array($nom_critere, $criteres)) {
$valeur_critere = str_replace(' ', '%20', $valeur_critere);
$parametres_flux .= $nom_critere.'='.$valeur_critere.'&';
}
}
if ($parametres_flux == '?') {
$parametres_flux = '';
} else {
$parametres_flux = rtrim($parametres_flux, '&');
}
return $parametres_flux;
}
}
?>
/branches/v3.01-serpe/widget/modules/photo/config.defaut.ini
New file
0,0 → 1,21
[photo]
; Chemin pour l'autoload à ajouter
autoload = "bibliotheque/;bibliotheque/xml_feed_parser/1.0.4/;bibliotheque/xml_feed_parser/1.0.4/parsers/"
; URL ou chemin du flux RSS contenant les liens vers les photos - ne pas oublier de changer motif_guid en même temps!
fluxRssUrl = "https://api.tela-botanica.org/service:cel:CelSyndicationImage/multicriteres/atom/M"
; Expression régulière pour récupérer le numéro de l'image à partir de l'URL renvoyée par le flux Atom
motif_guid = "/appli:cel-img:([0-9]+)[^.]+\.jpg$/"
; Squelette d'url pour accéder à la fiche eFlore
efloreUrlTpl = "https://www.tela-botanica.org/bdtfx-nn-%s"
; Nombre de vignette à afficher : nombre de vignettes par ligne et nombre de lignes séparés par une vigule (ex. : 4,3).
vignette = 4,3
; Afficher/Cacher l'affichage en grand de la dernière image ajoutée
extraActif = true
 
[photo.cache]
; Active/Désactive le cache
activation = true
; Dossier où stocker les fichiers de cache du widget
stockageDossier = "/tmp"
; Durée de vie du fichier de cache
dureeDeVie = 86400