diff options
| -rw-r--r-- | .gitattributes | 4 | ||||
| -rw-r--r-- | framework/Web/Services/IFeedContentProvider.php | 7 | ||||
| -rw-r--r-- | framework/Xml/TFeedDocument.php | 93 | ||||
| -rw-r--r-- | framework/Xml/TRssFeedDocument.php | 952 | ||||
| -rw-r--r-- | tests/unit/Xml/TRssFeedDocumentTest.php | 158 | 
5 files changed, 1214 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes index ea016ff1..b2a8f8f0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1569,6 +1569,7 @@ framework/Web/Javascripts/ratings/stars1.png -text  framework/Web/Javascripts/rico/colors.js -text  framework/Web/Javascripts/rico/extension.js -text  framework/Web/Javascripts/rico/rico.js -text +framework/Web/Services/IFeedContentProvider.php -text  framework/Web/Services/TFeedService.php -text  framework/Web/Services/TPageService.php -text  framework/Web/TAssetManager.php -text @@ -1679,6 +1680,8 @@ framework/Web/UI/WebControls/TWebControl.php -text  framework/Web/UI/WebControls/TWebControlAdapter.php -text  framework/Web/UI/WebControls/TWizard.php -text  framework/Web/UI/WebControls/TXmlTransform.php -text +framework/Xml/TFeedDocument.php -text +framework/Xml/TRssFeedDocument.php -text  framework/Xml/TXmlDocument.php -text  framework/interfaces.php -text  framework/prado.php -text @@ -2144,6 +2147,7 @@ tests/unit/Web/UI/WebControls/TRequiredFieldValidatorTest.php -text  tests/unit/Web/UI/WebControls/TXmlTransformTest.php -text  tests/unit/Web/UI/WebControls/data/hello.xml -text  tests/unit/Web/UI/WebControls/data/hello.xsl -text +tests/unit/Xml/TRssFeedDocumentTest.php -text  tests/unit/Xml/TXmlDocumentTest.php -text  tests/unit/Xml/TXmlElementListTest.php -text  tests/unit/Xml/TXmlElementTest.php -text diff --git a/framework/Web/Services/IFeedContentProvider.php b/framework/Web/Services/IFeedContentProvider.php new file mode 100644 index 00000000..0ba972f6 --- /dev/null +++ b/framework/Web/Services/IFeedContentProvider.php @@ -0,0 +1,7 @@ +<?php + +interface IFeedContentProvider { +  public function getFeedContent(); +} + +?>
\ No newline at end of file diff --git a/framework/Xml/TFeedDocument.php b/framework/Xml/TFeedDocument.php new file mode 100644 index 00000000..28f917cb --- /dev/null +++ b/framework/Xml/TFeedDocument.php @@ -0,0 +1,93 @@ +<?php +/** + * TFeedDocument class file + *  + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @link http://www.pradosoft.com + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Xml + */ + +Prado::using('System.Web.Services.IFeedContentProvider'); + +/** + * TFeedDocument class + *  + * TFeedDocument represents a Web feed used for Web syndication. + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +abstract class TFeedDocument extends DOMDocument implements IFeedContentProvider { +   +  /** +   *  +   */ +  public function __construct($encoding = null) { +    parent::__construct('1.0', $encoding); +  } + +  /** +   * +   */ +  public function getEncoding() { +    return $this->encoding; +  } + +  /** +   * +   */ +  public function setEncoding($encoding) { +    $this->encoding = $encoding; +  } +} + +/** + * TFeedElement class + *  + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +abstract class TFeedElement extends TXmlElement { +   +  /** +   * +   */ +  /*  public function getValue($name) { +    $element = $this->getElementByTagName($name); +    if($element instanceof TXmlElement) { +      return $element->getValue(); +    } +    throw new Exception("Element '$name' not found"); +  }*/ + +  /** +   * +   */ +  /*public function setValue($name, $value) { + +    if(($element = $this->getElementByTagName($name)) !== null) { +      $element->setValue($value); +    } else { +      $element = new TXmlElement($name); +      $element->setValue($value); +      $this->getElements()->add($element); +    } +  }*/ +} + +/** + * TFeedItem class + *  + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +abstract class TFeedItem extends TFeedElement { +    +} + +?>
\ No newline at end of file diff --git a/framework/Xml/TRssFeedDocument.php b/framework/Xml/TRssFeedDocument.php new file mode 100644 index 00000000..e4c441ab --- /dev/null +++ b/framework/Xml/TRssFeedDocument.php @@ -0,0 +1,952 @@ +<?php +/** + * TRssFeedDocument, TRssFeedItem, TRssFeedTextInput, TRssFeedCloud class file + *  + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @link http://www.pradosoft.com + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Xml + */ + +Prado::using('System.Xml.TFeedDocument'); + +/** + * TRssFeedDocument class + *  + * TRssFeedDocument represents an RSS feed. RSS is a family of web feed formats, specified in XML and  + * used for Web syndication. RSS is used by (among other things) news websites, weblogs and  + * podcasting. + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +class TRssFeedDocument extends TFeedDocument { +   +  private $_rss; // reference to rss node +  private $_channel; // reference to channel node + +  /** +   * Constructor +   */ +  public function __construct($encoding = null) { +    parent::__construct($encoding); + +    $this->formatOutput = true; + +    $this->_rss = $this->createElement('rss'); +    $this->_rss->setAttribute('version', '0.91'); +    $this->appendChild($this->_rss); + +    $this->_channel = $this->createElement('channel'); +    $this->_rss->appendChild($this->_channel); +  } + +  public function init() { +     +  } + +  /** +   * @return RSS version +   */ +  public function getVersion() { +    return $this->_rss->getAttribute('version'); +  } + +  /** +   * @param string $version RSS version +   */ +  public function setVersion($version) { +    if($version == '0.91' or $version == '0.92' or $version == '2.0') { +      $this->_rss->setAttribute('version', $version); +    } else { +      throw new TInvalidDataTypeException('rssfeed_version_invalid', $version); +    } +  } + +  /** +   * @return string The name of the channel. +   */ +  public function getTitle() { +    return $this->get('title'); +  } + +  /** +   * The name of the channel. It's how people refer to your service. If you have an HTML  +   * website that contains the same information as your RSS file, the title of your channel  +   * should be the same as the title of your website. +   * +   * @param string $title The name of the channel. +   */ +  public function setTitle($title) { +    $this->set('title', $title); +  } + +  /** +   * @return string The URL to the HTML website corresponding to the channel. +   */ +  public function getLink() { +    return $this->get('link'); +  } + +  /** +   * The URL to the HTML website corresponding to the channel. +   * +   * @param string $link The URL to the HTML website corresponding to the channel. +   */ +  public function setLink($link) { +    $this->set('link', $link); +  } + +  /** +   * @return string Phrase or sentence describing the channel. +   */ +  public function getDescription() { +    return $this->get('description'); +  } + +  /** +   * @param string $description Phrase or sentence describing the channel. +   */ +  public function setDescription($description) { +    $this->set('description', $description); +  } + +  /** +   * @return string The language the channel is written in. +   */ +  public function getLanguage() { +    return $this->get('language'); +  } + +  /** +   * The language the channel is written in. This allows aggregators to group all Italian  +   * language sites, for example, on a single page. A list of allowable values for this  +   * element, as provided by Netscape, is {@link http://www.rssboard.org/rss-language-codes here}.  +   * You may also use {@link http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes values defined}  +   * by the W3C. +   */ +  public function setLanguage($language) { +    $this->set('language', $language); +  } + +  /** +   * @return string Copyright notice for content in the channel. +   */ +  public function getCopyright() { +    return $this->get('copyright'); +  } +   +  /** +   * @param string Copyright notice for content in the channel. +   */ +  public function setCopyright($copyright) { +    $this->set('copyright', $copyright); +  } + +  /** +   * @return string Email address for person responsible for editorial content. +   */ +  public function getManagingEditor() { +    return $this->get('managingEditor'); +  } +   +  /** +   * @param string Email address for person responsible for editorial content. +   */ +  public function setManagingEditor($managingEditor) { +    $this->set('managingEditor', $managingEditor); +  } + +  /** +   * @return string Email address for person responsible for technical issues relating to channel. +   */ +  public function getWebMaster() { +    return $this->get('webMaster'); +  } +   +  /** +   * @param string Email address for person responsible for technical issues relating to channel. +   */ +  public function setWebMaster($webMaster) { +    $this->set('webMaster', $webMaster); +  } + +  /** +   * @return string The {@link http://www.w3.org/PICS/ PICS} rating for the channel. +   */ +  public function getRating() { +    return $this->get('rating'); +  } +   +  /** +   * @param string The {@link http://www.w3.org/PICS/ PICS} rating for the channel. +   */ +  public function setRating($rating) { +    $this->set('rating', $rating); +  } + +  /** +   * @return string Publication date +   */ +  public function getPublicationDate() { +    return $this->get('pubDate'); +  } + +  /** +   * The publication date for the content in the channel. For example, the New York Times  +   * publishes on a daily basis, the publication date flips once every 24 hours. That's when  +   * the pubDate of the channel changes. All date-times in RSS conform to the Date and Time  +   * Specification of {@link http://asg.web.cmu.edu/rfc/rfc822.html RFC 822}, with the exception  +   * that the year may be expressed with two characters or four characters (four preferred). +   * +   * @param string $pubDate Publication date +   */ +  public function setPublicationDate($pubDate) { +    $this->set('pubDate', $pubDate); +  } + +  /** +   * @return The last time the channel was modified. +   */ +  public function getLastBuildDate() { +    return $this->get('lastBuildDate'); +  } + +  /** +   * @param string $date The last time the channel was modified (RFC 822). +   */ +  public function setLastBuildDate($date) { +    return $this->set('lastBuildDate', $date); +  } + +  /** +   * @return An URL that references a description of the channel. +   */ +  public function getDocumentation() { +    return $this->get('docs'); +  } +   +  /** +   * A URL that points to the documentation for the format used in the RSS file. It's probably  +   * a pointer to this page. It's for people who might stumble across an RSS file on a Web  +   * server 25 years from now and wonder what it is. +   *  +   * @param string $documentation An URL that references a description of the channel. +   */ +  public function setDocumentation($documentation) { +    $this->set('docs', $documentation); +  } + +  /** +   * @return array The days of the week, spelled out in English. +   */ +  public function getSkipDays() { +    $skipDays = $this->_channel->getElementsByTagName('skipDays')->item(0); +    $return = array(); +    if($skipDays instanceof DOMElement) { +      $days = $skipDays->getElementsByTagName('day'); +      foreach($days as $day) { +        $return[] = $day->nodeValue; +      } +    } +    return $return; +  } + +  /** +   * @param array $days The days of the week, spelled out in English. +   */ +  public function setSkipDays($days) { + +    $skipDays = $this->createElement('skipDays'); +    foreach($days as $day) { // Append day +      $day = $this->createElement('day', $day); +      $skipDays->appendChild($day); +    } +     +    // Add skipDays +    $node = $this->_channel->getElementsByTagName('skipDays')->item(0); +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($skipDays, $node); +    } else { +      $this->_channel->appendChild($skipDays); +    } +  } + +  /** +   * @return array +   */ +  public function getSkipHours() { +    $skipHours = $this->_channel->getElementsByTagName('skipHours')->item(0); +    $return = array(); +    if($skipHours instanceof DOMElement) { +      $hours = $skipHours->getElementsByTagName('hour'); +      foreach($hours as $hour) { +        $return[] = (int)$hour->nodeValue; +      } +    } +    return $return;     +  } + +  /** +   * A list of hour's indicating the hours in the day, GMT, when the channel is unlikely to  +   * be updated. If not set, the channel is assumed to be updated hourly. +   * +   * @param array $hours +   */ +  public function setSkipHours($hours) { +     +    $skipHours = $this->createElement('skipHours'); +    foreach($hours as $hour) { // Append hour +      $hour = $this->createElement('hour', $hour); +      $skipHours->appendChild($hour); +    } +     +    // Add skipHours +    $node = $this->_channel->getElementsByTagName('skipHours')->item(0); +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($skipHours, $node); +    } else { +      $this->_channel->appendChild($skipHours); +    }     +  } + +  /** +   * +   * +   * @param TRssFeedItem $item  +   */ +  public function addItem(TRssFeedItem $item) { + +    //if($this->_version == '0.91' and count($this->getItems()) <= 15) { + +      $fragment = $this->createDocumentFragment(); +      if($fragment->appendXML($item->toString())) { +	$this->_channel->appendChild($fragment); +      } else { +	// TODO +      } +    /*} else { +      throw new TInvalidOperationException(''); +    }*/ +  } + +  /** +   * +   * +   * @param TRssFeedImage $image The feed accompanying icon. +   */ +  public function setImage(TRssFeedImage $image) { +    $fragment = $this->createDocumentFragment(); +    $fragment->appendXML($image->toString()); +    $node = $this->_channel->getElementsByTagName($name)->item(0); +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($fragment, $node); +    } else { +      $this->_channel->appendChild($fragment); +    } +  } + +  /** +   * +   * +   * @param TRssFeedTextInput $textInput A small text box and a Submit button to associate with a CGI application. +   */ +  public function setTextInput(TRssFeedTextInput $textInput) { +    $fragment = $this->createDocumentFragment(); +    $fragment->appendXML($textInput->toString()); +    $node = $this->_channel->getElementsByTagName($name)->item(0); +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($fragment, $node); +    } else { +      $this->_channel->appendChild($fragment); +    } +  } + +  /** +   * +   * @param TRssFeedCloud $cloud +   * @since RSS 0.92 +   */ +  public function setCloud(TRssFeedCloud $cloud) { +    // TODO: RSS >= 0.92 +    $fragment = $this->createDocumentFragment(); +    $fragment->appendXML($cloud->toString()); +    $node = $this->_channel->getElementsByTagName($name)->item(0); +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($fragment, $node); +    } else { +      $this->_channel->appendChild($fragment); +    } + +  } +   +  /** +   * @return array A list of TRssItem's +   */ +  public function getItems() { +    $return = array(); +    $elements = $this->getElementsByTagName('item'); +     +    $items = new TRssFeedItemList(); +     +    /*foreach($items as $item) { +      $return[] =  +    }*/ +    return $return; +  } + +  /** +   * @return string Category path seperated with forward slash. +   */ +  public function getCategory() { +    return $this->get('category'); +  } + +  /** +   * Specify one or more categories that the channel belongs to. +   * +   * @param string $category Category path seperated with forward slash. +   * @param string $domain Domain name which the category applies to. +   * @since RSS 2.0 +   */  +  public function setCategory($category, $domain) { +    $newNode = $this->createElement('category', $category); +    $newNode->setAttribute('domain', $domain); +    $node = $this->_channel->getElementsByTagName($category)->item(0);  +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($newNode, $node); +    } else { +      $this->_channel->appendChild($newNode); +    } +  } +   +  /** +   * @return string A string indicating the program used to generate the channel. +   */ +  public function getGenerator() { +    return $this->get('generator'); +  } + +  /** +   * @param string $generator A string indicating the program used to generate the channel. +   * @since RSS 2.0 +   */ +  public function setGenerator($generator) { +    if($this->getVersion() >= '2.0') { +      $this->set('generator', $generator); +    } else { +      throw new TInvalidDataTypeException('rssfeed_generator_unsupported'); +    } +  } + +  /** +   * ttl stands for time to live. It's a number of minutes that indicates how long a  +   * channel can be cached before refreshing from the source. +   * +   * @param int Number of minutes that channel can be cached. +   * @since RSS 2.0 +   */ +  public function setTimeToLive($ttl) { +     +  } + +  /** +   * Help getter +   */ +  private function get($name) { +    return $this->getElementsByTagName($name)->item(0)->nodeValue; +  } + +  /** +   * Helpt setter +   */ +  private function set($name, $value) { +    $newNode = $this->createElement($name, $value); +    $node = $this->_channel->getElementsByTagName($name)->item(0);  +    if($node instanceof DOMElement) { +      $this->_channel->replaceChild($newNode, $node); +    } else { +      $this->_channel->appendChild($newNode); +    } +  } + +  /** +   * +   * @return string Feed as XML +   */ +  public function getFeedContent() { +    return $this->saveXML(); +  } +} + +/** + * TRssFeedItem class + *  + * An item may represent a "story" -- much like a story in a newspaper or magazine; if so its  + * description is a synopsis of the story, and the link points to the full story. An item may  + * also be complete in itself, if so, the description contains the text (entity-encoded HTML  + * is allowed), and the link and title may be omitted. All elements of an item are optional,  + * however at least one of title or description must be present.  + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +class TRssFeedItem extends TFeedItem { + +   +  public function __construct() { +    parent::__construct('item'); +  } + +  /** +   * @return string The title of the item. +   */ +  public function getTitle() { +    return $this->get('title'); +  } + +  /** +   * @param string $title The title of the item. +   */ +  public function setTitle($title) {     +    $this->set('title', $title); +  }   + +  /** +   * @return string The URL of the item. +   */ +  public function getLink() { +    return $this->get('link'); +  } + +  /** +   * @param string $link The URL of the item. +   */ +  public function setLink($link) { +    $this->set('link', $link); +  } + +  /** +   * @return string The item synopsis. +   */ +  public function getDescription() { +    return $this->get('description'); +  } + +  /** +   * @param string $description The item synopsis. +   */ +  public function setDescription($description) { +    $this->set('description', $description); +  } + +   +  /** +   * The RSS channel that the item came from. The purpose of this property is to propagate  +   * credit for links, to publicize the sources of news items. It can be used in the Post  +   * command of an aggregator. It should be generated automatically when forwarding an item  +   * from an aggregator to a weblog authoring tool. +   * +   * @param string $source Name of source +   * @param string $url Link back to source +   * @since RSS 0.92 +   */ +  public function setSource($source, $url) { +    $source = $this->getElementsByTagName('source'); +    if($source instanceof TXmlElement) { +      $source->setValue($source); +      $source->setAttribute('url', $url); +    } else { +      $source = new TXmlElement('source'); +      $source->setValue($source); +      $source->setAttribute('url', $url); +      $this->getElements()->add($source); +    } +  } + +  /** +   * Describes a media object that is attached to the item. +   *  +   * @param string $url Where the enclosure is located. +   * @param int $length Size in bytes. +   * @param string $type  MIME type +   * @since RSS 0.92 +   */ +  public function setEnclosure($url, $length, $type) { +    $enclosure = $this->getElementsByTagName('enclosure'); +    if($enclosure instanceof TXmlElement) { +      $enclosure->setAttribute('url', $url); +      $enclosure->setAttribute('length', $length); +      $enclosure->setAttribute('type', $type); +    } else { +      $enclosure = new TXmlElement('enclosure'); +      $enclosure->setAttribute('url', $url); +      $enclosure->setAttribute('length', $length); +      $enclosure->setAttribute('type', $type); +      $this->getElements()->add($enclosure); +    } +  } + +  /** +   * Includes the item in one or more categories. +   *  +   * @param string $category A forward-slash-separated string that identifies a hierarchic location in the indicated taxonomy. +   * @param string $domain  +   * @since RSS 0.92 +   */ +  public function setCategory($category, $domain) { +    $element = $this->getElementsByTagName('category'); +    if($element instanceof TXmlElement) { +      $element->setValue($category); +      $element->setAttribute('domain', $domain); +    } else { +      $element = new TXmlElement('category'); +      $element->setValue($category); +      $element->setAttribute('domain', $domain); +      $this->getElements()->insertAt(count($this->getElements()), $element); +    } +  } + +  /** +   * @param string $comments URL of a page for comments relating to the item. +   * @since RSS 2.0 +   */ +  public function setComments($comments) { +    $this->set('comments', $comments); +  } + +  /** +   * @param string $author Email address of the author of the item. +   * @since RSS 2.0 +   */ +  public function setAuthor($author) { +    $this->set('author', $author); +  } + +  /** +   * @param string $pubDate Indicates when the item was published. +   * @since RSS 2.0 +   */ +  public function setPublicationDate($pubDate) { +    $this->set('pubDate', $pubDate); +  } + +  /** +   * guid stands for globally unique identifier. It's a string that uniquely identifies the  +   * item. When present, an aggregator may choose to use this string to determine if an item  +   * is new. +   * +   * @param string $guid A string that uniquely identifies the item. +   * @param bool $isPermaLink If its value is false, the guid may not be assumed to be a url, or a url to anything in particular. +   * @since RSS 2.0 +   */ +  public function setGuid($guid, $isPermaLink = true) { +     +  } +} + +/** + * TRssFeedItemList class + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +class TRssFeedItemList extends TList { +   + +  /*public function insertAt($index, TRssFeedItem $item) { +     +  } + +  public function removeAt($index) { +     +  }*/ + +} + +/** + * TRssFeedImage class + * + * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + */ +class TRssFeedImage extends TFeedElement { + +  public function __construct() { +    parent::__construct('image'); +  } + +  /** +   * @return string Title of the image. +   */ +  public function getTitle() { +    return $this->get('title'); +  } + +  /** +   * Title describes the image, it's used in the ALT attribute of the HTML <img> tag when the  +   * channel is rendered in HTML. +   * +   * @param string $title Title of the image. +   */ +  public function setTitle($title) { +    $this->set('title', $title); +  } + +  /** +   * @return string URL of a GIF, JPEG or PNG image that represents the channel. +   */ +  public function getUrl() { +    return $this->get('url'); +  } + +  /** +   * @param string $url URL of a GIF, JPEG or PNG image that represents the channel. +   */ +  public function setUrl($url) { +    $this->set('url', $url); +  } + +  /** +   * @return string The URL that a user is expected to click on. +   */ +  public function getLink() { +    return $this->get('link'); +  } + +  /** +   * The URL that a user is expected to click on, as opposed to a {@link TRssFeedImage::setUrl}  +   * that is for loading a resource, such as an image. +   * +   * The link must start with either "http://" or "ftp://". All other urls are considered  +   * invalid. +   *  +   * @param string $link The URL that a user is expected to click on. +   */ +  public function setLink($link) { +    if(substr($link, 0, 7) == 'http://' or substr($link, 0, 6) == 'ftp://') { +      $this->set('link', $link); +    } else { +      throw new TInvalidDataValueException('rssfeedimage_link_invalid'); +    } +  } + +  /** +   * @return int Width of the image in pixels. +   */ +  public function getWidth() { +    return $this->get('width'); +  } + +  /** +   * The value must be between 1 and 144. If ommitted, the default value is 88. +   *  +   * @param int Width of the image in pixels. +   */ +  public function setWidth($width) { +    if($width >= 1 and $width <= 144) { +      $this->set('width', $width); +    } else { +      throw new TInvalidDataValueException('rssfeedimage_width_invalid', 1, 144); +    } +  } + +  /** +   * @return int Height of the image in pixels. +   */ +  public function getHeight() { +    return $this->get('height'); +  } + +  /** +   * The value must be between 1 and 400. If ommitted, the default value is 31. +   * +   * @param int $height Height of the image in pixels. +   */ +  public function setHeight($height) { +    if($height >= 1 and $height <= 400) { +      $this->set('height', $height); +    } else { +      throw new TInvalidDataValueException('rssfeedimage_height_invalid', 1, 400); +    } +  } +   +  /** +   * @return string A plain text description of the image. +   */ +  public function getDescription() { +    return $this->get('description'); +  } + +  /** +   * @param string $description A plain text description of the image. +   */ +  public function setDescription($description) { +    $this->set('description', $description); +  } + +} + +/** + * TRssFeedTextInput class + * + * The purpose of the textinput element is something of a mystery. You can use it to specify  + * a search engine box. Or to allow a reader to provide feedback. Most aggregators ignore it. + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1  + */ +class TRssFeedTextInput extends TFeedElement { +   +  public function __construct() { +    parent::__construct('textinput'); +  } +   +  /** +   * @return string The label of the Submit button in the text input area. +   */ +  public function getTitle() { +    return $this->get('title'); +  } +   +  /** +   * @param string $title The label of the Submit button in the text input area. +   */ +  public function setTitle($title) { +    $this->set('title', $title); +  } + +  /** +   * @return string Explains the text input area. +   */ +  public function getDescription() { +    return $this->get('description'); +  } + +  /** +   * @param string $description Explains the text input area. +   */ +  public function setDescription($description) { +    $this->set('description', $description); +  } + +  /** +   * @return string The name of the text object in the text input area. +   */ +  public function getName() { +    return $this->get('name'); +  } + +  /** +   * @param string $name The name of the text object in the text input area. +   */ +  public function setName($name) { +    $this->set('name', $name); +  } + +  /** +   * @return string The URL of the script that processes text input requests. +   */ +  public function getLink() { +    return $this->get('link'); +  } + +  /** +   * @param string $link The URL of the script that processes text input requests. +   */ +  public function setLink($link) { +    $this->set('link', $link); +  } +} + + +/** + * TRssFeedCloud class + * + * It specifies a web service that supports the rssCloud interface which can be  + * implemented in HTTP-POST, XML-RPC or SOAP 1.1. + * + * Its purpose is to allow processes to register with a cloud to be notified of  + * updates to the channel, implementing a lightweight publish-subscribe protocol  + * for RSS feeds. + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Xml + * @since 3.1 + * @link http://www.rssboard.org/rsscloud-interface RssCloud API + */ +class TRssFeedCloud extends TFeedElement { + +  const PROTOCOL_HTTP_POST = 'HTTP-POST'; +  const PROTOCOL_XML_RPC = 'XML-RPC'; +  const PROTOCOL_SOAP = 'SOAP'; + +  public function __construct() { +    parent::__construct('cloud'); +  } + +  public function getDomain() { +    return $this->get('domain'); +  } + +  public function setDomain($domain) { +    $this->set('domain', $domain); +  } + +  public function getPort() { +    return $this->get('port'); +  } +   +  public function setPort($port) { +    $this->set('port', $port); +  } + +  public function getPath() { +    return $this->get('path'); +  } + +  public function setPath($path) { +    $this->set('path', $path); +  } + +  public function getRegisterProcedure() { +    return $this->get('registerProcedure'); +  } + +  public function setRegisterProcedure($registerProcedure) { +    $this->set('registerProcedure', $registerProcedure); +  } + +  public function getProtocol() { +    return $this->get('protocol'); +  } + +  public function setProtocol($protocol) { +    if(strcasecmp($protocol, self::PROTOCOL_HTTP_POST) or +       strcasecmp($protocol, self::PROTOCOL_XML_RPC) or +       strcasecmp($protocol, self::PROTOCOL_SOAP)) { +      $this->set('protocol', $protocol); +    } else { +      throw new TInvalidDataTypeException('rssfeedcloud_protocol_invalid', $protocol); +    } +  } + +  protected function get($name) { +    return $this->getAttribute($name)->nodeValue; +  } + +  protected function set($name, $value) { +    $this->setAttribute($name, $value); +  } + +} + +?>
\ No newline at end of file diff --git a/tests/unit/Xml/TRssFeedDocumentTest.php b/tests/unit/Xml/TRssFeedDocumentTest.php new file mode 100644 index 00000000..ad6bf7dc --- /dev/null +++ b/tests/unit/Xml/TRssFeedDocumentTest.php @@ -0,0 +1,158 @@ +<?php +require_once dirname(__FILE__).'/../phpunit2.php'; + +Prado::using('System.Xml.TRssFeedDocument'); + +/** + * @package System.Xml.TRssFeedDocument + */ +class TRssFeedDocumentTest extends PHPUnit2_Framework_TestCase { + +  public function testConstruct() { +    $feed = new TRssFeedDocument(); +    self::assertEquals('0.91', $feed->getVersion()); +    $feed = new TRssFeedDocument('UTF-8'); +    self::assertEquals('UTF-8', $feed->getEncoding()); +  } +   +  public function testSetVersion() { +    $feed = new TRssFeedDocument(); +    $feed->setVersion('0.92'); +    self::assertEquals('0.92', $feed->getVersion()); +    $feed->setVersion('2.0'); +    self::assertEquals('2.0', $feed->getVersion()); +  } + +  public function testSetTitle() { +    $expected = "This is a title"; +    $feed = new TRssFeedDocument(); +    $feed->setTitle($expected); +    self::assertEquals($expected, $feed->getTitle()); +  } + +  public function testSetLink() { +    $expected = "http://www.pradosoft.com"; +    $feed = new TRssFeedDocument(); +    $feed->setLink($expected); +    self::assertEquals($expected, $feed->getLink()); +  } + +  public function testSetDescription() { +    $expected = "This is a description"; +    $feed = new TRssFeedDocument(); +    $feed->setDescription($expected); +    self::assertEquals($expected, $feed->getDescription()); +  } + +  public function testSetLanguage() { +    $expected = "en-us"; +    $feed = new TRssFeedDocument(); +    $feed->setLanguage($expected); +    self::assertEquals($expected, $feed->getLanguage()); +  } + +  public function testSetCopyright() { +    $expected = "Copyright (C) 2006 PradoSoft"; +    $feed = new TRssFeedDocument(); +    $feed->setCopyright($expected); +    self::assertEquals($expected, $feed->getCopyright()); +  } + +  public function testSetManagingEditor() { +    $expected = "test@gmail.com"; +    $feed = new TRssFeedDocument(); +    $feed->setManagingEditor($expected); +    self::assertEquals($expected, $feed->getManagingEditor()); +  } + +  public function testSetWebMaster() { +    $expected = "test@gmail.com"; +    $feed = new TRssFeedDocument(); +    $feed->setWebMaster($expected); +    self::assertEquals($expected, $feed->getWebMaster()); +  } +   +  public function testSetRating() { +    $expected = '(PICS-1.1 "http://www.classify.org/safesurf/" l r (SS~~000 1))'; +    $feed = new TRssFeedDocument(); +    $feed->setRating($expected); +    self::assertEquals($expected, $feed->getRating()); +  } + +  public function testSetPublicationDate() { +    $expected = 'Fri, 13 Apr 2001 19:23:02 GMT'; +    $feed = new TRssFeedDocument(); +    $feed->setPublicationDate($expected); +    self::assertEquals($expected, $feed->getPublicationDate()); +  } + +  public function testSetLastBuildDate() { +    $expected = 'Fri, 13 Apr 2001 19:23:02 GMT'; +    $feed = new TRssFeedDocument(); +    $feed->setLastBuildDate($expected); +    self::assertEquals($expected, $feed->getLastBuildDate()); +  } + +  public function testSetDocumentation() { +    $expected = 'http://backend.userland.com/rss092'; +    $feed = new TRssFeedDocument(); +    $feed->setDocumentation($expected); +    self::assertEquals($expected, $feed->getDocumentation()); +  } + +  public function testSetSkipDays() { +    $expected = array('Saturday', 'Sunday'); +    $feed = new TRssFeedDocument(); +    $feed->setSkipDays($expected); +    self::assertEquals($expected, $feed->getSkipDays()); +  } + +  public function testSetSkipHours() { +    $expected = array(1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23); +    $feed = new TRssFeedDocument(); +    $feed->setSkipHours($expected); +    self::assertEquals($expected, $feed->getSkipHours()); +  } + +  public function testAddItem() { +    $feed = new TRssFeedDocument(); +    $item = new TRssFeedItem(); +    $feed->addItem($item); +    $items = $feed->getItems(); +    /*    var_dump($items); +    self::assertType($items[0], 'TRssItem');*/ +  } + +  public function testSetImage() { +    throw new PHPUnit2_Framework_IncompleteTestError(); +  } + +  public function testSetTextInput() { +    throw new PHPUnit2_Framework_IncompleteTestError(); +  } + +  public function testSetCloud() { +    throw new PHPUnit2_Framework_IncompleteTestError(); +  } + +  public function testSetCategory() { +    $expected = 'Business/Industries/Publishing/Publishers/Nonfiction/'; +    $feed = new TRssFeedDocument(); +    $feed->setCategory($expected, 'http://www.pradosoft.com'); +    self::assertEquals($expected, $feed->getCategory()); +  } + +  public function testSetGenerator() { +    $expected = 'PRADO 3.0'; +    $feed = new TRssFeedDocument(); +    $feed->setVersion('2.0'); +    $feed->setGenerator($expected); +    self::assertEquals($expected, $feed->getGenerator()); +  } + +  public function testSetTimeToLive() { +    throw new PHPUnit2_Framework_IncompleteTestError(); +  } +} + +?>
\ No newline at end of file  | 
