Merge branch '0.8.x' of git@gitorious.org:laconica/dev into 0.8.x

This commit is contained in:
Evan Prodromou 2009-02-06 15:38:01 -05:00
commit d260d841eb
15 changed files with 4716 additions and 1066 deletions

34
README
View File

@ -26,14 +26,14 @@ instant messenger programs (GTalk/Jabber), and specially-designed
desktop clients that support the Twitter API. desktop clients that support the Twitter API.
Laconica supports an open standard called OpenMicroBlogging Laconica supports an open standard called OpenMicroBlogging
(http://openmicroblogging.org/) that lets users on different Web sites <http://openmicroblogging.org/> that lets users on different Web sites
or in different companies subscribe to each others' notices. It or in different companies subscribe to each others' notices. It
enables a distributed social network spread all across the Web. enables a distributed social network spread all across the Web.
Laconica was originally developed for the Open Software Service, Laconica was originally developed for the Open Software Service,
Identi.ca (http://identi.ca/). It is shared with you in hope that you Identi.ca <http://identi.ca/>. It is shared with you in hope that you
too make an Open Software Service available to your users. To learn too make an Open Software Service available to your users. To learn
more, please see the Open Software Service Definition 1.0: more, please see the Open Software Service Definition 1.1:
http://www.opendefinition.org/ossd http://www.opendefinition.org/ossd
@ -182,6 +182,10 @@ and the URLs are listed here for your convenience.
version may render your Laconica site unable to send or receive XMPP version may render your Laconica site unable to send or receive XMPP
messages. messages.
- Facebook library. Used for the Facebook application. - Facebook library. Used for the Facebook application.
- PEAR Services_oEmbed. Used for some multimedia integration.
- PEAR HTTP_Request is an oEmbed dependency.
- PEAR Validat is an oEmbed dependency.e
- PEAR Net_URL is an oEmbed dependency.2
A design goal of Laconica is that the basic Web functionality should A design goal of Laconica is that the basic Web functionality should
work on even the most restrictive commercial hosting services. work on even the most restrictive commercial hosting services.
@ -404,7 +408,7 @@ config.php, and access to the Laconica database from the mail server.
XMPP XMPP
---- ----
XMPP (eXtended Message and Presence Protocol, http://xmpp.org/) is the XMPP (eXtended Message and Presence Protocol, <http://xmpp.org/>) is the
instant-messenger protocol that drives Jabber and GTalk IM. You can instant-messenger protocol that drives Jabber and GTalk IM. You can
distribute messages via XMPP using the system below; however, you distribute messages via XMPP using the system below; however, you
need to run the XMPP incoming daemon to allow incoming messages as need to run the XMPP incoming daemon to allow incoming messages as
@ -537,7 +541,7 @@ Sample cron job:
Sitemaps Sitemaps
-------- --------
Sitemap files (http://sitemaps.org/) are a very nice way of telling Sitemap files <http://sitemaps.org/> are a very nice way of telling
search engines and other interested bots what's available on your site search engines and other interested bots what's available on your site
and what's changed recently. You can generate sitemap files for your and what's changed recently. You can generate sitemap files for your
Laconica instance. Laconica instance.
@ -558,7 +562,7 @@ Laconica instance.
like './sitemapindex.xml'. sitemap-directory is the directory where like './sitemapindex.xml'. sitemap-directory is the directory where
you want the sitemaps stored, like './sitemaps/' (make sure the dir you want the sitemaps stored, like './sitemaps/' (make sure the dir
exists). URL-prefix-for-sitemaps is the full URL for the sitemap dir, exists). URL-prefix-for-sitemaps is the full URL for the sitemap dir,
typically something like 'http://example.net/mublog/sitemaps/'. typically something like <http://example.net/mublog/sitemaps/>.
You can use several methods for submitting your sitemap index to You can use several methods for submitting your sitemap index to
search engines to get your site indexed. One is to add a line like the search engines to get your site indexed. One is to add a line like the
@ -612,7 +616,7 @@ modification to use the new output format.
Translation Translation
----------- -----------
Translations in Laconica use the gettext system (http://www.gnu.org/software/gettext/). Translations in Laconica use the gettext system <http://www.gnu.org/software/gettext/>.
Theoretically, you can add your own sub-directory to the locale/ Theoretically, you can add your own sub-directory to the locale/
subdirectory to add a new language to your system. You'll need to subdirectory to add a new language to your system. You'll need to
compile the ".po" files into ".mo" files, however. compile the ".po" files into ".mo" files, however.
@ -627,7 +631,7 @@ Backups
There is no built-in system for doing backups in Laconica. You can make There is no built-in system for doing backups in Laconica. You can make
backups of a working Laconica system by backing up the database and backups of a working Laconica system by backing up the database and
the Web directory. To backup the database use mysqldump (http://ur1.ca/7xo) the Web directory. To backup the database use mysqldump <http://ur1.ca/7xo>
and to backup the Web directory, try tar. and to backup the Web directory, try tar.
Private Private
@ -819,7 +823,7 @@ db
-- --
This section is a reference to the configuration options for This section is a reference to the configuration options for
DB_DataObject (see http://ur1.ca/7xp). The ones that you may want to DB_DataObject (see <http://ur1.ca/7xp>). The ones that you may want to
set are listed below for clarity. set are listed below for clarity.
database: a DSN (Data Source Name) for your Laconica database. This is database: a DSN (Data Source Name) for your Laconica database. This is
@ -919,7 +923,7 @@ server: If set, defines another server where avatars are stored in the
the client to speed up page loading, either with another the client to speed up page loading, either with another
virtual server or with an NFS or SAMBA share. Clients virtual server or with an NFS or SAMBA share. Clients
typically only make 2 connections to a single server at a typically only make 2 connections to a single server at a
time (http://ur1.ca/6ih), so this can parallelize the job. time <http://ur1.ca/6ih>, so this can parallelize the job.
Defaults to null. Defaults to null.
public public
@ -1000,7 +1004,7 @@ memcached
--------- ---------
You can get a significant boost in performance by caching some You can get a significant boost in performance by caching some
database data in memcached (http://www.danga.com/memcached/). database data in memcached <http://www.danga.com/memcached/>.
enabled: Set to true to enable. Default false. enabled: Set to true to enable. Default false.
server: a string with the hostname of the memcached server. Can also server: a string with the hostname of the memcached server. Can also
@ -1011,7 +1015,7 @@ sphinx
You can get a significant boost in performance using Sphinx Search You can get a significant boost in performance using Sphinx Search
instead of your database server to search for users and notices. instead of your database server to search for users and notices.
(http://sphinxsearch.com/). <http://sphinxsearch.com/>.
enabled: Set to true to enable. Default false. enabled: Set to true to enable. Default false.
server: a string with the hostname of the sphinx server. server: a string with the hostname of the sphinx server.
@ -1024,7 +1028,7 @@ A catch-all for integration with other systems.
source: The name to use for the source of posts to Twitter. Defaults source: The name to use for the source of posts to Twitter. Defaults
to 'laconica', but if you request your own source name from to 'laconica', but if you request your own source name from
Twitter (http://twitter.com/help/request_source), you can use Twitter <http://twitter.com/help/request_source>, you can use
that here instead. Status updates on Twitter will then have that here instead. Status updates on Twitter will then have
links to your site. links to your site.
@ -1101,7 +1105,7 @@ Unstable version
If you're adventurous or impatient, you may want to install the If you're adventurous or impatient, you may want to install the
development version of Laconica. To get it, use the git version development version of Laconica. To get it, use the git version
control tool (http://git-scm.com/) like so: control tool <http://git-scm.com/> like so:
git clone http://laconi.ca/software/laconica.git git clone http://laconi.ca/software/laconica.git
@ -1114,7 +1118,7 @@ There are several ways to get more information about Laconica.
* There is a mailing list for Laconica developers and admins at * There is a mailing list for Laconica developers and admins at
http://mail.laconi.ca/mailman/listinfo/laconica-dev http://mail.laconi.ca/mailman/listinfo/laconica-dev
* The #laconica IRC channel on freenode.net (http://www.freenode.net/). * The #laconica IRC channel on freenode.net <http://www.freenode.net/>.
* The Laconica wiki, http://laconi.ca/trac/ * The Laconica wiki, http://laconi.ca/trac/
Feedback Feedback

1521
extlib/HTTP/Request.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,106 @@
<?php
/**
* Listener for HTTP_Request and HTTP_Response objects
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2002-2007, Richard Heyes
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTTP
* @package HTTP_Request
* @author Alexey Borzov <avb@php.net>
* @copyright 2002-2007 Richard Heyes
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Listener.php,v 1.3 2007/05/18 10:33:31 avb Exp $
* @link http://pear.php.net/package/HTTP_Request/
*/
/**
* Listener for HTTP_Request and HTTP_Response objects
*
* This class implements the Observer part of a Subject-Observer
* design pattern.
*
* @category HTTP
* @package HTTP_Request
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.4.4
*/
class HTTP_Request_Listener
{
/**
* A listener's identifier
* @var string
*/
var $_id;
/**
* Constructor, sets the object's identifier
*
* @access public
*/
function HTTP_Request_Listener()
{
$this->_id = md5(uniqid('http_request_', 1));
}
/**
* Returns the listener's identifier
*
* @access public
* @return string
*/
function getId()
{
return $this->_id;
}
/**
* This method is called when Listener is notified of an event
*
* @access public
* @param object an object the listener is attached to
* @param string Event name
* @param mixed Additional data
* @abstract
*/
function update(&$subject, $event, $data = null)
{
echo "Notified of event: '$event'\n";
if (null !== $data) {
echo "Additional data: ";
var_dump($data);
}
}
}
?>

813
extlib/Net/URL2.php Normal file
View File

@ -0,0 +1,813 @@
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2007-2008, Christian Schmidt, Peytz & Co. A/S |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Christian Schmidt <schmidt at php dot net> |
// +-----------------------------------------------------------------------+
//
// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $
//
// Net_URL2 Class (PHP5 Only)
// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
/**
* @license BSD License
*/
class Net_URL2
{
/**
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
* is true.
*/
const OPTION_STRICT = 'strict';
/**
* Represent arrays in query using PHP's [] notation. Default is true.
*/
const OPTION_USE_BRACKETS = 'use_brackets';
/**
* URL-encode query variable keys. Default is true.
*/
const OPTION_ENCODE_KEYS = 'encode_keys';
/**
* Query variable separators when parsing the query string. Every character
* is considered a separator. Default is specified by the
* arg_separator.input php.ini setting (this defaults to "&").
*/
const OPTION_SEPARATOR_INPUT = 'input_separator';
/**
* Query variable separator used when generating the query string. Default
* is specified by the arg_separator.output php.ini setting (this defaults
* to "&").
*/
const OPTION_SEPARATOR_OUTPUT = 'output_separator';
/**
* Default options corresponds to how PHP handles $_GET.
*/
private $options = array(
self::OPTION_STRICT => true,
self::OPTION_USE_BRACKETS => true,
self::OPTION_ENCODE_KEYS => true,
self::OPTION_SEPARATOR_INPUT => 'x&',
self::OPTION_SEPARATOR_OUTPUT => 'x&',
);
/**
* @var string|bool
*/
private $scheme = false;
/**
* @var string|bool
*/
private $userinfo = false;
/**
* @var string|bool
*/
private $host = false;
/**
* @var int|bool
*/
private $port = false;
/**
* @var string
*/
private $path = '';
/**
* @var string|bool
*/
private $query = false;
/**
* @var string|bool
*/
private $fragment = false;
/**
* @param string $url an absolute or relative URL
* @param array $options
*/
public function __construct($url, $options = null)
{
$this->setOption(self::OPTION_SEPARATOR_INPUT,
ini_get('arg_separator.input'));
$this->setOption(self::OPTION_SEPARATOR_OUTPUT,
ini_get('arg_separator.output'));
if (is_array($options)) {
foreach ($options as $optionName => $value) {
$this->setOption($optionName);
}
}
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
$this->scheme = $reg[1];
$url = substr($url, strlen($reg[0]));
}
if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
$this->setAuthority($reg[1]);
$url = substr($url, strlen($reg[0]));
}
$i = strcspn($url, '?#');
$this->path = substr($url, 0, $i);
$url = substr($url, $i);
if (preg_match('@^\?([^#]*)@', $url, $reg)) {
$this->query = $reg[1];
$url = substr($url, strlen($reg[0]));
}
if ($url) {
$this->fragment = substr($url, 1);
}
}
/**
* Returns the scheme, e.g. "http" or "urn", or false if there is no
* scheme specified, i.e. if this is a relative URL.
*
* @return string|bool
*/
public function getScheme()
{
return $this->scheme;
}
/**
* @param string|bool $scheme
*
* @return void
* @see getScheme()
*/
public function setScheme($scheme)
{
$this->scheme = $scheme;
}
/**
* Returns the user part of the userinfo part (the part preceding the first
* ":"), or false if there is no userinfo part.
*
* @return string|bool
*/
public function getUser()
{
return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
}
/**
* Returns the password part of the userinfo part (the part after the first
* ":"), or false if there is no userinfo part (i.e. the URL does not
* contain "@" in front of the hostname) or the userinfo part does not
* contain ":".
*
* @return string|bool
*/
public function getPassword()
{
return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
}
/**
* Returns the userinfo part, or false if there is none, i.e. if the
* authority part does not contain "@".
*
* @return string|bool
*/
public function getUserinfo()
{
return $this->userinfo;
}
/**
* Sets the userinfo part. If two arguments are passed, they are combined
* in the userinfo part as username ":" password.
*
* @param string|bool $userinfo userinfo or username
* @param string|bool $password
*
* @return void
*/
public function setUserinfo($userinfo, $password = false)
{
$this->userinfo = $userinfo;
if ($password !== false) {
$this->userinfo .= ':' . $password;
}
}
/**
* Returns the host part, or false if there is no authority part, e.g.
* relative URLs.
*
* @return string|bool
*/
public function getHost()
{
return $this->host;
}
/**
* @param string|bool $host
*
* @return void
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* Returns the port number, or false if there is no port number specified,
* i.e. if the default port is to be used.
*
* @return int|bool
*/
public function getPort()
{
return $this->port;
}
/**
* @param int|bool $port
*
* @return void
*/
public function setPort($port)
{
$this->port = intval($port);
}
/**
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
* false if there is no authority none.
*
* @return string|bool
*/
public function getAuthority()
{
if (!$this->host) {
return false;
}
$authority = '';
if ($this->userinfo !== false) {
$authority .= $this->userinfo . '@';
}
$authority .= $this->host;
if ($this->port !== false) {
$authority .= ':' . $this->port;
}
return $authority;
}
/**
* @param string|false $authority
*
* @return void
*/
public function setAuthority($authority)
{
$this->user = false;
$this->pass = false;
$this->host = false;
$this->port = false;
if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
if ($reg[1]) {
$this->userinfo = $reg[2];
}
$this->host = $reg[3];
if (isset($reg[5])) {
$this->port = intval($reg[5]);
}
}
}
/**
* Returns the path part (possibly an empty string).
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* @param string $path
*
* @return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Returns the query string (excluding the leading "?"), or false if "?"
* isn't present in the URL.
*
* @return string|bool
* @see self::getQueryVariables()
*/
public function getQuery()
{
return $this->query;
}
/**
* @param string|bool $query
*
* @return void
* @see self::setQueryVariables()
*/
public function setQuery($query)
{
$this->query = $query;
}
/**
* Returns the fragment name, or false if "#" isn't present in the URL.
*
* @return string|bool
*/
public function getFragment()
{
return $this->fragment;
}
/**
* @param string|bool $fragment
*
* @return void
*/
public function setFragment($fragment)
{
$this->fragment = $fragment;
}
/**
* Returns the query string like an array as the variables would appear in
* $_GET in a PHP script.
*
* @return array
*/
public function getQueryVariables()
{
$pattern = '/[' .
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
']/';
$parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach ($parts as $part) {
if (strpos($part, '=') !== false) {
list($key, $value) = explode('=', $part, 2);
} else {
$key = $part;
$value = null;
}
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
$key = rawurldecode($key);
}
$value = rawurldecode($value);
if ($this->getOption(self::OPTION_USE_BRACKETS) &&
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
$key = $matches[1];
$idx = $matches[2];
// Ensure is an array
if (empty($return[$key]) || !is_array($return[$key])) {
$return[$key] = array();
}
// Add data
if ($idx === '') {
$return[$key][] = $value;
} else {
$return[$key][$idx] = $value;
}
} elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
&& !empty($return[$key])
) {
$return[$key] = (array) $return[$key];
$return[$key][] = $value;
} else {
$return[$key] = $value;
}
}
return $return;
}
/**
* @param array $array (name => value) array
*
* @return void
*/
public function setQueryVariables(array $array)
{
if (!$array) {
$this->query = false;
} else {
foreach ($array as $name => $value) {
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
$name = rawurlencode($name);
}
if (is_array($value)) {
foreach ($value as $k => $v) {
$parts[] = $this->getOption(self::OPTION_USE_BRACKETS)
? sprintf('%s[%s]=%s', $name, $k, $v)
: ($name . '=' . $v);
}
} elseif (!is_null($value)) {
$parts[] = $name . '=' . $value;
} else {
$parts[] = $name;
}
}
$this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
$parts);
}
}
/**
* @param string $name
* @param mixed $value
*
* @return array
*/
public function setQueryVariable($name, $value)
{
$array = $this->getQueryVariables();
$array[$name] = $value;
$this->setQueryVariables($array);
}
/**
* @param string $name
*
* @return void
*/
public function unsetQueryVariable($name)
{
$array = $this->getQueryVariables();
unset($array[$name]);
$this->setQueryVariables($array);
}
/**
* Returns a string representation of this URL.
*
* @return string
*/
public function getURL()
{
// See RFC 3986, section 5.3
$url = "";
if ($this->scheme !== false) {
$url .= $this->scheme . ':';
}
$authority = $this->getAuthority();
if ($authority !== false) {
$url .= '//' . $authority;
}
$url .= $this->path;
if ($this->query !== false) {
$url .= '?' . $this->query;
}
if ($this->fragment !== false) {
$url .= '#' . $this->fragment;
}
return $url;
}
/**
* Returns a normalized string representation of this URL. This is useful
* for comparison of URLs.
*
* @return string
*/
public function getNormalizedURL()
{
$url = clone $this;
$url->normalize();
return $url->getUrl();
}
/**
* Returns a normalized Net_URL2 instance.
*
* @return Net_URL2
*/
public function normalize()
{
// See RFC 3886, section 6
// Schemes are case-insensitive
if ($this->scheme) {
$this->scheme = strtolower($this->scheme);
}
// Hostnames are case-insensitive
if ($this->host) {
$this->host = strtolower($this->host);
}
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
if ($this->port &&
$this->scheme &&
$this->port == getservbyname($this->scheme, 'tcp')) {
$this->port = false;
}
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
foreach (array('userinfo', 'host', 'path') as $part) {
if ($this->$part) {
$this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
}
}
// Path segment normalization (RFC 3986, section 6.2.2.3)
$this->path = self::removeDotSegments($this->path);
// Scheme based normalization (RFC 3986, section 6.2.3)
if ($this->host && !$this->path) {
$this->path = '/';
}
}
/**
* Returns whether this instance represents an absolute URL.
*
* @return bool
*/
public function isAbsolute()
{
return (bool) $this->scheme;
}
/**
* Returns an Net_URL2 instance representing an absolute URL relative to
* this URL.
*
* @param Net_URL2|string $reference relative URL
*
* @return Net_URL2
*/
public function resolve($reference)
{
if (is_string($reference)) {
$reference = new self($reference);
}
if (!$this->isAbsolute()) {
throw new Exception('Base-URL must be absolute');
}
// A non-strict parser may ignore a scheme in the reference if it is
// identical to the base URI's scheme.
if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
$reference->scheme = false;
}
$target = new self('');
if ($reference->scheme !== false) {
$target->scheme = $reference->scheme;
$target->setAuthority($reference->getAuthority());
$target->path = self::removeDotSegments($reference->path);
$target->query = $reference->query;
} else {
$authority = $reference->getAuthority();
if ($authority !== false) {
$target->setAuthority($authority);
$target->path = self::removeDotSegments($reference->path);
$target->query = $reference->query;
} else {
if ($reference->path == '') {
$target->path = $this->path;
if ($reference->query !== false) {
$target->query = $reference->query;
} else {
$target->query = $this->query;
}
} else {
if (substr($reference->path, 0, 1) == '/') {
$target->path = self::removeDotSegments($reference->path);
} else {
// Merge paths (RFC 3986, section 5.2.3)
if ($this->host !== false && $this->path == '') {
$target->path = '/' . $this->path;
} else {
$i = strrpos($this->path, '/');
if ($i !== false) {
$target->path = substr($this->path, 0, $i + 1);
}
$target->path .= $reference->path;
}
$target->path = self::removeDotSegments($target->path);
}
$target->query = $reference->query;
}
$target->setAuthority($this->getAuthority());
}
$target->scheme = $this->scheme;
}
$target->fragment = $reference->fragment;
return $target;
}
/**
* Removes dots as described in RFC 3986, section 5.2.4, e.g.
* "/foo/../bar/baz" => "/bar/baz"
*
* @param string $path a path
*
* @return string a path
*/
private static function removeDotSegments($path)
{
$output = '';
// Make sure not to be trapped in an infinite loop due to a bug in this
// method
$j = 0;
while ($path && $j++ < 100) {
// Step A
if (substr($path, 0, 2) == './') {
$path = substr($path, 2);
} elseif (substr($path, 0, 3) == '../') {
$path = substr($path, 3);
// Step B
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
$path = '/' . substr($path, 3);
// Step C
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
$path = '/' . substr($path, 4);
$i = strrpos($output, '/');
$output = $i === false ? '' : substr($output, 0, $i);
// Step D
} elseif ($path == '.' || $path == '..') {
$path = '';
// Step E
} else {
$i = strpos($path, '/');
if ($i === 0) {
$i = strpos($path, '/', 1);
}
if ($i === false) {
$i = strlen($path);
}
$output .= substr($path, 0, $i);
$path = substr($path, $i);
}
}
return $output;
}
/**
* Returns a Net_URL2 instance representing the canonical URL of the
* currently executing PHP script.
*
* @return string
*/
public static function getCanonical()
{
if (!isset($_SERVER['REQUEST_METHOD'])) {
// ALERT - no current URL
throw new Exception('Script was not called through a webserver');
}
// Begin with a relative URL
$url = new self($_SERVER['PHP_SELF']);
$url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
$url->host = $_SERVER['SERVER_NAME'];
$port = intval($_SERVER['SERVER_PORT']);
if ($url->scheme == 'http' && $port != 80 ||
$url->scheme == 'https' && $port != 443) {
$url->port = $port;
}
return $url;
}
/**
* Returns the URL used to retrieve the current request.
*
* @return string
*/
public static function getRequestedURL()
{
return self::getRequested()->getUrl();
}
/**
* Returns a Net_URL2 instance representing the URL used to retrieve the
* current request.
*
* @return Net_URL2
*/
public static function getRequested()
{
if (!isset($_SERVER['REQUEST_METHOD'])) {
// ALERT - no current URL
throw new Exception('Script was not called through a webserver');
}
// Begin with a relative URL
$url = new self($_SERVER['REQUEST_URI']);
$url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
// Set host and possibly port
$url->setAuthority($_SERVER['HTTP_HOST']);
return $url;
}
/**
* Sets the specified option.
*
* @param string $optionName a self::OPTION_ constant
* @param mixed $value option value
*
* @return void
* @see self::OPTION_STRICT
* @see self::OPTION_USE_BRACKETS
* @see self::OPTION_ENCODE_KEYS
*/
function setOption($optionName, $value)
{
if (!array_key_exists($optionName, $this->options)) {
return false;
}
$this->options[$optionName] = $value;
}
/**
* Returns the value of the specified option.
*
* @param string $optionName The name of the option to retrieve
*
* @return mixed
*/
function getOption($optionName)
{
return isset($this->options[$optionName])
? $this->options[$optionName] : false;
}
}

357
extlib/Services/oEmbed.php Normal file
View File

@ -0,0 +1,357 @@
<?php
/**
* An interface for oEmbed consumption
*
* PHP version 5.1.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Validate.php';
require_once 'Net/URL2.php';
require_once 'HTTP/Request.php';
require_once 'Services/oEmbed/Exception.php';
require_once 'Services/oEmbed/Exception/NoSupport.php';
require_once 'Services/oEmbed/Object.php';
/**
* Base class for consuming oEmbed objects
*
* <code>
* <?php
*
* require_once 'Services/oEmbed.php';
*
* // The URL that we'd like to find out more information about.
* $url = 'http://flickr.com/photos/joestump/2848795611/';
*
* // The oEmbed API URI. Not all providers support discovery yet so we're
* // explicitly providing one here. If one is not provided Services_oEmbed
* // attempts to discover it. If none is found an exception is thrown.
* $oEmbed = new Services_oEmbed($url, array(
* Services_oEmbed::OPTION_API => 'http://www.flickr.com/services/oembed/'
* ));
* $object = $oEmbed->getObject();
*
* // All of the objects have somewhat sane __toString() methods that allow
* // you to output them directly.
* echo (string)$object;
*
* ?>
* </code>
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed
{
/**
* HTTP timeout in seconds
*
* All HTTP requests made by Services_oEmbed will respect this timeout.
* This can be passed to {@link Services_oEmbed::setOption()} or to the
* options parameter in {@link Services_oEmbed::__construct()}.
*
* @var string OPTION_TIMEOUT Timeout in seconds
*/
const OPTION_TIMEOUT = 'http_timeout';
/**
* HTTP User-Agent
*
* All HTTP requests made by Services_oEmbed will be sent with the
* string set by this option.
*
* @var string OPTION_USER_AGENT The HTTP User-Agent string
*/
const OPTION_USER_AGENT = 'http_user_agent';
/**
* The API's URI
*
* If the API is known ahead of time this option can be used to explicitly
* set it. If not present then the API is attempted to be discovered
* through the auto-discovery mechanism.
*
* @var string OPTION_API
*/
const OPTION_API = 'oembed_api';
/**
* Options for oEmbed requests
*
* @var array $options The options for making requests
*/
protected $options = array(
self::OPTION_TIMEOUT => 3,
self::OPTION_API => null,
self::OPTION_USER_AGENT => 'Services_oEmbed 0.1.0'
);
/**
* URL of object to get embed information for
*
* @var object $url {@link Net_URL2} instance of URL of object
*/
protected $url = null;
/**
* Constructor
*
* @param string $url The URL to fetch an oEmbed for
* @param array $options A list of options for the oEmbed lookup
*
* @throws {@link Services_oEmbed_Exception} if the $url is invalid
* @throws {@link Services_oEmbed_Exception} when no valid API is found
* @return void
*/
public function __construct($url, array $options = array())
{
if (Validate::uri($url)) {
$this->url = new Net_URL2($url);
} else {
throw new Services_oEmbed_Exception('URL is invalid');
}
if (count($options)) {
foreach ($options as $key => $val) {
$this->setOption($key, $val);
}
}
if ($this->options[self::OPTION_API] === null) {
$this->options[self::OPTION_API] = $this->discover();
}
}
/**
* Set an option for the oEmbed request
*
* @param mixed $option The option name
* @param mixed $value The option value
*
* @see Services_oEmbed::OPTION_API, Services_oEmbed::OPTION_TIMEOUT
* @throws {@link Services_oEmbed_Exception} on invalid option
* @access public
* @return void
*/
public function setOption($option, $value)
{
switch ($option) {
case self::OPTION_API:
case self::OPTION_TIMEOUT:
break;
default:
throw new Services_oEmbed_Exception(
'Invalid option "' . $option . '"'
);
}
$func = '_set_' . $option;
if (method_exists($this, $func)) {
$this->options[$option] = $this->$func($value);
} else {
$this->options[$option] = $value;
}
}
/**
* Set the API option
*
* @param string $value The API's URI
*
* @throws {@link Services_oEmbed_Exception} on invalid API URI
* @see Validate::uri()
* @return string
*/
protected function _set_oembed_api($value)
{
if (!Validate::uri($value)) {
throw new Services_oEmbed_Exception(
'API URI provided is invalid'
);
}
return $value;
}
/**
* Get the oEmbed response
*
* @param array $params Optional parameters for
*
* @throws {@link Services_oEmbed_Exception} on cURL errors
* @throws {@link Services_oEmbed_Exception} on HTTP errors
* @throws {@link Services_oEmbed_Exception} when result is not parsable
* @return object The oEmbed response as an object
*/
public function getObject(array $params = array())
{
$params['url'] = $this->url->getURL();
if (!isset($params['format'])) {
$params['format'] = 'json';
}
$sets = array();
foreach ($params as $var => $val) {
$sets[] = $var . '=' . urlencode($val);
}
$url = $this->options[self::OPTION_API] . '?' . implode('&', $sets);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->options[self::OPTION_TIMEOUT]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Services_oEmbed_Exception(
curl_error($ch), curl_errno($ch)
);
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (substr($code, 0, 1) != '2') {
throw new Services_oEmbed_Exception('Non-200 code returned');
}
curl_close($ch);
switch ($params['format']) {
case 'json':
$res = json_decode($result);
if (!is_object($res)) {
throw new Services_oEmbed_Exception(
'Could not parse JSON response'
);
}
break;
case 'xml':
libxml_use_internal_errors(true);
$res = simplexml_load_string($result);
if (!$res instanceof SimpleXMLElement) {
$errors = libxml_get_errors();
$err = array_shift($errors);
libxml_clear_errors();
libxml_use_internal_errors(false);
throw new Services_oEmbed_Exception(
$err->message, $error->code
);
}
break;
}
return Services_oEmbed_Object::factory($res);
}
/**
* Discover an oEmbed API
*
* @param string $url The URL to attempt to discover oEmbed for
*
* @throws {@link Services_oEmbed_Exception} if the $url is invalid
* @return string The oEmbed API endpoint discovered
*/
protected function discover($url)
{
$body = $this->sendRequest($url);
// Find all <link /> tags that have a valid oembed type set. We then
// extract the href attribute for each type.
$regexp = '#<link([^>]*)type="' .
'(application/json|text/xml)\+oembed"([^>]*)>#i';
$m = $ret = array();
if (!preg_match_all($regexp, $body, $m)) {
throw new Services_oEmbed_Exception_NoSupport(
'No valid oEmbed links found on page'
);
}
foreach ($m[0] as $i => $link) {
$h = array();
if (preg_match('/href="([^"]+)"/i', $link, $h)) {
$ret[$m[2][$i]] = $h[1];
}
}
return (isset($ret['json']) ? $ret['json'] : array_pop($ret));
}
/**
* Send a GET request to the provider
*
* @param mixed $url The URL to send the request to
*
* @throws {@link Services_oEmbed_Exception} on HTTP errors
* @return string The contents of the response
*/
private function sendRequest($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->options[self::OPTION_TIMEOUT]);
curl_setopt($ch, CURLOPT_USERAGENT, $this->options[self::OPTION_USER_AGENT]);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Services_oEmbed_Exception(
curl_error($ch), curl_errno($ch)
);
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (substr($code, 0, 1) != '2') {
throw new Services_oEmbed_Exception('Non-200 code returned');
}
return $result;
}
}
?>

View File

@ -0,0 +1,65 @@
<?php
/**
* Base exception class for {@link Services_oEmbed}
*
* PHP version 5.1.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'PEAR/Exception.php';
/**
* Base exception class for {@link Services_oEmbed}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Exception extends PEAR_Exception
{
}
?>

View File

@ -0,0 +1,63 @@
<?php
/**
* Exception class when no oEmbed support is discovered
*
* PHP version 5.2.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
/**
* Exception class when no oEmbed support is discovered
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Exception_NoSupport extends Services_oEmbed_Exception
{
}
?>

View File

@ -0,0 +1,126 @@
<?php
/**
* An interface for oEmbed consumption
*
* PHP version 5.1.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Object/Exception.php';
/**
* Base class for consuming oEmbed objects
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
abstract class Services_oEmbed_Object
{
/**
* Valid oEmbed object types
*
* @var array $types Array of valid object types
* @see Services_oEmbed_Object::factory()
*/
static protected $types = array(
'photo' => 'Photo',
'video' => 'Video',
'link' => 'Link',
'rich' => 'Rich'
);
/**
* Create an oEmbed object from result
*
* @param object $object Raw object returned from API
*
* @throws {@link Services_oEmbed_Object_Exception} on object error
* @return object Instance of object driver
* @see Services_oEmbed_Object_Link, Services_oEmbed_Object_Photo
* @see Services_oEmbed_Object_Rich, Services_oEmbed_Object_Video
*/
static public function factory($object)
{
if (!isset($object->type)) {
throw new Services_oEmbed_Object_Exception(
'Object has no type'
);
}
$type = (string)$object->type;
if (!isset(self::$types[$type])) {
throw new Services_oEmbed_Object_Exception(
'Object type is unknown or invalid: ' . $type
);
}
$file = 'Services/oEmbed/Object/' . self::$types[$type] . '.php';
include_once $file;
$class = 'Services_oEmbed_Object_' . self::$types[$type];
if (!class_exists($class)) {
throw new Services_oEmbed_Object_Exception(
'Object class is invalid or not present'
);
}
$instance = new $class($object);
return $instance;
}
/**
* Instantiation is not allowed
*
* @return void
*/
private function __construct()
{
}
}
?>

View File

@ -0,0 +1,139 @@
<?php
/**
* Base class for oEmbed objects
*
* PHP version 5.1.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
/**
* Base class for oEmbed objects
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
abstract class Services_oEmbed_Object_Common
{
/**
* Raw object returned from API
*
* @var object $object The raw object from the API
*/
protected $object = null;
/**
* Required fields per the specification
*
* @var array $required Array of required fields
* @link http://oembed.com
*/
protected $required = array();
/**
* Constructor
*
* @param object $object Raw object returned from the API
*
* @throws {@link Services_oEmbed_Object_Exception} on missing fields
* @return void
*/
public function __construct($object)
{
$this->object = $object;
$this->required[] = 'version';
foreach ($this->required as $field) {
if (!isset($this->$field)) {
throw new Services_oEmbed_Object_Exception(
'Object is missing required ' . $field . ' attribute'
);
}
}
}
/**
* Get object variable
*
* @param string $var Variable to get
*
* @see Services_oEmbed_Object_Common::$object
* @return mixed Attribute's value or null if it's not set/exists
*/
public function __get($var)
{
if (property_exists($this->object, $var)) {
return $this->object->$var;
}
return null;
}
/**
* Is variable set?
*
* @param string $var Variable name to check
*
* @return boolean True if set, false if not
* @see Services_oEmbed_Object_Common::$object
*/
public function __isset($var)
{
if (property_exists($this->object, $var)) {
return (isset($this->object->$var));
}
return false;
}
/**
* Require a sane __toString for all objects
*
* @return string
*/
abstract public function __toString();
}
?>

View File

@ -0,0 +1,65 @@
<?php
/**
* Exception for {@link Services_oEmbed_Object}
*
* PHP version 5.1.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Exception.php';
/**
* Exception for {@link Services_oEmbed_Object}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Object_Exception extends Services_oEmbed_Exception
{
}
?>

View File

@ -0,0 +1,73 @@
<?php
/**
* Link object for {@link Services_oEmbed}
*
* PHP version 5.2.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Object/Common.php';
/**
* Link object for {@link Services_oEmbed}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Object_Link extends Services_oEmbed_Object_Common
{
/**
* Output a sane link
*
* @return string An HTML link of the object
*/
public function __toString()
{
return '<a href="' . $this->url . '">' . $this->title . '</a>';
}
}
?>

View File

@ -0,0 +1,89 @@
<?php
/**
* Photo object for {@link Services_oEmbed}
*
* PHP version 5.2.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Object/Common.php';
/**
* Photo object for {@link Services_oEmbed}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Object_Photo extends Services_oEmbed_Object_Common
{
/**
* Required fields for photo objects
*
* @var array $required Required fields
*/
protected $required = array(
'url', 'width', 'height'
);
/**
* Output a valid HTML tag for image
*
* @return string HTML <img /> tag for Photo
*/
public function __toString()
{
$img = '<img src="' . $this->url . '" width="' . $this->width . '" ' .
'height="' . $this->height . '"';
if (isset($this->title)) {
$img .= ' alt="' . $this->title . '"';
}
return $img . ' />';
}
}
?>

View File

@ -0,0 +1,82 @@
<?php
/**
* Photo object for {@link Services_oEmbed}
*
* PHP version 5.2.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Object/Common.php';
/**
* Photo object for {@link Services_oEmbed}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Object_Rich extends Services_oEmbed_Object_Common
{
/**
* Required fields for rich objects
*
* @var array $required Required fields
*/
protected $required = array(
'html', 'width', 'height'
);
/**
* Output a the HTML tag for rich object
*
* @return string HTML for rich object
*/
public function __toString()
{
return $this->html;
}
}
?>

View File

@ -0,0 +1,82 @@
<?php
/**
* Photo object for {@link Services_oEmbed}
*
* PHP version 5.2.0+
*
* Copyright (c) 2008, Digg.com, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Digg.com, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version SVN: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
require_once 'Services/oEmbed/Object/Common.php';
/**
* Photo object for {@link Services_oEmbed}
*
* @category Services
* @package Services_oEmbed
* @author Joe Stump <joe@joestump.net>
* @copyright 2008 Digg.com, Inc.
* @license http://tinyurl.com/42zef New BSD License
* @version Release: @version@
* @link http://code.google.com/p/digg
* @link http://oembed.com
*/
class Services_oEmbed_Object_Video extends Services_oEmbed_Object_Common
{
/**
* Required fields for video objects
*
* @var array $required Required fields
*/
protected $required = array(
'html', 'width', 'height'
);
/**
* Output a valid embed tag for video
*
* @return string HTML for video
*/
public function __toString()
{
return $this->html;
}
}
?>

View File

@ -1,24 +1,22 @@
<?php <?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox, Amir Saied |
// +----------------------------------------------------------------------+
// | This source file is subject to the New BSD license, That is bundled |
// | with this package in the file LICENSE, and is available through |
// | the world-wide-web at |
// | http://www.opensource.org/licenses/bsd-license.php |
// | If you did not receive a copy of the new BSDlicense and are unable |
// | to obtain it through the world-wide-web, please send a note to |
// | pajoye@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Tomas V.V.Cox <cox@idecnet.com> |
// | Pierre-Alain Joye <pajoye@php.net> |
// | Amir Mohammad Saied <amir@php.net> |
// +----------------------------------------------------------------------+
//
/** /**
* Validation class * Validation class
* *
* Copyright (c) 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox, Amir Saied
*
* This source file is subject to the New BSD license, That is bundled
* with this package in the file LICENSE, and is available through
* the world-wide-web at
* http://www.opensource.org/licenses/bsd-license.php
* If you did not receive a copy of the new BSDlicense and are unable
* to obtain it through the world-wide-web, please send a note to
* pajoye@php.net so we can mail you a copy immediately.
*
* Author: Tomas V.V.Cox <cox@idecnet.com>
* Pierre-Alain Joye <pajoye@php.net>
* Amir Mohammad Saied <amir@php.net>
*
*
* Package to validate various datas. It includes : * Package to validate various datas. It includes :
* - numbers (min/max, decimal or not) * - numbers (min/max, decimal or not)
* - email (syntax, domain check) * - email (syntax, domain check)
@ -34,7 +32,7 @@
* @author Amir Mohammad Saied <amir@php.net> * @author Amir Mohammad Saied <amir@php.net>
* @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Validate.php,v 1.123 2007/12/12 16:45:51 davidc Exp $ * @version CVS: $Id: Validate.php,v 1.134 2009/01/28 12:27:33 davidc Exp $
* @link http://pear.php.net/package/Validate * @link http://pear.php.net/package/Validate
*/ */
@ -69,15 +67,15 @@ define('VALIDATE_ALL_EMAILS', 8);
* - uri (RFC2396) * - uri (RFC2396)
* - possibility valid multiple data with a single method call (::multiple) * - possibility valid multiple data with a single method call (::multiple)
* *
* @category Validate * @category Validate
* @package Validate * @package Validate
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Pierre-Alain Joye <pajoye@php.net> * @author Pierre-Alain Joye <pajoye@php.net>
* @author Amir Mohammad Saied <amir@php.net> * @author Amir Mohammad Saied <amir@php.net>
* @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@ * @version Release: @package_version@
* @link http://pear.php.net/package/Validate * @link http://pear.php.net/package/Validate
*/ */
class Validate class Validate
{ {
@ -205,17 +203,51 @@ class Validate
'zm','zw', 'zm','zw',
); );
/**
* Validate a tag URI (RFC4151)
*
* @param string $uri tag URI to validate
*
* @return boolean true if valid tag URI, false if not
*
* @access private
*/
function __uriRFC4151($uri)
{
$datevalid = false;
if (preg_match(
'/^tag:(?<name>.*),(?<date>\d{4}-?\d{0,2}-?\d{0,2}):(?<specific>.*)(.*:)*$/', $uri, $matches)) {
$date = $matches['date'];
$date6 = strtotime($date);
if ((strlen($date) == 4) && $date <= date('Y')) {
$datevalid = true;
} elseif ((strlen($date) == 7) && ($date6 < strtotime("now"))) {
$datevalid = true;
} elseif ((strlen($date) == 10) && ($date6 < strtotime("now"))) {
$datevalid = true;
}
if (self::email($matches['name'])) {
$namevalid = true;
} else {
$namevalid = self::email('info@' . $matches['name']);
}
return $datevalid && $namevalid;
} else {
return false;
}
}
/** /**
* Validate a number * Validate a number
* *
* @param string $number Number to validate * @param string $number Number to validate
* @param array $options array where: * @param array $options array where:
* 'decimal' is the decimal char or false when decimal not allowed * 'decimal' is the decimal char or false when decimal
* i.e. ',.' to allow both ',' and '.' * not allowed.
* 'dec_prec' Number of allowed decimals * i.e. ',.' to allow both ',' and '.'
* 'min' minimum value * 'dec_prec' Number of allowed decimals
* 'max' maximum value * 'min' minimum value
* 'max' maximum value
* *
* @return boolean true if valid number, false if not * @return boolean true if valid number, false if not
* *
@ -228,8 +260,8 @@ class Validate
extract($options); extract($options);
} }
$dec_prec = $dec_prec ? "{1,$dec_prec}" : '+'; $dec_prec = $dec_prec ? "{1,$dec_prec}" : '+';
$dec_regex = $decimal ? "[$decimal][0-9]$dec_prec" : ''; $dec_regex = $decimal ? "[$decimal][0-9]$dec_prec" : '';
if (!preg_match("|^[-+]?\s*[0-9]+($dec_regex)?\$|", $number)) { if (!preg_match("|^[-+]?\s*[0-9]+($dec_regex)?\$|", $number)) {
return false; return false;
@ -253,15 +285,16 @@ class Validate
/** /**
* Converting a string to UTF-7 (RFC 2152) * Converting a string to UTF-7 (RFC 2152)
* *
* @param $string string to be converted * @param string $string string to be converted
* *
* @return string converted string * @return string converted string
* *
* @access private * @access private
*/ */
function __stringToUtf7($string) { function __stringToUtf7($string)
{
$return = ''; $return = '';
$utf7 = array( $utf7 = array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
@ -270,7 +303,9 @@ class Validate
'3', '4', '5', '6', '7', '8', '9', '+', ',' '3', '4', '5', '6', '7', '8', '9', '+', ','
); );
$state = 0; $state = 0;
if (!empty($string)) { if (!empty($string)) {
$i = 0; $i = 0;
while ($i <= strlen($string)) { while ($i <= strlen($string)) {
@ -296,24 +331,24 @@ class Validate
} }
} }
$return .= '-'; $return .= '-';
$state = 0; $state = 0;
} else { } else {
switch($state) { switch($state) {
case 1: case 1:
$return .= $utf7[ord($char) >> 2]; $return .= $utf7[ord($char) >> 2];
$residue = (ord($char) & 0x03) << 4; $residue = (ord($char) & 0x03) << 4;
$state = 2; $state = 2;
break; break;
case 2: case 2:
$return .= $utf7[$residue | (ord($char) >> 4)]; $return .= $utf7[$residue | (ord($char) >> 4)];
$residue = (ord($char) & 0x0F) << 2; $residue = (ord($char) & 0x0F) << 2;
$state = 3; $state = 3;
break; break;
case 3: case 3:
$return .= $utf7[$residue | (ord($char) >> 6)]; $return .= $utf7[$residue | (ord($char) >> 6)];
$return .= $utf7[ord($char) & 0x3F]; $return .= $utf7[ord($char) & 0x3F];
$state = 1; $state = 1;
break; break;
} }
} }
$i++; $i++;
@ -326,9 +361,9 @@ class Validate
/** /**
* Validate an email according to full RFC822 (inclusive human readable part) * Validate an email according to full RFC822 (inclusive human readable part)
* *
* @param string $email email to validate, * @param string $email email to validate,
* will return the address for optional dns validation * will return the address for optional dns validation
* @param array $options email() options * @param array $options email() options
* *
* @return boolean true if valid email, false if not * @return boolean true if valid email, false if not
* *
@ -336,10 +371,7 @@ class Validate
*/ */
function __emailRFC822(&$email, &$options) function __emailRFC822(&$email, &$options)
{ {
if (Validate::__stringToUtf7($email) != $email) { static $address = null;
return false;
}
static $address = null;
static $uncomment = null; static $uncomment = null;
if (!$address) { if (!$address) {
// atom = 1*<any CHAR except specials, SPACE and CTLs> // atom = 1*<any CHAR except specials, SPACE and CTLs>
@ -383,6 +415,7 @@ class Validate
// address = mailbox ; one addressee // address = mailbox ; one addressee
// / group ; named list // / group ; named list
$address = '/^\s*(?:' . $mailbox . '|' . $group . ')$/'; $address = '/^\s*(?:' . $mailbox . '|' . $group . ')$/';
$uncomment = $uncomment =
'/((?:(?:\\\\"|[^("])*(?:' . $quoted_string . '/((?:(?:\\\\"|[^("])*(?:' . $quoted_string .
')?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/'; ')?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/';
@ -398,61 +431,19 @@ class Validate
* This function is used to make a much more proficient validation * This function is used to make a much more proficient validation
* against all types of official domain names. * against all types of official domain names.
* *
* @param string $email The email address to check.
* @param array $options The options for validation
*
* @access protected * @access protected
* @param string $email The email address to check. *
* @param array $options The options for validation * @return bool True if validating succeeds
* @return bool True if validating succeeds
*/ */
function _fullTLDValidation($email, $options) function _fullTLDValidation($email, $options)
{ {
$validate = array(); $validate = array();
if(!empty($options["VALIDATE_ITLD_EMAILS"])) array_push($validate, 'itld');
switch ($options) { if(!empty($options["VALIDATE_GTLD_EMAILS"])) array_push($validate, 'gtld');
/** 1 */ if(!empty($options["VALIDATE_CCTLD_EMAILS"])) array_push($validate, 'cctld');
case VALIDATE_ITLD_EMAILS:
array_push($validate, 'itld');
break;
/** 2 */
case VALIDATE_GTLD_EMAILS:
array_push($validate, 'gtld');
break;
/** 3 */
case VALIDATE_ITLD_EMAILS | VALIDATE_GTLD_EMAILS:
array_push($validate, 'itld');
array_push($validate, 'gtld');
break;
/** 4 */
case VALIDATE_CCTLD_EMAILS:
array_push($validate, 'cctld');
break;
/** 5 */
case VALIDATE_CCTLD_EMAILS | VALIDATE_ITLD_EMAILS:
array_push($validate, 'cctld');
array_push($validate, 'itld');
break;
/** 6 */
case VALIDATE_CCTLD_EMAILS ^ VALIDATE_ITLD_EMAILS:
array_push($validate, 'cctld');
array_push($validate, 'itld');
break;
/** 7 - 8 */
case VALIDATE_CCTLD_EMAILS | VALIDATE_ITLD_EMAILS | VALIDATE_GTLD_EMAILS:
case VALIDATE_ALL_EMAILS:
array_push($validate, 'cctld');
array_push($validate, 'itld');
array_push($validate, 'gtld');
break;
}
/**
* Debugging still, not implemented but code is somewhat here.
*/
$self = new Validate; $self = new Validate;
@ -460,6 +451,7 @@ class Validate
foreach ($validate as $valid) { foreach ($validate as $valid) {
$tmpVar = '_' . (string)$valid; $tmpVar = '_' . (string)$valid;
$toValidate[$valid] = $self->{$tmpVar}; $toValidate[$valid] = $self->{$tmpVar};
} }
@ -467,23 +459,24 @@ class Validate
return $e; return $e;
} }
// {{{ protected function executeFullEmailValidation
/** /**
* Execute the validation * Execute the validation
* *
* This function will execute the full email vs tld * This function will execute the full email vs tld
* validation using an array of tlds passed to it. * validation using an array of tlds passed to it.
* *
* @param string $email The email to validate.
* @param array $arrayOfTLDs The array of the TLDs to validate
*
* @access public * @access public
* @param string $email The email to validate. *
* @param array $arrayOfTLDs The array of the TLDs to validate
* @return true or false (Depending on if it validates or if it does not) * @return true or false (Depending on if it validates or if it does not)
*/ */
function executeFullEmailValidation($email, $arrayOfTLDs) function executeFullEmailValidation($email, $arrayOfTLDs)
{ {
$emailEnding = explode('.', $email); $emailEnding = explode('.', $email);
$emailEnding = $emailEnding[count($emailEnding)-1]; $emailEnding = $emailEnding[count($emailEnding)-1];
foreach ($arrayOfTLDs as $validator => $keys) { foreach ($arrayOfTLDs as $validator => $keys) {
if (in_array($emailEnding, $keys)) { if (in_array($emailEnding, $keys)) {
return true; return true;
@ -491,17 +484,26 @@ class Validate
} }
return false; return false;
} }
// }}}
/** /**
* Validate an email * Validate an email
* *
* @param string $email email to validate * @param string $email email to validate
* @param mixed boolean (BC) $check_domain Check or not if the domain exists * @param mixed boolean (BC) $check_domain Check or not if the domain exists
* array $options associative array of options * array $options associative array of options
* 'check_domain' boolean Check or not if the domain exists * 'check_domain' boolean Check or not if the domain exists
* 'use_rfc822' boolean Apply the full RFC822 grammar * 'use_rfc822' boolean Apply the full RFC822 grammar
* *
* Ex.
* $options = array(
* 'check_domain' => 'true',
* 'fullTLDValidation' => 'true',
* 'use_rfc822' => 'true',
* 'VALIDATE_GTLD_EMAILS' => 'true',
* 'VALIDATE_CCTLD_EMAILS' => 'true',
* 'VALIDATE_ITLD_EMAILS' => 'true',
* );
*
* @return boolean true if valid email, false if not * @return boolean true if valid email, false if not
* *
* @access public * @access public
@ -509,19 +511,46 @@ class Validate
function email($email, $options = null) function email($email, $options = null)
{ {
$check_domain = false; $check_domain = false;
$use_rfc822 = false; $use_rfc822 = false;
if (is_bool($options)) { if (is_bool($options)) {
$check_domain = $options; $check_domain = $options;
} elseif (is_array($options)) { } elseif (is_array($options)) {
extract($options); extract($options);
} }
/**
* Check for IDN usage so we can encode the domain as Punycode
* before continuing.
*/
$hasIDNA = false;
if (@include_once('Net/IDNA.php')) {
$hasIDNA = true;
}
if ($hasIDNA === true) {
if (strpos($email, '@') !== false) {
list($name, $domain) = explode('@', $email, 2);
// Check if the domain contains characters > 127 which means
// it's an idn domain name.
$chars = count_chars($domain, 1);
if (!empty($chars) && max(array_keys($chars)) > 127) {
$idna =& Net_IDNA::singleton();
$domain = $idna->encode($domain);
}
$email = "$name@$domain";
}
}
/** /**
* @todo Fix bug here.. even if it passes this, it won't be passing * @todo Fix bug here.. even if it passes this, it won't be passing
* The regular expression below * The regular expression below
*/ */
if (isset($fullTLDValidation)) { if (isset($fullTLDValidation)) {
$valid = Validate::_fullTLDValidation($email, $fullTLDValidation); //$valid = Validate::_fullTLDValidation($email, $fullTLDValidation);
$valid = Validate::_fullTLDValidation($email, $options);
if (!$valid) { if (!$valid) {
return false; return false;
@ -539,10 +568,11 @@ class Validate
\.((?:([^- ])[-a-z]*[-a-z]))) #7 TLD \.((?:([^- ])[-a-z]*[-a-z]))) #7 TLD
$&xi'; $&xi';
//checks if exists the domain (MX or A)
if ($use_rfc822? Validate::__emailRFC822($email, $options) : if ($use_rfc822? Validate::__emailRFC822($email, $options) :
preg_match($regex, $email)) { preg_match($regex, $email)) {
if ($check_domain && function_exists('checkdnsrr')) { if ($check_domain && function_exists('checkdnsrr')) {
list (, $domain) = explode('@', $email); list ($account, $domain) = explode('@', $email);
if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) { if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) {
return true; return true;
} }
@ -553,15 +583,15 @@ class Validate
return false; return false;
} }
/** /**
* Validate a string using the given format 'format' * Validate a string using the given format 'format'
* *
* @param string $string String to validate * @param string $string String to validate
* @param array $options Options array where: * @param array $options Options array where:
* 'format' is the format of the string * 'format' is the format of the string
* Ex: VALIDATE_NUM . VALIDATE_ALPHA (see constants) * Ex:VALIDATE_NUM . VALIDATE_ALPHA (see constants)
* 'min_length' minimum length * 'min_length' minimum length
* 'max_length' maximum length * 'max_length' maximum length
* *
* @return boolean true if valid string, false if not * @return boolean true if valid string, false if not
* *
@ -569,20 +599,26 @@ class Validate
*/ */
function string($string, $options) function string($string, $options)
{ {
$format = null; $format = null;
$min_length = $max_length = 0; $min_length = 0;
$max_length = 0;
if (is_array($options)) { if (is_array($options)) {
extract($options); extract($options);
} }
if ($format && !preg_match("|^[$format]*\$|s", $string)) { if ($format && !preg_match("|^[$format]*\$|s", $string)) {
return false; return false;
} }
if ($min_length && strlen($string) < $min_length) { if ($min_length && strlen($string) < $min_length) {
return false; return false;
} }
if ($max_length && strlen($string) > $max_length) { if ($max_length && strlen($string) > $max_length) {
return false; return false;
} }
return true; return true;
} }
@ -606,18 +642,18 @@ class Validate
* the characters ';/?:@$,' will not be accepted in the query part * the characters ';/?:@$,' will not be accepted in the query part
* if not urlencoded, refer to the option "strict'" * if not urlencoded, refer to the option "strict'"
* *
* @param string $url URI to validate * @param string $url URI to validate
* @param array $options Options used by the validation method. * @param array $options Options used by the validation method.
* key => type * key => type
* 'domain_check' => boolean * 'domain_check' => boolean
* Whether to check the DNS entry or not * Whether to check the DNS entry or not
* 'allowed_schemes' => array, list of protocols * 'allowed_schemes' => array, list of protocols
* List of allowed schemes ('http', * List of allowed schemes ('http',
* 'ssh+svn', 'mms') * 'ssh+svn', 'mms')
* 'strict' => string the refused chars * 'strict' => string the refused chars
* in query and fragment parts * in query and fragment parts
* default: ';/?:@$,' * default: ';/?:@$,'
* empty: accept all rfc2396 foreseen chars * empty: accept all rfc2396 foreseen chars
* *
* @return boolean true if valid uri, false if not * @return boolean true if valid uri, false if not
* *
@ -631,6 +667,14 @@ class Validate
if (is_array($options)) { if (is_array($options)) {
extract($options); extract($options);
} }
if (is_array($allowed_schemes) &&
in_array("tag", $allowed_schemes)
) {
if (strpos($url, "tag:") === 0) {
return self::__uriRFC4151($url);
}
}
if (preg_match( if (preg_match(
'&^(?:([a-z][-+.a-z0-9]*):)? # 1. scheme '&^(?:([a-z][-+.a-z0-9]*):)? # 1. scheme
(?:// # authority start (?:// # authority start
@ -645,7 +689,7 @@ class Validate
$scheme = isset($matches[1]) ? $matches[1] : ''; $scheme = isset($matches[1]) ? $matches[1] : '';
$authority = isset($matches[3]) ? $matches[3] : '' ; $authority = isset($matches[3]) ? $matches[3] : '' ;
if (is_array($allowed_schemes) && if (is_array($allowed_schemes) &&
!in_array($scheme,$allowed_schemes) !in_array($scheme, $allowed_schemes)
) { ) {
return false; return false;
} }
@ -676,16 +720,16 @@ class Validate
/** /**
* Validate date and times. Note that this method need the Date_Calc class * Validate date and times. Note that this method need the Date_Calc class
* *
* @param string $date Date to validate * @param string $date Date to validate
* @param array $options array options where : * @param array $options array options where :
* 'format' The format of the date (%d-%m-%Y) * 'format' The format of the date (%d-%m-%Y)
* or rfc822_compliant * or rfc822_compliant
* 'min' The date has to be greater * 'min' The date has to be greater
* than this array($day, $month, $year) * than this array($day, $month, $year)
* or PEAR::Date object * or PEAR::Date object
* 'max' The date has to be smaller than * 'max' The date has to be smaller than
* this array($day, $month, $year) * this array($day, $month, $year)
* or PEAR::Date object * or PEAR::Date object
* *
* @return boolean true if valid date/time, false if not * @return boolean true if valid date/time, false if not
* *
@ -693,8 +737,10 @@ class Validate
*/ */
function date($date, $options) function date($date, $options)
{ {
$max = $min = false; $max = false;
$min = false;
$format = ''; $format = '';
if (is_array($options)) { if (is_array($options)) {
extract($options); extract($options);
} }
@ -711,15 +757,15 @@ class Validate
return false; return false;
} }
$year = (int)$matches[4]; $year = (int)$matches[4];
$months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
$month = array_keys($months, $matches[3]); $month = array_keys($months, $matches[3]);
$month = (int)$month[0]+1; $month = (int)$month[0]+1;
$day = (int)$matches[2]; $day = (int)$matches[2];
$weekday= $matches[1]; $weekday = $matches[1];
$hour = (int)$matches[6]; $hour = (int)$matches[6];
$minute = (int)$matches[7]; $minute = (int)$matches[7];
isset($matches[9]) ? $second = (int)$matches[9] : $second = 0; isset($matches[9]) ? $second = (int)$matches[9] : $second = 0;
if ((strlen($year) != 4) || if ((strlen($year) != 4) ||
@ -736,72 +782,72 @@ class Validate
if ($c == '%') { if ($c == '%') {
$next = $format{$i + 1}; $next = $format{$i + 1};
switch ($next) { switch ($next) {
case 'j': case 'j':
case 'd': case 'd':
if ($next == 'j') { if ($next == 'j') {
$day = (int)Validate::_substr($date, 1, 2); $day = (int)Validate::_substr($date, 1, 2);
} else { } else {
$day = (int)Validate::_substr($date, 0, 2); $day = (int)Validate::_substr($date, 0, 2);
} }
if ($day < 1 || $day > 31) { if ($day < 1 || $day > 31) {
return false; return false;
} }
break; break;
case 'm': case 'm':
case 'n': case 'n':
if ($next == 'm') { if ($next == 'm') {
$month = (int)Validate::_substr($date, 0, 2); $month = (int)Validate::_substr($date, 0, 2);
} else { } else {
$month = (int)Validate::_substr($date, 1, 2); $month = (int)Validate::_substr($date, 1, 2);
} }
if ($month < 1 || $month > 12) { if ($month < 1 || $month > 12) {
return false; return false;
} }
break; break;
case 'Y': case 'Y':
case 'y': case 'y':
if ($next == 'Y') { if ($next == 'Y') {
$year = Validate::_substr($date, 4); $year = Validate::_substr($date, 4);
$year = (int)$year?$year:''; $year = (int)$year?$year:'';
} else { } else {
$year = (int)(substr(date('Y'), 0, 2) . $year = (int)(substr(date('Y'), 0, 2) .
Validate::_substr($date, 2)); Validate::_substr($date, 2));
} }
if (strlen($year) != 4 || $year < 0 || $year > 9999) { if (strlen($year) != 4 || $year < 0 || $year > 9999) {
return false; return false;
} }
break; break;
case 'g': case 'g':
case 'h': case 'h':
if ($next == 'g') { if ($next == 'g') {
$hour = Validate::_substr($date, 1, 2); $hour = Validate::_substr($date, 1, 2);
} else { } else {
$hour = Validate::_substr($date, 2); $hour = Validate::_substr($date, 2);
} }
if (!preg_match('/^\d+$/', $hour) || $hour < 0 || $hour > 12) { if (!preg_match('/^\d+$/', $hour) || $hour < 0 || $hour > 12) {
return false; return false;
} }
break; break;
case 'G': case 'G':
case 'H': case 'H':
if ($next == 'G') { if ($next == 'G') {
$hour = Validate::_substr($date, 1, 2); $hour = Validate::_substr($date, 1, 2);
} else { } else {
$hour = Validate::_substr($date, 2); $hour = Validate::_substr($date, 2);
} }
if (!preg_match('/^\d+$/', $hour) || $hour < 0 || $hour > 24) { if (!preg_match('/^\d+$/', $hour) || $hour < 0 || $hour > 24) {
return false; return false;
} }
break; break;
case 's': case 's':
case 'i': case 'i':
$t = Validate::_substr($date, 2); $t = Validate::_substr($date, 2);
if (!preg_match('/^\d+$/', $t) || $t < 0 || $t > 59) { if (!preg_match('/^\d+$/', $t) || $t < 0 || $t > 59) {
return false; return false;
} }
break; break;
default: default:
trigger_error("Not supported char `$next' after % in offset " . ($i+2), E_USER_WARNING); trigger_error("Not supported char `$next' after % in offset " . ($i+2), E_USER_WARNING);
} }
$i++; $i++;
} else { } else {
@ -832,13 +878,13 @@ class Validate
include_once 'Date/Calc.php'; include_once 'Date/Calc.php';
if (is_a($min, 'Date') && if (is_a($min, 'Date') &&
(Date_Calc::compareDates($day, $month, $year, (Date_Calc::compareDates($day, $month, $year,
$min->getDay(), $min->getMonth(), $min->getYear()) < 0)) $min->getDay(), $min->getMonth(), $min->getYear()) < 0)
{ ) {
return false; return false;
} elseif (is_array($min) && } elseif (is_array($min) &&
(Date_Calc::compareDates($day, $month, $year, (Date_Calc::compareDates($day, $month, $year,
$min[0], $min[1], $min[2]) < 0)) $min[0], $min[1], $min[2]) < 0)
{ ) {
return false; return false;
} }
} }
@ -847,13 +893,13 @@ class Validate
include_once 'Date/Calc.php'; include_once 'Date/Calc.php';
if (is_a($max, 'Date') && if (is_a($max, 'Date') &&
(Date_Calc::compareDates($day, $month, $year, (Date_Calc::compareDates($day, $month, $year,
$max->getDay(), $max->getMonth(), $max->getYear()) > 0)) $max->getDay(), $max->getMonth(), $max->getYear()) > 0)
{ ) {
return false; return false;
} elseif (is_array($max) && } elseif (is_array($max) &&
(Date_Calc::compareDates($day, $month, $year, (Date_Calc::compareDates($day, $month, $year,
$max[0], $max[1], $max[2]) > 0)) $max[0], $max[1], $max[2]) > 0)
{ ) {
return false; return false;
} }
} }
@ -862,6 +908,16 @@ class Validate
return true; return true;
} }
/**
* Substr
*
* @param string &$date Date
* @param string $num Length
* @param string $opt Unknown
*
* @access private
* @return string
*/
function _substr(&$date, $num, $opt = false) function _substr(&$date, $num, $opt = false)
{ {
if ($opt && strlen($date) >= $opt && preg_match('/^[0-9]{'.$opt.'}/', $date, $m)) { if ($opt && strlen($date) >= $opt && preg_match('/^[0-9]{'.$opt.'}/', $date, $m)) {
@ -873,7 +929,8 @@ class Validate
return $ret; return $ret;
} }
function _modf($val, $div) { function _modf($val, $div)
{
if (function_exists('bcmod')) { if (function_exists('bcmod')) {
return bcmod($val, $div); return bcmod($val, $div);
} elseif (function_exists('fmod')) { } elseif (function_exists('fmod')) {
@ -887,21 +944,22 @@ class Validate
/** /**
* Calculates sum of product of number digits with weights * Calculates sum of product of number digits with weights
* *
* @param string $number number string * @param string $number number string
* @param array $weights reference to array of weights * @param array $weights reference to array of weights
*
* @returns int returns product of number digits with weights
* *
* @access protected * @access protected
*
* @return int returns product of number digits with weights
*/ */
function _multWeights($number, &$weights) { function _multWeights($number, &$weights)
{
if (!is_array($weights)) { if (!is_array($weights)) {
return -1; return -1;
} }
$sum = 0; $sum = 0;
$count = min(count($weights), strlen($number)); $count = min(count($weights), strlen($number));
if ($count == 0) { // empty string or weights array if ($count == 0) { // empty string or weights array
return -1; return -1;
} }
for ($i = 0; $i < $count; ++$i) { for ($i = 0; $i < $count; ++$i) {
@ -914,17 +972,18 @@ class Validate
/** /**
* Calculates control digit for a given number * Calculates control digit for a given number
* *
* @param string $number number string * @param string $number number string
* @param array $weights reference to array of weights * @param array $weights reference to array of weights
* @param int $modulo (optionsl) number * @param int $modulo (optionsl) number
* @param int $subtract (optional) number * @param int $subtract (optional) number
* @param bool $allow_high (optional) true if function can return number higher than 10 * @param bool $allow_high (optional) true if function can return number higher than 10
*
* @returns int -1 calculated control number is returned
* *
* @access protected * @access protected
*
* @return int -1 calculated control number is returned
*/ */
function _getControlNumber($number, &$weights, $modulo = 10, $subtract = 0, $allow_high = false) { function _getControlNumber($number, &$weights, $modulo = 10, $subtract = 0, $allow_high = false)
{
// calc sum // calc sum
$sum = Validate::_multWeights($number, $weights); $sum = Validate::_multWeights($number, $weights);
if ($sum == -1) { if ($sum == -1) {
@ -944,16 +1003,17 @@ class Validate
/** /**
* Validates a number * Validates a number
* *
* @param string $number number to validate * @param string $number number to validate
* @param array $weights reference to array of weights * @param array $weights reference to array of weights
* @param int $modulo (optionsl) number * @param int $modulo (optional) number
* @param int $subtract (optional) numbier * @param int $subtract (optional) number
*
* @returns bool true if valid, false if not
* *
* @access protected * @access protected
*
* @return bool true if valid, false if not
*/ */
function _checkControlNumber($number, &$weights, $modulo = 10, $subtract = 0) { function _checkControlNumber($number, &$weights, $modulo = 10, $subtract = 0)
{
if (strlen($number) < count($weights)) { if (strlen($number) < count($weights)) {
return false; return false;
} }
@ -977,13 +1037,13 @@ class Validate
* assoc array in the form $var_name => $value. * assoc array in the form $var_name => $value.
* Can be used on any of Validate subpackages * Can be used on any of Validate subpackages
* *
* @param array $data Ex: array('name' => 'toto', 'email' => 'toto@thing.info'); * @param array $data Ex: array('name' => 'toto', 'email' => 'toto@thing.info');
* @param array $val_type Contains the validation type and all parameters used in. * @param array $val_type Contains the validation type and all parameters used in.
* 'val_type' is not optional * 'val_type' is not optional
* others validations properties must have the same name as the function * others validations properties must have the same name as the function
* parameters. * parameters.
* Ex: array('toto'=>array('type'=>'string','format'='toto@thing.info','min_length'=>5)); * Ex: array('toto'=>array('type'=>'string','format'='toto@thing.info','min_length'=>5));
* @param boolean $remove if set, the elements not listed in data will be removed * @param boolean $remove if set, the elements not listed in data will be removed
* *
* @return array value name => true|false the value name comes from the data key * @return array value name => true|false the value name comes from the data key
* *
@ -991,8 +1051,9 @@ class Validate
*/ */
function multiple(&$data, &$val_type, $remove = false) function multiple(&$data, &$val_type, $remove = false)
{ {
$keys = array_keys($data); $keys = array_keys($data);
$valid = array(); $valid = array();
foreach ($keys as $var_name) { foreach ($keys as $var_name) {
if (!isset($val_type[$var_name])) { if (!isset($val_type[$var_name])) {
if ($remove) { if ($remove) {
@ -1000,8 +1061,8 @@ class Validate
} }
continue; continue;
} }
$opt = $val_type[$var_name]; $opt = $val_type[$var_name];
$methods = get_class_methods('Validate'); $methods = get_class_methods('Validate');
$val2check = $data[$var_name]; $val2check = $data[$var_name];
// core validation method // core validation method
if (in_array(strtolower($opt['type']), $methods)) { if (in_array(strtolower($opt['type']), $methods)) {
@ -1014,11 +1075,11 @@ class Validate
} }
$valid[$var_name] = call_user_func(array('Validate', $method), $val2check, $opt); $valid[$var_name] = call_user_func(array('Validate', $method), $val2check, $opt);
/** /**
* external validation method in the form: * external validation method in the form:
* "<class name><underscore><method name>" * "<class name><underscore><method name>"
* Ex: us_ssn will include class Validate/US.php and call method ssn() * Ex: us_ssn will include class Validate/US.php and call method ssn()
*/ */
} elseif (strpos($opt['type'], '_') !== false) { } elseif (strpos($opt['type'], '_') !== false) {
$validateType = explode('_', $opt['type']); $validateType = explode('_', $opt['type']);
$method = array_pop($validateType); $method = array_pop($validateType);
@ -1029,20 +1090,24 @@ class Validate
trigger_error("$class isn't installed or you may have some permissoin issues", E_USER_ERROR); trigger_error("$class isn't installed or you may have some permissoin issues", E_USER_ERROR);
} }
$ce = substr(phpversion(), 0, 1) > 4 ? class_exists($class, false) : class_exists($class); $ce = substr(phpversion(), 0, 1) > 4 ?
class_exists($class, false) : class_exists($class);
if (!$ce || if (!$ce ||
!in_array($method, get_class_methods($class))) !in_array($method, get_class_methods($class))
{ ) {
trigger_error("Invalid validation type $class::$method", E_USER_WARNING); trigger_error("Invalid validation type $class::$method",
E_USER_WARNING);
continue; continue;
} }
unset($opt['type']); unset($opt['type']);
if (sizeof($opt) == 1) { if (sizeof($opt) == 1) {
$opt = array_pop($opt); $opt = array_pop($opt);
} }
$valid[$var_name] = call_user_func(array($class, $method), $data[$var_name], $opt); $valid[$var_name] = call_user_func(array($class, $method),
$data[$var_name], $opt);
} else { } else {
trigger_error("Invalid validation type {$opt['type']}", E_USER_WARNING); trigger_error("Invalid validation type {$opt['type']}",
E_USER_WARNING);
} }
} }
return $valid; return $valid;