diff --git a/.gitignore b/.gitignore index 218ee79d0d..52dc0bdab1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ !.gitmodule composer.phar -/vendor/ +/data/vendor/ *.cache *.log /data/config/config.php diff --git a/.travis.yml b/.travis.yml index 7b7c7cedc1..a79b85d7de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,24 +26,25 @@ before_script: - if [[ $TRAVIS_PHP_VERSION == '5.3.3' ]]; then composer install --dev --no-interaction --prefer-source ; fi - if [[ $TRAVIS_PHP_VERSION != '5.3.3' ]]; then composer install --dev --no-interaction ; fi - sh -c "if [ '$DB' = 'mysql' ]; then sh ./eccube_install.sh mysql; fi" - - sh -c "if [ '$DB' = 'pgsql' ]; then sh ./eccube_install.sh pgsql; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then sh ./eccube_install.sh appveyor; fi" - cp tests/require.php.jenkins tests/require.php - cat ./data/config/config.php - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - php -S localhost:8085 -t html/ & - - php vendor/bin/codecept build + - php data/vendor/bin/codecept build script: - mkdir -p reports/coverage - - php vendor/bin/phpunit -c phpunit.xml.dist - - php vendor/bin/codecept run --env travis --steps + - php data/vendor/bin/phpunit -c phpunit.xml.dist + - php data/vendor/bin/codecept run --env travis --steps after_script: - - php vendor/bin/coveralls -v + - php data/vendor/bin/coveralls -v + - cat ./data/logs/error.log # Cache folder, you can delete cache from Travis CI web interface cache: directories: - - vendor + - data/vendor - $HOME/.composer/cache vendor/ diff --git a/README.md b/README.md index 2077f73050..f5ba39f4fd 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,46 @@ -# EC-CUBE 2.13系 +# EC-CUBE 2.13系 / 2.17系(開発中) [![Build Status](https://travis-ci.org/EC-CUBE/eccube-2_13.svg)](https://travis-ci.org/EC-CUBE/eccube-2_13) [![Coverage Status](https://coveralls.io/repos/EC-CUBE/eccube-2_13/badge.png)](https://coveralls.io/r/EC-CUBE/eccube-2_13) -* * * * * * * * * * * * * * * * * * * * +--- -=========== - -### EC-CUBE Trac について +## EC-CUBE Trac について EC-CUBE 2.13系については、2014年10月以前に利用されていた、[EC-CUBE Trac](http://svn.ec-cube.net/open_trac/) と[SVN](http://svn.ec-cube.net/open/)がございますので、合わせてご参照ください。 -新規のご投稿やコミットはいただけませんが、GitHubにまだ移されていない不具合の情報や過去の経緯などが御確認いただけます。 +新規のご投稿やコミットはいただけませんが、GitHubに移されていない不具合の情報や過去の経緯などをご確認いただけます。 -EC-CUBE Trac にある議論の再開や不具合の修正についても、GitHubにIssueを起票しなおしていただいたり、Pull Requestをいただけますと幸いです。 +EC-CUBE Trac にある議論の再開や不具合の修正についても、GitHubにIssueを再作成していただいたり、Pull requestをいただけますと幸いです。 -### 開発協力 +## 開発協力 コードの提供・追加、修正・変更その他「EC-CUBE」への開発の御協力(以下「コミット」といいます)を行っていただく場合には、 [EC-CUBEのコピーライトポリシー](https://github.com/EC-CUBE/ec-cube/blob/50de4ac511ab5a5577c046b61754d98be96aa328/LICENSE.txt)をご理解いただき、ご了承いただく必要がございます。 -pull requestを送信する際は、EC-CUBEのコピーライトポリシーに同意したものとみなします。 +Pull requestを送信する際は、EC-CUBEのコピーライトポリシーに同意したものとみなします。 + +## 開発方針 + +本リポジトリでは、以下方針で開発を行っています。 + +### 2.13系 + +* 保守と不具合修正を行います。 +* 修正時は `master` に対してPull requestを作成してください。 + +### 2.17系(開発中) + +* EC-CUBE 2.13系に対して、PHP7対応を行うバージョンです。 +* ブランチ `improve/php7` で開発を行っています。 +修正時は `improve/php7` に対してPull requestを作成してください。 +* 2.17系に関連するIssueについては、[マイルストーン 2.17.0](https://github.com/EC-CUBE/eccube-2_13/milestone/5)を参照してください。 + +##### 2.17系 システム要件の変更 -### 開発方針 +動作にはPHP5.4以降が必要になります。 -本リポジトリでは、以下の対応を開発方針として定めます。 +##### 2.17系 インストールについて -* EC-CUBE2.13系の保守 -* 不具合修正 +Composerを導入に伴い、clone後に`composer install`の実行が必要です。 -上記に含まれない新規機能開発や構造の変化を伴う修正等については、 -[EC-CUBE/ec-cube](https://github.com/EC-CUBE/ec-cube)にて開発を行っております。 +--- +上記に含まれない新規機能開発や構造の変化を伴う修正等については、[EC-CUBE/ec-cube](https://github.com/EC-CUBE/ec-cube)にて開発を行っております。 diff --git a/composer.json b/composer.json index 64e7056f5e..8f5c1e9c29 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "config": { "disable-tls": true, "secure-http": false, + "vendor-dir": "data/vendor", "platform": { "php": "5.4" } @@ -32,23 +33,18 @@ "pear-pear.php.net/PEAR" : "*", "pear-pear.php.net/Archive_Tar" : "*", "pear-pear.php.net/Mail" : "*", - "pear-pear.php.net/Calendar" : "*", "pear-pear.php.net/Cache_Lite" : "*", "pear-pear.php.net/File_SearchReplace" : "*", - "pear-pear.php.net/HTTP_Request" : "*", "pear-pear.php.net/MDB2_Driver_mysqli" : "1.5.0b4", "pear-pear.php.net/MDB2_Driver_pgsql" : "1.5.0b4", "pear-pear.php.net/MDB2" : "2.5.0-beta5 as 2.5.0", - "pear-pear.php.net/Net_SMTP" : "*", - "pear-pear.php.net/Net_Socket" : "*", - "pear-pear.php.net/Net_URL" : "*", "pear-pear.php.net/Net_UserAgent_Mobile" : "*", - "pear-pear.php.net/SOAP" : "*", "pear-pear.php.net/Services_JSON" : "*", "pear-pear.php.net/Text_Password" : "*", "pear-pear.php.net/XML_Parser" : "*", "pear-pear.php.net/XML_Serializer" : "*", - "pear-pear.php.net/XML_Util" : "*" + "pear-pear.php.net/XML_Util" : "*", + "mobiledetect/mobiledetectlib": "^2.8" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock index 6fe5abb51f..5e40b68e48 100644 --- a/composer.lock +++ b/composer.lock @@ -4,52 +4,74 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "f426e51cd01ae4e2e02879aad4522883", + "content-hash": "c89ab5c445e872cee2577039bbb3a8cd", "packages": [ { - "name": "pear-pear.php.net/Archive_Tar", - "version": "1.4.2", + "name": "mobiledetect/mobiledetectlib", + "version": "2.8.26", + "source": { + "type": "git", + "url": "https://github.com/serbanghita/Mobile-Detect.git", + "reference": "a0ed86c9d7c04ae27fa6418b55e3beb04dfe3297" + }, "dist": { - "type": "file", - "url": "http://pear.php.net/get/Archive_Tar-1.4.2.tgz", - "reference": null, - "shasum": null + "type": "zip", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/a0ed86c9d7c04ae27fa6418b55e3beb04dfe3297", + "reference": "a0ed86c9d7c04ae27fa6418b55e3beb04dfe3297", + "shasum": "" }, "require": { - "php": ">=5.2.0.0" + "php": ">=5.0.0" }, - "replace": { - "pear-pear/archive_tar": "== 1.4.2.0" + "require-dev": { + "phpunit/phpunit": "*" }, - "type": "pear-library", + "type": "library", "autoload": { "classmap": [ - "" - ] + "Mobile_Detect.php" + ], + "psr-0": { + "Detection": "namespaced/" + } }, - "include-path": [ - "/" - ], + "notification-url": "https://packagist.org/downloads/", "license": [ - "New BSD License" + "MIT" ], - "description": "This class provides handling of tar files in PHP.\nIt supports creating, listing, extracting and adding to tar files.\nGzip support is available if PHP has the zlib extension built-in or\nloaded. Bz2 compression is also supported with the bz2 extension loaded." + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "http://mobiledetect.net", + "role": "Developer" + } + ], + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "keywords": [ + "detect mobile devices", + "mobile", + "mobile detect", + "mobile detector", + "php mobile detect" + ], + "time": "2017-08-29T18:23:54+00:00" }, { - "name": "pear-pear.php.net/Cache_Lite", - "version": "1.8.0", + "name": "pear-pear.php.net/Archive_Tar", + "version": "1.4.3", "dist": { "type": "file", - "url": "http://pear.php.net/get/Cache_Lite-1.8.0.tgz", + "url": "http://pear.php.net/get/Archive_Tar-1.4.3.tgz", "reference": null, "shasum": null }, "require": { - "pear-pear.php.net/pear": ">=1.10.1.0", - "php": ">=5.4.0.0" + "php": ">=5.2.0.0" }, "replace": { - "pear-pear/cache_lite": "== 1.8.0.0" + "pear-pear/archive_tar": "== 1.4.3.0" }, "type": "pear-library", "autoload": { @@ -61,24 +83,25 @@ "/" ], "license": [ - "lgpl" + "New BSD License" ], - "description": "This package is a little cache system optimized for file containers. It is fast and safe (because it\n uses file locking and/or anti-corruption tests)." + "description": "This class provides handling of tar files in PHP.\nIt supports creating, listing, extracting and adding to tar files.\nGzip support is available if PHP has the zlib extension built-in or\nloaded. Bz2 compression is also supported with the bz2 extension loaded." }, { - "name": "pear-pear.php.net/Calendar", - "version": "0.5.5", + "name": "pear-pear.php.net/Cache_Lite", + "version": "1.8.0", "dist": { "type": "file", - "url": "http://pear.php.net/get/Calendar-0.5.5.tgz", + "url": "http://pear.php.net/get/Cache_Lite-1.8.0.tgz", "reference": null, "shasum": null }, "require": { - "php": ">=5.0.0.0" + "pear-pear.php.net/pear": ">=1.10.1.0", + "php": ">=5.4.0.0" }, "replace": { - "pear-pear/calendar": "== 0.5.5.0" + "pear-pear/cache_lite": "== 1.8.0.0" }, "type": "pear-library", "autoload": { @@ -90,9 +113,9 @@ "/" ], "license": [ - "BSD" + "lgpl" ], - "description": "Calendar provides an API for building Calendar data structures. Using\nthe simple iterator and it's "query" API, a user interface can easily be\nbuilt on top of the calendar data structure, at the same time easily connecting it\nto some kind of underlying data store, where "event" information is\nbeing held.\n\nIt provides different calculation "engines" the default being based on\nUnix timestamps (offering fastest performance) with an alternative using PEAR::Date\nwhich extends the calendar past the limitations of Unix timestamps. Other engines\nshould be implementable for other types of calendar (e.g. a Chinese Calendar based\non lunar cycles)." + "description": "This package is a little cache system optimized for file containers. It is fast and safe (because it\n uses file locking and/or anti-corruption tests)." }, { "name": "pear-pear.php.net/Console_Getopt", @@ -152,37 +175,6 @@ ], "description": "Provides various functions to perform replace\non files. Preg/Ereg regex supported along with faster, but more basic str_replace routine." }, - { - "name": "pear-pear.php.net/HTTP_Request", - "version": "1.4.4", - "dist": { - "type": "file", - "url": "http://pear.php.net/get/HTTP_Request-1.4.4.tgz", - "reference": null, - "shasum": null - }, - "require": { - "pear-pear.php.net/net_socket": ">=1.0.7.0", - "pear-pear.php.net/net_url": ">=1.0.12.0", - "php": ">=4.2.0.0" - }, - "replace": { - "pear-pear/http_request": "== 1.4.4.0" - }, - "type": "pear-library", - "autoload": { - "classmap": [ - "" - ] - }, - "include-path": [ - "/" - ], - "license": [ - "BSD" - ], - "description": "Supports GET/POST/HEAD/TRACE/PUT/DELETE, Basic authentication, Proxy,\nProxy Authentication, SSL, file uploads etc." - }, { "name": "pear-pear.php.net/MDB2", "version": "2.5.0b5", @@ -317,94 +309,6 @@ ], "description": "PEAR's Mail package defines an interface for implementing mailers under the PEAR hierarchy. It also provides supporting functions useful to multiple mailer backends. Currently supported backends include: PHP's native mail() function, sendmail, and SMTP. This package also provides a RFC822 email address list validation utility class." }, - { - "name": "pear-pear.php.net/Net_SMTP", - "version": "1.8.0", - "dist": { - "type": "file", - "url": "http://pear.php.net/get/Net_SMTP-1.8.0.tgz", - "reference": null, - "shasum": null - }, - "require": { - "pear-pear.php.net/net_socket": ">=1.0.7.0", - "php": ">=5.4.0.0" - }, - "replace": { - "pear-pear/net_smtp": "== 1.8.0.0" - }, - "type": "pear-library", - "autoload": { - "classmap": [ - "" - ] - }, - "include-path": [ - "/" - ], - "license": [ - "PHP License" - ], - "description": "Provides an implementation of the SMTP protocol using PEAR's Net_Socket class." - }, - { - "name": "pear-pear.php.net/Net_Socket", - "version": "1.2.2", - "dist": { - "type": "file", - "url": "http://pear.php.net/get/Net_Socket-1.2.2.tgz", - "reference": null, - "shasum": null - }, - "require": { - "php": ">=5.4.0.0" - }, - "replace": { - "pear-pear/net_socket": "== 1.2.2.0" - }, - "type": "pear-library", - "autoload": { - "classmap": [ - "" - ] - }, - "include-path": [ - "/" - ], - "license": [ - "BSD-2-Clause" - ], - "description": "Net_Socket is a class interface to TCP sockets. It provides blocking\n and non-blocking operation, with different reading and writing modes\n (byte-wise, block-wise, line-wise and special formats like network\n byte-order ip addresses)." - }, - { - "name": "pear-pear.php.net/Net_URL", - "version": "1.0.15", - "dist": { - "type": "file", - "url": "http://pear.php.net/get/Net_URL-1.0.15.tgz", - "reference": null, - "shasum": null - }, - "require": { - "php": ">=4.0.0.0" - }, - "replace": { - "pear-pear/net_url": "== 1.0.15.0" - }, - "type": "pear-library", - "autoload": { - "classmap": [ - "" - ] - }, - "include-path": [ - "/" - ], - "license": [ - "BSD" - ], - "description": "Provides easy parsing of URLs and their constituent parts." - }, { "name": "pear-pear.php.net/Net_UserAgent_Mobile", "version": "1.0.0", @@ -438,10 +342,10 @@ }, { "name": "pear-pear.php.net/PEAR", - "version": "1.10.4", + "version": "1.10.5", "dist": { "type": "file", - "url": "http://pear.php.net/get/PEAR-1.10.4.tgz", + "url": "http://pear.php.net/get/PEAR-1.10.5.tgz", "reference": null, "shasum": null }, @@ -459,7 +363,7 @@ "pear-pear.php.net/pear_frontend_web": "<=0.4.0.0" }, "replace": { - "pear-pear/pear": "== 1.10.4.0" + "pear-pear/pear": "== 1.10.5.0" }, "type": "pear-library", "autoload": { @@ -475,37 +379,6 @@ ], "description": "The PEAR package contains:\n * the PEAR installer, for creating, distributing\n and installing packages\n * the PEAR_Exception PHP5 error handling mechanism\n * the PEAR_ErrorStack advanced error handling mechanism\n * the PEAR_Error error handling mechanism\n * the OS_Guess class for retrieving info about the OS\n where PHP is running on\n * the System class for quick handling of common operations\n with files and directories\n * the PEAR base class\n Features in a nutshell:\n * full support for channels\n * pre-download dependency validation\n * new package.xml 2.0 format allows tremendous flexibility while maintaining BC\n * support for optional dependency groups and limited support for sub-packaging\n * robust dependency support\n * full dependency validation on uninstall\n * remote install for hosts with only ftp access - no more problems with\n restricted host installation\n * full support for mirroring\n * support for bundling several packages into a single tarball\n * support for static dependencies on a url-based package\n * support for custom file roles and installation tasks" }, - { - "name": "pear-pear.php.net/SOAP", - "version": "0.13.0", - "dist": { - "type": "file", - "url": "http://pear.php.net/get/SOAP-0.13.0.tgz", - "reference": null, - "shasum": null - }, - "require": { - "pear-pear.php.net/http_request": "*", - "pear-pear.php.net/pear": "*", - "php": ">=5.0.0.0" - }, - "replace": { - "pear-pear/soap": "== 0.13.0.0" - }, - "type": "pear-library", - "autoload": { - "classmap": [ - "" - ] - }, - "include-path": [ - "/" - ], - "license": [ - "PHP License" - ], - "description": "Implementation of SOAP protocol and services" - }, { "name": "pear-pear.php.net/Services_JSON", "version": "1.0.3", @@ -658,10 +531,10 @@ }, { "name": "pear-pear.php.net/XML_Util", - "version": "1.4.2", + "version": "1.4.3", "dist": { "type": "file", - "url": "http://pear.php.net/get/XML_Util-1.4.2.tgz", + "url": "http://pear.php.net/get/XML_Util-1.4.3.tgz", "reference": null, "shasum": null }, @@ -670,7 +543,7 @@ "php": ">=5.4.0.0" }, "replace": { - "pear-pear/xml_util": "== 1.4.2.0" + "pear-pear/xml_util": "== 1.4.3.0" }, "type": "pear-library", "autoload": { @@ -802,28 +675,28 @@ }, { "name": "codeception/codeception", - "version": "2.2.11", + "version": "2.3.5", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "a8681b416921ae282ccca2c485d75a3ed6756080" + "reference": "e807cd458eb9f7ae7464f33ad835a2f54aa73194" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/a8681b416921ae282ccca2c485d75a3ed6756080", - "reference": "a8681b416921ae282ccca2c485d75a3ed6756080", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/e807cd458eb9f7ae7464f33ad835a2f54aa73194", + "reference": "e807cd458eb9f7ae7464f33ad835a2f54aa73194", "shasum": "" }, "require": { "behat/gherkin": "~4.4.0", "ext-json": "*", "ext-mbstring": "*", - "facebook/webdriver": ">=1.0.1 <2.0", + "facebook/webdriver": ">=1.1.3 <2.0", "guzzlehttp/guzzle": ">=4.1.4 <7.0", "guzzlehttp/psr7": "~1.0", "php": ">=5.4.0 <8.0", "phpunit/php-code-coverage": ">=2.2.4 <6.0", - "phpunit/phpunit": ">4.8.20 <6.0", + "phpunit/phpunit": ">4.8.20 <7.0", "phpunit/phpunit-mock-objects": ">2.3 <5.0", "sebastian/comparator": ">1.1 <3.0", "sebastian/diff": "^1.4", @@ -848,6 +721,7 @@ "php-amqplib/php-amqplib": "~2.4", "predis/predis": "^1.0", "squizlabs/php_codesniffer": "~2.0", + "symfony/process": ">=2.7 <4.0", "vlucas/phpdotenv": "^2.4.0" }, "suggest": { @@ -892,7 +766,7 @@ "functional testing", "unit testing" ], - "time": "2017-05-11T21:07:05+00:00" + "time": "2017-08-10T20:28:02+00:00" }, { "name": "doctrine/instantiator", @@ -1310,16 +1184,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "shasum": "" }, "require": { @@ -1355,26 +1229,26 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03T12:10:50+00:00" + "time": "2016-01-25T08:17:30+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.7.0", + "version": "v1.7.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", "sebastian/comparator": "^1.1|^2.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, @@ -1385,7 +1259,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.7.x-dev" } }, "autoload": { @@ -1418,7 +1292,7 @@ "spy", "stub" ], - "time": "2017-03-02T20:05:34+00:00" + "time": "2017-09-04T11:05:03+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1670,16 +1544,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.35", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -1738,7 +1612,7 @@ "testing", "xunit" ], - "time": "2017-02-06T05:18:07+00:00" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -2068,23 +1942,23 @@ }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { @@ -2116,7 +1990,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", @@ -2421,16 +2295,16 @@ }, { "name": "symfony/browser-kit", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "4386755566fc8d29bddf89694663b0e96cb01e61" + "reference": "50cf5bfff540325d81ca2f2dc75ac2a5e446090d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/4386755566fc8d29bddf89694663b0e96cb01e61", - "reference": "4386755566fc8d29bddf89694663b0e96cb01e61", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/50cf5bfff540325d81ca2f2dc75ac2a5e446090d", + "reference": "50cf5bfff540325d81ca2f2dc75ac2a5e446090d", "shasum": "" }, "require": { @@ -2474,11 +2348,11 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-04-12T14:07:15+00:00" + "time": "2017-07-12T12:59:33+00:00" }, { "name": "symfony/config", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -2534,16 +2408,16 @@ }, { "name": "symfony/console", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e" + "reference": "c0807a2ca978e64d8945d373a9221a5c35d1a253" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e", - "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e", + "url": "https://api.github.com/repos/symfony/console/zipball/c0807a2ca978e64d8945d373a9221a5c35d1a253", + "reference": "c0807a2ca978e64d8945d373a9221a5c35d1a253", "shasum": "" }, "require": { @@ -2591,11 +2465,11 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-04-26T01:38:53+00:00" + "time": "2017-08-27T14:29:03+00:00" }, { "name": "symfony/css-selector", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -2648,16 +2522,16 @@ }, { "name": "symfony/debug", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "344f50ce827413b3640bfcb1e37386a67d06ea1f" + "reference": "efc9656dcb227e1459905d5aa51e43dfec76e752" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/344f50ce827413b3640bfcb1e37386a67d06ea1f", - "reference": "344f50ce827413b3640bfcb1e37386a67d06ea1f", + "url": "https://api.github.com/repos/symfony/debug/zipball/efc9656dcb227e1459905d5aa51e43dfec76e752", + "reference": "efc9656dcb227e1459905d5aa51e43dfec76e752", "shasum": "" }, "require": { @@ -2701,20 +2575,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-04-19T19:56:30+00:00" + "time": "2017-08-27T14:29:03+00:00" }, { "name": "symfony/dom-crawler", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "dd2fc76e011cb480b2d163c3b2deebd3de4471c8" + "reference": "2d902344b9902a0189408ab5d9e84fa4b233fcfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/dd2fc76e011cb480b2d163c3b2deebd3de4471c8", - "reference": "dd2fc76e011cb480b2d163c3b2deebd3de4471c8", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2d902344b9902a0189408ab5d9e84fa4b233fcfc", + "reference": "2d902344b9902a0189408ab5d9e84fa4b233fcfc", "shasum": "" }, "require": { @@ -2757,20 +2631,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-04-12T14:07:15+00:00" + "time": "2017-08-15T13:30:53+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "7fc8e2b4118ff316550596357325dfd92a51f531" + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fc8e2b4118ff316550596357325dfd92a51f531", - "reference": "7fc8e2b4118ff316550596357325dfd92a51f531", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1377400fd641d7d1935981546aaef780ecd5bf6d", + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d", "shasum": "" }, "require": { @@ -2817,20 +2691,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-04-26T16:56:54+00:00" + "time": "2017-06-02T07:47:27+00:00" }, { "name": "symfony/filesystem", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "dc40154e26a0116995e4f2f0c71cb9c2fe0775a3" + "reference": "714b1036010c354ae2b25d7f9ca27e14e265e9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/dc40154e26a0116995e4f2f0c71cb9c2fe0775a3", - "reference": "dc40154e26a0116995e4f2f0c71cb9c2fe0775a3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/714b1036010c354ae2b25d7f9ca27e14e265e9f2", + "reference": "714b1036010c354ae2b25d7f9ca27e14e265e9f2", "shasum": "" }, "require": { @@ -2866,20 +2740,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-04-12T14:07:15+00:00" + "time": "2017-07-11T07:12:11+00:00" }, { "name": "symfony/finder", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "16d55394b31547e4a8494551b85c9b9915545347" + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/16d55394b31547e4a8494551b85c9b9915545347", - "reference": "16d55394b31547e4a8494551b85c9b9915545347", + "url": "https://api.github.com/repos/symfony/finder/zipball/4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", "shasum": "" }, "require": { @@ -2915,20 +2789,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-04-12T14:07:15+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.3.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" + "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7c8fae0ac1d216eb54349e6a8baa57d515fe8803", + "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803", "shasum": "" }, "require": { @@ -2940,7 +2814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -2974,11 +2848,11 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-14T15:44:48+00:00" }, { "name": "symfony/stopwatch", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -3027,16 +2901,16 @@ }, { "name": "symfony/yaml", - "version": "v2.8.20", + "version": "v2.8.27", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02" + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/93ccdde79f4b079c7558da4656a3cb1c50c68e02", - "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", "shasum": "" }, "require": { @@ -3072,7 +2946,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-05-01T14:31:55+00:00" + "time": "2017-06-01T20:52:29+00:00" } ], "aliases": [ diff --git a/data/Smarty/templates/admin/products/product_class.tpl b/data/Smarty/templates/admin/products/product_class.tpl index caf1ba6ce8..fa1b9800e5 100644 --- a/data/Smarty/templates/admin/products/product_class.tpl +++ b/data/Smarty/templates/admin/products/product_class.tpl @@ -295,7 +295,7 @@ - + diff --git a/data/class/SC_Cache.php b/data/class/SC_Cache.php index 2be0cf4f48..73d2171078 100644 --- a/data/class/SC_Cache.php +++ b/data/class/SC_Cache.php @@ -21,8 +21,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -require DATA_REALDIR . 'module/Cache/Lite.php'; - /** * Cache controll using PEAR::Cache_Lite. */ diff --git a/data/class/SC_Product.php b/data/class/SC_Product.php index c5ea95f79e..d8a4e57274 100644 --- a/data/class/SC_Product.php +++ b/data/class/SC_Product.php @@ -38,9 +38,9 @@ class SC_Product public $classCategories = array(); public $stock_find; /** 規格1クラス名 */ - public $className1 = ''; + public $className1 = []; /** 規格2クラス名 */ - public $className2 = ''; + public $className2 = []; /** 規格1が設定されている */ public $classCat1_find; /** 規格2が設定されている */ @@ -404,10 +404,10 @@ public function getProductsClass($productClassId) // 税込計算 if (!SC_Utils_Ex::isBlank($arrProduct['price01'])) { - $arrProduct['price01_inctax'] = SC_Helper_TaxRule_Ex::sfCalcIncTax($arrProduct['price01'], $arrProduct['product_id'], $productClassId); + $arrProduct['price01_inctax'] = SC_Helper_TaxRule_Ex::sfCalcIncTax($arrProduct['price01'], $arrProduct['product_id'], $productClassId); } if (!SC_Utils_Ex::isBlank($arrProduct['price02'])) { - $arrProduct['price02_inctax'] = SC_Helper_TaxRule_Ex::sfCalcIncTax($arrProduct['price02'], $arrProduct['product_id'], $productClassId); + $arrProduct['price02_inctax'] = SC_Helper_TaxRule_Ex::sfCalcIncTax($arrProduct['price02'], $arrProduct['product_id'], $productClassId); } return $arrProduct; @@ -698,7 +698,8 @@ public function getProductDispConditions($tablename = null) * @param bool $include_hidden * @return array */ - public function getCategoryIds($product_id, $include_hidden = false) { + public function getCategoryIds($product_id, $include_hidden = false) + { if ($this->isValidProductId($product_id, $include_hidden)) { $objQuery =& SC_Query_Ex::getSingletonInstance(); $category_id = $objQuery->getCol('category_id', 'dtb_product_categories', 'product_id = ?', array($product_id)); @@ -718,7 +719,8 @@ public function getCategoryIds($product_id, $include_hidden = false) { * @param bool $include_deleted * @return bool */ - public function isValidProductId($product_id, $include_hidden = false, $include_deleted = false) { + public function isValidProductId($product_id, $include_hidden = false, $include_deleted = false) + { $where = ''; if (!$include_hidden) { $where .= 'status = 1'; diff --git a/data/class/SC_Query.php b/data/class/SC_Query.php index c9d0988362..11833dc152 100644 --- a/data/class/SC_Query.php +++ b/data/class/SC_Query.php @@ -1040,7 +1040,7 @@ public function execute(&$sth, $arrVal = array()) // #1658 (SC_Query の各種メソッドでプレースホルダの数に誤りがあるとメモリリークが発生する) 対応 // TODO 現状は PEAR 内のバックトレースを抑制することで、メモリーリークの影響を小さくしている。 // 根本的には、そのバックトレースが、どこに居座っているかを特定して、対策すべき。 - $pear_property =& PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); + $pear_property =& PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); $bak = $pear_property; $pear_property = true; diff --git a/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php b/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php index 1616e4bdea..7e2c5c9d9b 100644 --- a/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php +++ b/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php @@ -70,7 +70,8 @@ public function sfChangeMySQL($sql) $sql = $this->sfChangeTrunc($sql); // ARRAY_TO_STRINGをGROUP_CONCATに変換する $sql = $this->sfChangeArrayToString($sql); - + // rank に引用符をつける + $sql = $this->sfChangeReservedWords($sql); return $sql; } @@ -342,6 +343,15 @@ public function sfGetCreateIndexDefinition($table, $name, $definition) return $definition; } + /** + * 予約語に引用符を付与する. + */ + public function sfChangeReservedWords($sql) + { + $changesql = preg_replace('/(^|[^\w])RANK([^\w]|$)/i', '$1`RANK`$2', $sql); + return $changesql; + } + /** * 擬似表を表すSQL文(FROM 句)を取得する * @@ -360,7 +370,11 @@ public function getDummyFromClauseSql() */ public function initObjQuery(SC_Query &$objQuery) { - $objQuery->exec('SET SESSION storage_engine = InnoDB'); + if ($objQuery->conn->getConnection()->server_version >= 50705) { + $objQuery->exec('SET SESSION default_storage_engine = InnoDB'); + } else { + $objQuery->exec('SET SESSION storage_engine = InnoDB'); + } $objQuery->exec("SET SESSION sql_mode = 'ANSI'"); } } diff --git a/data/class/helper/SC_Helper_Customer.php b/data/class/helper/SC_Helper_Customer.php index 8eee97d78b..ef905a8605 100644 --- a/data/class/helper/SC_Helper_Customer.php +++ b/data/class/helper/SC_Helper_Customer.php @@ -248,7 +248,7 @@ public function sfGetCustomerData($customer_id, $mask_flg = true) // 誕生日を年月日に分ける if (isset($arrForm['birth'])) { $birth = explode(' ', $arrForm['birth']); - list($arrForm['year'], $arrForm['month'], $arrForm['day']) = explode('-', $birth[0]); + list($arrForm['year'], $arrForm['month'], $arrForm['day']) = array_map("intval",explode('-', $birth[0])); } if ($mask_flg) { diff --git a/data/class/pages/admin/basis/LC_Page_Admin_Basis_Tax.php b/data/class/pages/admin/basis/LC_Page_Admin_Basis_Tax.php index b3656fbf2b..2cf5c6bd6d 100644 --- a/data/class/pages/admin/basis/LC_Page_Admin_Basis_Tax.php +++ b/data/class/pages/admin/basis/LC_Page_Admin_Basis_Tax.php @@ -151,11 +151,11 @@ public function action() $TaxRule = $objTaxRule->getTaxRuleData($tax_rule_id); $tmp = explode(" ", $TaxRule['apply_date']); - $tmp_ymd = explode("-", $tmp[0]); + $tmp_ymd = array_map("intval",explode('-', $tmp[0])); $TaxRule['apply_date_year'] = $tmp_ymd[0]; $TaxRule['apply_date_month'] = $tmp_ymd[1]; $TaxRule['apply_date_day'] = $tmp_ymd[2]; - $tmp_hm = explode(":", $tmp[1]); + $tmp_hm = array_map("intval",explode(":", $tmp[1])); $TaxRule['apply_date_hour'] = $tmp_hm[0]; $TaxRule['apply_date_minutes'] = $tmp_hm[1]; diff --git a/data/class/pages/admin/contents/LC_Page_Admin_Contents.php b/data/class/pages/admin/contents/LC_Page_Admin_Contents.php index fef419d505..5a44c4e5fe 100644 --- a/data/class/pages/admin/contents/LC_Page_Admin_Contents.php +++ b/data/class/pages/admin/contents/LC_Page_Admin_Contents.php @@ -240,7 +240,7 @@ public function checkLinkMethod($link_method) */ public function splitNewsDate($news_date) { - return explode('-', $news_date); + return array_map("intval",explode('-', $news_date)); } /** diff --git a/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php b/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php index 139164e666..f423c4844f 100644 --- a/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php +++ b/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php @@ -150,18 +150,17 @@ public function lfRenumber($parent_category_id) rank = ( SELECT COUNT(*) - FROM dtb_product_categories t_in - WHERE t_in.category_id = dtb_product_categories.category_id - AND ( - t_in.rank < dtb_product_categories.rank - OR ( - t_in.rank = dtb_product_categories.rank - AND t_in.product_id < dtb_product_categories.product_id - ) + FROM (SELECT product_id,rank FROM dtb_product_categories WHERE category_id = dtb_product_categories.category_id) t_in + WHERE + t_in.rank < dtb_product_categories.rank + OR ( + t_in.rank = dtb_product_categories.rank + AND t_in.product_id < dtb_product_categories.product_id ) ) + 1 WHERE dtb_product_categories.category_id = ? __EOS__; + $arrRet = $objQuery->query($sql, array($parent_category_id)); return $arrRet; diff --git a/data/class/pages/admin/total/LC_Page_Admin_Total.php b/data/class/pages/admin/total/LC_Page_Admin_Total.php index 66cf51dc9d..dd2da5f190 100644 --- a/data/class/pages/admin/total/LC_Page_Admin_Total.php +++ b/data/class/pages/admin/total/LC_Page_Admin_Total.php @@ -486,7 +486,7 @@ public function lfGetGraphPng($keyname) /** * @param string $col_date */ - public function lfGetWhereMember($col_date, $sdate, $edate, $type, $col_member = 'customer_id') + public function lfGetWhereMember($col_date, $sdate, $edate, $type = NULL, $col_member = 'customer_id') { $where = ''; // 取得日付の指定 diff --git a/data/module/Archive/Tar.php b/data/module/Archive/Tar.php deleted file mode 100644 index 570b39c05f..0000000000 --- a/data/module/Archive/Tar.php +++ /dev/null @@ -1,2422 +0,0 @@ - - * 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. - * - * 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 File_Formats - * @package Archive_Tar - * @author Vincent Blavet - * @copyright 1997-2010 The Authors - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Archive_Tar - */ - -require_once 'PEAR.php'; - -define('ARCHIVE_TAR_ATT_SEPARATOR', 90001); -define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); - -if (!function_exists('gzopen') && function_exists('gzopen64')) { - function gzopen($filename, $mode, $use_include_path = 0) - { - gzopen64($filename, $mode, $use_include_path); - } -} - -if (!function_exists('gztell') && function_exists('gztell64')) { - function gztell($zp) - { - gztell64($zp); - } -} - -if (!function_exists('gzseek') && function_exists('gzseek64')) { - function gzseek($zp, $offset, $whence = SEEK_SET) - { - gzseek64($zp, $offset, $whence); - } -} - -/** - * Creates a (compressed) Tar archive - * - * @package Archive_Tar - * @author Vincent Blavet - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version $Revision$ - */ -class Archive_Tar extends PEAR -{ - /** - * @var string Name of the Tar - */ - var $_tarname = ''; - - /** - * @var boolean if true, the Tar file will be gzipped - */ - var $_compress = false; - - /** - * @var string Type of compression : 'none', 'gz', 'bz2' or 'lzma2' - */ - var $_compress_type = 'none'; - - /** - * @var string Explode separator - */ - var $_separator = ' '; - - /** - * @var file descriptor - */ - var $_file = 0; - - /** - * @var string Local Tar name of a remote Tar (http:// or ftp://) - */ - var $_temp_tarname = ''; - - /** - * @var string regular expression for ignoring files or directories - */ - var $_ignore_regexp = ''; - - /** - * @var object PEAR_Error object - */ - var $error_object = null; - - // {{{ constructor - /** - * Archive_Tar Class constructor. This flavour of the constructor only - * declare a new Archive_Tar object, identifying it by the name of the - * tar file. - * If the compress argument is set the tar will be read or created as a - * gzip or bz2 compressed TAR file. - * - * @param string $p_tarname The name of the tar archive to create - * @param string $p_compress can be null, 'gz', 'bz2' or 'lzma2'. This - * parameter indicates if gzip, bz2 or lzma2 compression - * is required. For compatibility reason the - * boolean value 'true' means 'gz'. - * - * @access public - */ - function Archive_Tar($p_tarname, $p_compress = null) - { - if (version_compare(PHP_VERSION, '5.0.0', '<')) { - $this->PEAR(); - } - $this->_compress = false; - $this->_compress_type = 'none'; - if (($p_compress === null) || ($p_compress == '')) { - if (@file_exists($p_tarname)) { - if ($fp = @fopen($p_tarname, "rb")) { - // look for gzip magic cookie - $data = fread($fp, 2); - fclose($fp); - if ($data == "\37\213") { - $this->_compress = true; - $this->_compress_type = 'gz'; - // No sure it's enought for a magic code .... - } elseif ($data == "BZ") { - $this->_compress = true; - $this->_compress_type = 'bz2'; - } elseif (file_get_contents($p_tarname, false, null, 1, 4) == '7zXZ') { - $this->_compress = true; - $this->_compress_type = 'lzma2'; - } - } - } else { - // probably a remote file or some file accessible - // through a stream interface - if (substr($p_tarname, -2) == 'gz') { - $this->_compress = true; - $this->_compress_type = 'gz'; - } elseif ((substr($p_tarname, -3) == 'bz2') || - (substr($p_tarname, -2) == 'bz') - ) { - $this->_compress = true; - $this->_compress_type = 'bz2'; - } else { - if (substr($p_tarname, -2) == 'xz') { - $this->_compress = true; - $this->_compress_type = 'lzma2'; - } - } - } - } else { - if (($p_compress === true) || ($p_compress == 'gz')) { - $this->_compress = true; - $this->_compress_type = 'gz'; - } else { - if ($p_compress == 'bz2') { - $this->_compress = true; - $this->_compress_type = 'bz2'; - } else { - if ($p_compress == 'lzma2') { - $this->_compress = true; - $this->_compress_type = 'lzma2'; - } else { - $this->_error( - "Unsupported compression type '$p_compress'\n" . - "Supported types are 'gz', 'bz2' and 'lzma2'.\n" - ); - return false; - } - } - } - } - $this->_tarname = $p_tarname; - if ($this->_compress) { // assert zlib or bz2 or xz extension support - if ($this->_compress_type == 'gz') { - $extname = 'zlib'; - } else { - if ($this->_compress_type == 'bz2') { - $extname = 'bz2'; - } else { - if ($this->_compress_type == 'lzma2') { - $extname = 'xz'; - } - } - } - - if (!extension_loaded($extname)) { - PEAR::loadExtension($extname); - } - if (!extension_loaded($extname)) { - $this->_error( - "The extension '$extname' couldn't be found.\n" . - "Please make sure your version of PHP was built " . - "with '$extname' support.\n" - ); - return false; - } - } - } - - // }}} - - // {{{ destructor - function _Archive_Tar() - { - $this->_close(); - // ----- Look for a local copy to delete - if ($this->_temp_tarname != '') { - @unlink($this->_temp_tarname); - } - $this->_PEAR(); - } - - // }}} - - // {{{ PHP5-compatible destructor - function __destruct() - { - $this->_Archive_Tar(); - } - - // }}} - - // {{{ create() - /** - * This method creates the archive file and add the files / directories - * that are listed in $p_filelist. - * If a file with the same name exist and is writable, it is replaced - * by the new tar. - * The method return false and a PEAR error text. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * For each directory added in the archive, the files and - * sub-directories are also added. - * See also createModify() method for more details. - * - * @param array $p_filelist An array of filenames and directory names, or a - * single string with names separated by a single - * blank space. - * - * @return true on success, false on error. - * @see createModify() - * @access public - */ - function create($p_filelist) - { - return $this->createModify($p_filelist, '', ''); - } - - // }}} - - // {{{ add() - /** - * This method add the files / directories that are listed in $p_filelist in - * the archive. If the archive does not exist it is created. - * The method return false and a PEAR error text. - * The files and directories listed are only added at the end of the archive, - * even if a file with the same name is already archived. - * See also createModify() method for more details. - * - * @param array $p_filelist An array of filenames and directory names, or a - * single string with names separated by a single - * blank space. - * - * @return true on success, false on error. - * @see createModify() - * @access public - */ - function add($p_filelist) - { - return $this->addModify($p_filelist, '', ''); - } - - // }}} - - // {{{ extract() - function extract($p_path = '', $p_preserve = false) - { - return $this->extractModify($p_path, '', $p_preserve); - } - - // }}} - - // {{{ listContent() - function listContent() - { - $v_list_detail = array(); - - if ($this->_openRead()) { - if (!$this->_extractList('', $v_list_detail, "list", '', '')) { - unset($v_list_detail); - $v_list_detail = 0; - } - $this->_close(); - } - - return $v_list_detail; - } - - // }}} - - // {{{ createModify() - /** - * This method creates the archive file and add the files / directories - * that are listed in $p_filelist. - * If the file already exists and is writable, it is replaced by the - * new tar. It is a create and not an add. If the file exists and is - * read-only or is a directory it is not replaced. The method return - * false and a PEAR error text. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * The path indicated in $p_remove_dir will be removed from the - * memorized path of each file / directory listed when this path - * exists. By default nothing is removed (empty path '') - * The path indicated in $p_add_dir will be added at the beginning of - * the memorized path of each file / directory listed. However it can - * be set to empty ''. The adding of a path is done after the removing - * of path. - * The path add/remove ability enables the user to prepare an archive - * for extraction in a different path than the origin files are. - * See also addModify() method for file adding properties. - * - * @param array $p_filelist An array of filenames and directory names, - * or a single string with names separated by - * a single blank space. - * @param string $p_add_dir A string which contains a path to be added - * to the memorized path of each element in - * the list. - * @param string $p_remove_dir A string which contains a path to be - * removed from the memorized path of each - * element in the list, when relevant. - * - * @return boolean true on success, false on error. - * @access public - * @see addModify() - */ - function createModify($p_filelist, $p_add_dir, $p_remove_dir = '') - { - $v_result = true; - - if (!$this->_openWrite()) { - return false; - } - - if ($p_filelist != '') { - if (is_array($p_filelist)) { - $v_list = $p_filelist; - } elseif (is_string($p_filelist)) { - $v_list = explode($this->_separator, $p_filelist); - } else { - $this->_cleanFile(); - $this->_error('Invalid file list'); - return false; - } - - $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir); - } - - if ($v_result) { - $this->_writeFooter(); - $this->_close(); - } else { - $this->_cleanFile(); - } - - return $v_result; - } - - // }}} - - // {{{ addModify() - /** - * This method add the files / directories listed in $p_filelist at the - * end of the existing archive. If the archive does not yet exists it - * is created. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * The path indicated in $p_remove_dir will be removed from the - * memorized path of each file / directory listed when this path - * exists. By default nothing is removed (empty path '') - * The path indicated in $p_add_dir will be added at the beginning of - * the memorized path of each file / directory listed. However it can - * be set to empty ''. The adding of a path is done after the removing - * of path. - * The path add/remove ability enables the user to prepare an archive - * for extraction in a different path than the origin files are. - * If a file/dir is already in the archive it will only be added at the - * end of the archive. There is no update of the existing archived - * file/dir. However while extracting the archive, the last file will - * replace the first one. This results in a none optimization of the - * archive size. - * If a file/dir does not exist the file/dir is ignored. However an - * error text is send to PEAR error. - * If a file/dir is not readable the file/dir is ignored. However an - * error text is send to PEAR error. - * - * @param array $p_filelist An array of filenames and directory - * names, or a single string with names - * separated by a single blank space. - * @param string $p_add_dir A string which contains a path to be - * added to the memorized path of each - * element in the list. - * @param string $p_remove_dir A string which contains a path to be - * removed from the memorized path of - * each element in the list, when - * relevant. - * - * @return true on success, false on error. - * @access public - */ - function addModify($p_filelist, $p_add_dir, $p_remove_dir = '') - { - $v_result = true; - - if (!$this->_isArchive()) { - $v_result = $this->createModify( - $p_filelist, - $p_add_dir, - $p_remove_dir - ); - } else { - if (is_array($p_filelist)) { - $v_list = $p_filelist; - } elseif (is_string($p_filelist)) { - $v_list = explode($this->_separator, $p_filelist); - } else { - $this->_error('Invalid file list'); - return false; - } - - $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); - } - - return $v_result; - } - - // }}} - - // {{{ addString() - /** - * This method add a single string as a file at the - * end of the existing archive. If the archive does not yet exists it - * is created. - * - * @param string $p_filename A string which contains the full - * filename path that will be associated - * with the string. - * @param string $p_string The content of the file added in - * the archive. - * @param int $p_datetime A custom date/time (unix timestamp) - * for the file (optional). - * @param array $p_params An array of optional params: - * stamp => the datetime (replaces - * datetime above if it exists) - * mode => the permissions on the - * file (600 by default) - * type => is this a link? See the - * tar specification for details. - * (default = regular file) - * uid => the user ID of the file - * (default = 0 = root) - * gid => the group ID of the file - * (default = 0 = root) - * - * @return true on success, false on error. - * @access public - */ - function addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) - { - $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); - $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; - $p_type = @$p_params["type"] ? $p_params["type"] : ""; - $p_uid = @$p_params["uid"] ? $p_params["uid"] : ""; - $p_gid = @$p_params["gid"] ? $p_params["gid"] : ""; - $v_result = true; - - if (!$this->_isArchive()) { - if (!$this->_openWrite()) { - return false; - } - $this->_close(); - } - - if (!$this->_openAppend()) { - return false; - } - - // Need to check the get back to the temporary file ? .... - $v_result = $this->_addString($p_filename, $p_string, $p_datetime, $p_params); - - $this->_writeFooter(); - - $this->_close(); - - return $v_result; - } - - // }}} - - // {{{ extractModify() - /** - * This method extract all the content of the archive in the directory - * indicated by $p_path. When relevant the memorized path of the - * files/dir can be modified by removing the $p_remove_path path at the - * beginning of the file/dir path. - * While extracting a file, if the directory path does not exists it is - * created. - * While extracting a file, if the file already exists it is replaced - * without looking for last modification date. - * While extracting a file, if the file already exists and is write - * protected, the extraction is aborted. - * While extracting a file, if a directory with the same name already - * exists, the extraction is aborted. - * While extracting a directory, if a file with the same name already - * exists, the extraction is aborted. - * While extracting a file/directory if the destination directory exist - * and is write protected, or does not exist but can not be created, - * the extraction is aborted. - * If after extraction an extracted file does not show the correct - * stored file size, the extraction is aborted. - * When the extraction is aborted, a PEAR error text is set and false - * is returned. However the result can be a partial extraction that may - * need to be manually cleaned. - * - * @param string $p_path The path of the directory where the - * files/dir need to by extracted. - * @param string $p_remove_path Part of the memorized path that can be - * removed if present at the beginning of - * the file/dir path. - * @param boolean $p_preserve Preserve user/group ownership of files - * - * @return boolean true on success, false on error. - * @access public - * @see extractList() - */ - function extractModify($p_path, $p_remove_path, $p_preserve = false) - { - $v_result = true; - $v_list_detail = array(); - - if ($v_result = $this->_openRead()) { - $v_result = $this->_extractList( - $p_path, - $v_list_detail, - "complete", - 0, - $p_remove_path, - $p_preserve - ); - $this->_close(); - } - - return $v_result; - } - - // }}} - - // {{{ extractInString() - /** - * This method extract from the archive one file identified by $p_filename. - * The return value is a string with the file content, or NULL on error. - * - * @param string $p_filename The path of the file to extract in a string. - * - * @return a string with the file content or NULL. - * @access public - */ - function extractInString($p_filename) - { - if ($this->_openRead()) { - $v_result = $this->_extractInString($p_filename); - $this->_close(); - } else { - $v_result = null; - } - - return $v_result; - } - - // }}} - - // {{{ extractList() - /** - * This method extract from the archive only the files indicated in the - * $p_filelist. These files are extracted in the current directory or - * in the directory indicated by the optional $p_path parameter. - * If indicated the $p_remove_path can be used in the same way as it is - * used in extractModify() method. - * - * @param array $p_filelist An array of filenames and directory names, - * or a single string with names separated - * by a single blank space. - * @param string $p_path The path of the directory where the - * files/dir need to by extracted. - * @param string $p_remove_path Part of the memorized path that can be - * removed if present at the beginning of - * the file/dir path. - * @param boolean $p_preserve Preserve user/group ownership of files - * - * @return true on success, false on error. - * @access public - * @see extractModify() - */ - function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false) - { - $v_result = true; - $v_list_detail = array(); - - if (is_array($p_filelist)) { - $v_list = $p_filelist; - } elseif (is_string($p_filelist)) { - $v_list = explode($this->_separator, $p_filelist); - } else { - $this->_error('Invalid string list'); - return false; - } - - if ($v_result = $this->_openRead()) { - $v_result = $this->_extractList( - $p_path, - $v_list_detail, - "partial", - $v_list, - $p_remove_path, - $p_preserve - ); - $this->_close(); - } - - return $v_result; - } - - // }}} - - // {{{ setAttribute() - /** - * This method set specific attributes of the archive. It uses a variable - * list of parameters, in the format attribute code + attribute values : - * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); - * - * @param mixed $argv variable list of attributes and values - * - * @return true on success, false on error. - * @access public - */ - function setAttribute() - { - $v_result = true; - - // ----- Get the number of variable list of arguments - if (($v_size = func_num_args()) == 0) { - return true; - } - - // ----- Get the arguments - $v_att_list = & func_get_args(); - - // ----- Read the attributes - $i = 0; - while ($i < $v_size) { - - // ----- Look for next option - switch ($v_att_list[$i]) { - // ----- Look for options that request a string value - case ARCHIVE_TAR_ATT_SEPARATOR : - // ----- Check the number of parameters - if (($i + 1) >= $v_size) { - $this->_error( - 'Invalid number of parameters for ' - . 'attribute ARCHIVE_TAR_ATT_SEPARATOR' - ); - return false; - } - - // ----- Get the value - $this->_separator = $v_att_list[$i + 1]; - $i++; - break; - - default : - $this->_error('Unknow attribute code ' . $v_att_list[$i] . ''); - return false; - } - - // ----- Next attribute - $i++; - } - - return $v_result; - } - - // }}} - - // {{{ setIgnoreRegexp() - /** - * This method sets the regular expression for ignoring files and directories - * at import, for example: - * $arch->setIgnoreRegexp("#CVS|\.svn#"); - * - * @param string $regexp regular expression defining which files or directories to ignore - * - * @access public - */ - function setIgnoreRegexp($regexp) - { - $this->_ignore_regexp = $regexp; - } - - // }}} - - // {{{ setIgnoreList() - /** - * This method sets the regular expression for ignoring all files and directories - * matching the filenames in the array list at import, for example: - * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); - * - * @param array $list a list of file or directory names to ignore - * - * @access public - */ - function setIgnoreList($list) - { - $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); - $regexp = '#/' . join('$|/', $list) . '#'; - $this->setIgnoreRegexp($regexp); - } - - // }}} - - // {{{ _error() - function _error($p_message) - { - $this->error_object = & $this->raiseError($p_message); - } - - // }}} - - // {{{ _warning() - function _warning($p_message) - { - $this->error_object = & $this->raiseError($p_message); - } - - // }}} - - // {{{ _isArchive() - function _isArchive($p_filename = null) - { - if ($p_filename == null) { - $p_filename = $this->_tarname; - } - clearstatcache(); - return @is_file($p_filename) && !@is_link($p_filename); - } - - // }}} - - // {{{ _openWrite() - function _openWrite() - { - if ($this->_compress_type == 'gz' && function_exists('gzopen')) { - $this->_file = @gzopen($this->_tarname, "wb9"); - } else { - if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { - $this->_file = @bzopen($this->_tarname, "w"); - } else { - if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { - $this->_file = @xzopen($this->_tarname, 'w'); - } else { - if ($this->_compress_type == 'none') { - $this->_file = @fopen($this->_tarname, "wb"); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - return false; - } - } - } - } - - if ($this->_file == 0) { - $this->_error( - 'Unable to open in write mode \'' - . $this->_tarname . '\'' - ); - return false; - } - - return true; - } - - // }}} - - // {{{ _openRead() - function _openRead() - { - if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { - - // ----- Look if a local copy need to be done - if ($this->_temp_tarname == '') { - $this->_temp_tarname = uniqid('tar') . '.tmp'; - if (!$v_file_from = @fopen($this->_tarname, 'rb')) { - $this->_error( - 'Unable to open in read mode \'' - . $this->_tarname . '\'' - ); - $this->_temp_tarname = ''; - return false; - } - if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { - $this->_error( - 'Unable to open in write mode \'' - . $this->_temp_tarname . '\'' - ); - $this->_temp_tarname = ''; - return false; - } - while ($v_data = @fread($v_file_from, 1024)) { - @fwrite($v_file_to, $v_data); - } - @fclose($v_file_from); - @fclose($v_file_to); - } - - // ----- File to open if the local copy - $v_filename = $this->_temp_tarname; - - } else // ----- File to open if the normal Tar file - { - $v_filename = $this->_tarname; - } - - if ($this->_compress_type == 'gz' && function_exists('gzopen')) { - $this->_file = @gzopen($v_filename, "rb"); - } else { - if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { - $this->_file = @bzopen($v_filename, "r"); - } else { - if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { - $this->_file = @xzopen($v_filename, "r"); - } else { - if ($this->_compress_type == 'none') { - $this->_file = @fopen($v_filename, "rb"); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - return false; - } - } - } - } - - if ($this->_file == 0) { - $this->_error('Unable to open in read mode \'' . $v_filename . '\''); - return false; - } - - return true; - } - - // }}} - - // {{{ _openReadWrite() - function _openReadWrite() - { - if ($this->_compress_type == 'gz') { - $this->_file = @gzopen($this->_tarname, "r+b"); - } else { - if ($this->_compress_type == 'bz2') { - $this->_error( - 'Unable to open bz2 in read/write mode \'' - . $this->_tarname . '\' (limitation of bz2 extension)' - ); - return false; - } else { - if ($this->_compress_type == 'lzma2') { - $this->_error( - 'Unable to open lzma2 in read/write mode \'' - . $this->_tarname . '\' (limitation of lzma2 extension)' - ); - return false; - } else { - if ($this->_compress_type == 'none') { - $this->_file = @fopen($this->_tarname, "r+b"); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - return false; - } - } - } - } - - if ($this->_file == 0) { - $this->_error( - 'Unable to open in read/write mode \'' - . $this->_tarname . '\'' - ); - return false; - } - - return true; - } - - // }}} - - // {{{ _close() - function _close() - { - //if (isset($this->_file)) { - if (is_resource($this->_file)) { - if ($this->_compress_type == 'gz') { - @gzclose($this->_file); - } else { - if ($this->_compress_type == 'bz2') { - @bzclose($this->_file); - } else { - if ($this->_compress_type == 'lzma2') { - @xzclose($this->_file); - } else { - if ($this->_compress_type == 'none') { - @fclose($this->_file); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - } - } - } - } - - $this->_file = 0; - } - - // ----- Look if a local copy need to be erase - // Note that it might be interesting to keep the url for a time : ToDo - if ($this->_temp_tarname != '') { - @unlink($this->_temp_tarname); - $this->_temp_tarname = ''; - } - - return true; - } - - // }}} - - // {{{ _cleanFile() - function _cleanFile() - { - $this->_close(); - - // ----- Look for a local copy - if ($this->_temp_tarname != '') { - // ----- Remove the local copy but not the remote tarname - @unlink($this->_temp_tarname); - $this->_temp_tarname = ''; - } else { - // ----- Remove the local tarname file - @unlink($this->_tarname); - } - $this->_tarname = ''; - - return true; - } - - // }}} - - // {{{ _writeBlock() - function _writeBlock($p_binary_data, $p_len = null) - { - if (is_resource($this->_file)) { - if ($p_len === null) { - if ($this->_compress_type == 'gz') { - @gzputs($this->_file, $p_binary_data); - } else { - if ($this->_compress_type == 'bz2') { - @bzwrite($this->_file, $p_binary_data); - } else { - if ($this->_compress_type == 'lzma2') { - @xzwrite($this->_file, $p_binary_data); - } else { - if ($this->_compress_type == 'none') { - @fputs($this->_file, $p_binary_data); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - } - } - } - } - } else { - if ($this->_compress_type == 'gz') { - @gzputs($this->_file, $p_binary_data, $p_len); - } else { - if ($this->_compress_type == 'bz2') { - @bzwrite($this->_file, $p_binary_data, $p_len); - } else { - if ($this->_compress_type == 'lzma2') { - @xzwrite($this->_file, $p_binary_data, $p_len); - } else { - if ($this->_compress_type == 'none') { - @fputs($this->_file, $p_binary_data, $p_len); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - } - } - } - } - - } - } - return true; - } - - // }}} - - // {{{ _readBlock() - function _readBlock() - { - $v_block = null; - if (is_resource($this->_file)) { - if ($this->_compress_type == 'gz') { - $v_block = @gzread($this->_file, 512); - } else { - if ($this->_compress_type == 'bz2') { - $v_block = @bzread($this->_file, 512); - } else { - if ($this->_compress_type == 'lzma2') { - $v_block = @xzread($this->_file, 512); - } else { - if ($this->_compress_type == 'none') { - $v_block = @fread($this->_file, 512); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - } - } - } - } - } - return $v_block; - } - - // }}} - - // {{{ _jumpBlock() - function _jumpBlock($p_len = null) - { - if (is_resource($this->_file)) { - if ($p_len === null) { - $p_len = 1; - } - - if ($this->_compress_type == 'gz') { - @gzseek($this->_file, gztell($this->_file) + ($p_len * 512)); - } else { - if ($this->_compress_type == 'bz2') { - // ----- Replace missing bztell() and bzseek() - for ($i = 0; $i < $p_len; $i++) { - $this->_readBlock(); - } - } else { - if ($this->_compress_type == 'lzma2') { - // ----- Replace missing xztell() and xzseek() - for ($i = 0; $i < $p_len; $i++) { - $this->_readBlock(); - } - } else { - if ($this->_compress_type == 'none') { - @fseek($this->_file, $p_len * 512, SEEK_CUR); - } else { - $this->_error( - 'Unknown or missing compression type (' - . $this->_compress_type . ')' - ); - } - } - } - } - - } - return true; - } - - // }}} - - // {{{ _writeFooter() - function _writeFooter() - { - if (is_resource($this->_file)) { - // ----- Write the last 0 filled block for end of archive - $v_binary_data = pack('a1024', ''); - $this->_writeBlock($v_binary_data); - } - return true; - } - - // }}} - - // {{{ _addList() - function _addList($p_list, $p_add_dir, $p_remove_dir) - { - $v_result = true; - $v_header = array(); - - // ----- Remove potential windows directory separator - $p_add_dir = $this->_translateWinPath($p_add_dir); - $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); - - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } - - if (sizeof($p_list) == 0) { - return true; - } - - foreach ($p_list as $v_filename) { - if (!$v_result) { - break; - } - - // ----- Skip the current tar name - if ($v_filename == $this->_tarname) { - continue; - } - - if ($v_filename == '') { - continue; - } - - // ----- ignore files and directories matching the ignore regular expression - if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/' . $v_filename)) { - $this->_warning("File '$v_filename' ignored"); - continue; - } - - if (!file_exists($v_filename) && !is_link($v_filename)) { - $this->_warning("File '$v_filename' does not exist"); - continue; - } - - // ----- Add the file or directory header - if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) { - return false; - } - - if (@is_dir($v_filename) && !@is_link($v_filename)) { - if (!($p_hdir = opendir($v_filename))) { - $this->_warning("Directory '$v_filename' can not be read"); - continue; - } - while (false !== ($p_hitem = readdir($p_hdir))) { - if (($p_hitem != '.') && ($p_hitem != '..')) { - if ($v_filename != ".") { - $p_temp_list[0] = $v_filename . '/' . $p_hitem; - } else { - $p_temp_list[0] = $p_hitem; - } - - $v_result = $this->_addList( - $p_temp_list, - $p_add_dir, - $p_remove_dir - ); - } - } - - unset($p_temp_list); - unset($p_hdir); - unset($p_hitem); - } - } - - return $v_result; - } - - // }}} - - // {{{ _addFile() - function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename = null) - { - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } - - if ($p_filename == '') { - $this->_error('Invalid file name'); - return false; - } - - if (is_null($v_stored_filename)) { - // ----- Calculate the stored filename - $p_filename = $this->_translateWinPath($p_filename, false);; - $v_stored_filename = $p_filename; - - if (strcmp($p_filename, $p_remove_dir) == 0) { - return true; - } - - if ($p_remove_dir != '') { - if (substr($p_remove_dir, -1) != '/') { - $p_remove_dir .= '/'; - } - - if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) { - $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); - } - } - - $v_stored_filename = $this->_translateWinPath($v_stored_filename); - if ($p_add_dir != '') { - if (substr($p_add_dir, -1) == '/') { - $v_stored_filename = $p_add_dir . $v_stored_filename; - } else { - $v_stored_filename = $p_add_dir . '/' . $v_stored_filename; - } - } - - $v_stored_filename = $this->_pathReduction($v_stored_filename); - } - - if ($this->_isArchive($p_filename)) { - if (($v_file = @fopen($p_filename, "rb")) == 0) { - $this->_warning( - "Unable to open file '" . $p_filename - . "' in binary read mode" - ); - return true; - } - - if (!$this->_writeHeader($p_filename, $v_stored_filename)) { - return false; - } - - while (($v_buffer = fread($v_file, 512)) != '') { - $v_binary_data = pack("a512", "$v_buffer"); - $this->_writeBlock($v_binary_data); - } - - fclose($v_file); - - } else { - // ----- Only header for dir - if (!$this->_writeHeader($p_filename, $v_stored_filename)) { - return false; - } - } - - return true; - } - - // }}} - - // {{{ _addString() - function _addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) - { - $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); - $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; - $p_type = @$p_params["type"] ? $p_params["type"] : ""; - $p_uid = @$p_params["uid"] ? $p_params["uid"] : 0; - $p_gid = @$p_params["gid"] ? $p_params["gid"] : 0; - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } - - if ($p_filename == '') { - $this->_error('Invalid file name'); - return false; - } - - // ----- Calculate the stored filename - $p_filename = $this->_translateWinPath($p_filename, false);; - - // ----- If datetime is not specified, set current time - if ($p_datetime === false) { - $p_datetime = time(); - } - - if (!$this->_writeHeaderBlock( - $p_filename, - strlen($p_string), - $p_stamp, - $p_mode, - $p_type, - $p_uid, - $p_gid - ) - ) { - return false; - } - - $i = 0; - while (($v_buffer = substr($p_string, (($i++) * 512), 512)) != '') { - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - } - - return true; - } - - // }}} - - // {{{ _writeHeader() - function _writeHeader($p_filename, $p_stored_filename) - { - if ($p_stored_filename == '') { - $p_stored_filename = $p_filename; - } - $v_reduce_filename = $this->_pathReduction($p_stored_filename); - - if (strlen($v_reduce_filename) > 99) { - if (!$this->_writeLongHeader($v_reduce_filename)) { - return false; - } - } - - $v_info = lstat($p_filename); - $v_uid = sprintf("%07s", DecOct($v_info[4])); - $v_gid = sprintf("%07s", DecOct($v_info[5])); - $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); - - $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); - - $v_linkname = ''; - - if (@is_link($p_filename)) { - $v_typeflag = '2'; - $v_linkname = readlink($p_filename); - $v_size = sprintf("%011s", DecOct(0)); - } elseif (@is_dir($p_filename)) { - $v_typeflag = "5"; - $v_size = sprintf("%011s", DecOct(0)); - } else { - $v_typeflag = '0'; - clearstatcache(); - $v_size = sprintf("%011s", DecOct($v_info['size'])); - } - - $v_magic = 'ustar '; - - $v_version = ' '; - - if (function_exists('posix_getpwuid')) { - $userinfo = posix_getpwuid($v_info[4]); - $groupinfo = posix_getgrgid($v_info[5]); - - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; - } else { - $v_uname = ''; - $v_gname = ''; - } - - $v_devmajor = ''; - - $v_devminor = ''; - - $v_prefix = ''; - - $v_binary_data_first = pack( - "a100a8a8a8a12a12", - $v_reduce_filename, - $v_perms, - $v_uid, - $v_gid, - $v_size, - $v_mtime - ); - $v_binary_data_last = pack( - "a1a100a6a2a32a32a8a8a155a12", - $v_typeflag, - $v_linkname, - $v_magic, - $v_version, - $v_uname, - $v_gname, - $v_devmajor, - $v_devminor, - $v_prefix, - '' - ); - - // ----- Calculate the checksum - $v_checksum = 0; - // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data_first, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156, $j = 0; $i < 512; $i++, $j++) { - $v_checksum += ord(substr($v_binary_data_last, $j, 1)); - } - - // ----- Write the first 148 bytes of the header in the archive - $this->_writeBlock($v_binary_data_first, 148); - - // ----- Write the calculated checksum - $v_checksum = sprintf("%06s ", DecOct($v_checksum)); - $v_binary_data = pack("a8", $v_checksum); - $this->_writeBlock($v_binary_data, 8); - - // ----- Write the last 356 bytes of the header in the archive - $this->_writeBlock($v_binary_data_last, 356); - - return true; - } - - // }}} - - // {{{ _writeHeaderBlock() - function _writeHeaderBlock( - $p_filename, - $p_size, - $p_mtime = 0, - $p_perms = 0, - $p_type = '', - $p_uid = 0, - $p_gid = 0 - ) { - $p_filename = $this->_pathReduction($p_filename); - - if (strlen($p_filename) > 99) { - if (!$this->_writeLongHeader($p_filename)) { - return false; - } - } - - if ($p_type == "5") { - $v_size = sprintf("%011s", DecOct(0)); - } else { - $v_size = sprintf("%011s", DecOct($p_size)); - } - - $v_uid = sprintf("%07s", DecOct($p_uid)); - $v_gid = sprintf("%07s", DecOct($p_gid)); - $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); - - $v_mtime = sprintf("%11s", DecOct($p_mtime)); - - $v_linkname = ''; - - $v_magic = 'ustar '; - - $v_version = ' '; - - if (function_exists('posix_getpwuid')) { - $userinfo = posix_getpwuid($p_uid); - $groupinfo = posix_getgrgid($p_gid); - - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; - } else { - $v_uname = ''; - $v_gname = ''; - } - - $v_devmajor = ''; - - $v_devminor = ''; - - $v_prefix = ''; - - $v_binary_data_first = pack( - "a100a8a8a8a12A12", - $p_filename, - $v_perms, - $v_uid, - $v_gid, - $v_size, - $v_mtime - ); - $v_binary_data_last = pack( - "a1a100a6a2a32a32a8a8a155a12", - $p_type, - $v_linkname, - $v_magic, - $v_version, - $v_uname, - $v_gname, - $v_devmajor, - $v_devminor, - $v_prefix, - '' - ); - - // ----- Calculate the checksum - $v_checksum = 0; - // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data_first, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156, $j = 0; $i < 512; $i++, $j++) { - $v_checksum += ord(substr($v_binary_data_last, $j, 1)); - } - - // ----- Write the first 148 bytes of the header in the archive - $this->_writeBlock($v_binary_data_first, 148); - - // ----- Write the calculated checksum - $v_checksum = sprintf("%06s ", DecOct($v_checksum)); - $v_binary_data = pack("a8", $v_checksum); - $this->_writeBlock($v_binary_data, 8); - - // ----- Write the last 356 bytes of the header in the archive - $this->_writeBlock($v_binary_data_last, 356); - - return true; - } - - // }}} - - // {{{ _writeLongHeader() - function _writeLongHeader($p_filename) - { - $v_size = sprintf("%11s ", DecOct(strlen($p_filename))); - - $v_typeflag = 'L'; - - $v_linkname = ''; - - $v_magic = ''; - - $v_version = ''; - - $v_uname = ''; - - $v_gname = ''; - - $v_devmajor = ''; - - $v_devminor = ''; - - $v_prefix = ''; - - $v_binary_data_first = pack( - "a100a8a8a8a12a12", - '././@LongLink', - 0, - 0, - 0, - $v_size, - 0 - ); - $v_binary_data_last = pack( - "a1a100a6a2a32a32a8a8a155a12", - $v_typeflag, - $v_linkname, - $v_magic, - $v_version, - $v_uname, - $v_gname, - $v_devmajor, - $v_devminor, - $v_prefix, - '' - ); - - // ----- Calculate the checksum - $v_checksum = 0; - // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data_first, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156, $j = 0; $i < 512; $i++, $j++) { - $v_checksum += ord(substr($v_binary_data_last, $j, 1)); - } - - // ----- Write the first 148 bytes of the header in the archive - $this->_writeBlock($v_binary_data_first, 148); - - // ----- Write the calculated checksum - $v_checksum = sprintf("%06s ", DecOct($v_checksum)); - $v_binary_data = pack("a8", $v_checksum); - $this->_writeBlock($v_binary_data, 8); - - // ----- Write the last 356 bytes of the header in the archive - $this->_writeBlock($v_binary_data_last, 356); - - // ----- Write the filename as content of the block - $i = 0; - while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) != '') { - $v_binary_data = pack("a512", "$v_buffer"); - $this->_writeBlock($v_binary_data); - } - - return true; - } - - // }}} - - // {{{ _readHeader() - function _readHeader($v_binary_data, &$v_header) - { - if (strlen($v_binary_data) == 0) { - $v_header['filename'] = ''; - return true; - } - - if (strlen($v_binary_data) != 512) { - $v_header['filename'] = ''; - $this->_error('Invalid block size : ' . strlen($v_binary_data)); - return false; - } - - if (!is_array($v_header)) { - $v_header = array(); - } - // ----- Calculate the checksum - $v_checksum = 0; - // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156; $i < 512; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } - - if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { - $fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . - "a8checksum/a1typeflag/a100link/a6magic/a2version/" . - "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; - } else { - $fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . - "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . - "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; - } - $v_data = unpack($fmt, $v_binary_data); - - if (strlen($v_data["prefix"]) > 0) { - $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; - } - - // ----- Extract the checksum - $v_header['checksum'] = OctDec(trim($v_data['checksum'])); - if ($v_header['checksum'] != $v_checksum) { - $v_header['filename'] = ''; - - // ----- Look for last block (empty block) - if (($v_checksum == 256) && ($v_header['checksum'] == 0)) { - return true; - } - - $this->_error( - 'Invalid checksum for file "' . $v_data['filename'] - . '" : ' . $v_checksum . ' calculated, ' - . $v_header['checksum'] . ' expected' - ); - return false; - } - - // ----- Extract the properties - $v_header['filename'] = $v_data['filename']; - if ($this->_maliciousFilename($v_header['filename'])) { - $this->_error( - 'Malicious .tar detected, file "' . $v_header['filename'] . - '" will not install in desired directory tree' - ); - return false; - } - $v_header['mode'] = OctDec(trim($v_data['mode'])); - $v_header['uid'] = OctDec(trim($v_data['uid'])); - $v_header['gid'] = OctDec(trim($v_data['gid'])); - $v_header['size'] = OctDec(trim($v_data['size'])); - $v_header['mtime'] = OctDec(trim($v_data['mtime'])); - if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { - $v_header['size'] = 0; - } - $v_header['link'] = trim($v_data['link']); - /* ----- All these fields are removed form the header because - they do not carry interesting info - $v_header[magic] = trim($v_data[magic]); - $v_header[version] = trim($v_data[version]); - $v_header[uname] = trim($v_data[uname]); - $v_header[gname] = trim($v_data[gname]); - $v_header[devmajor] = trim($v_data[devmajor]); - $v_header[devminor] = trim($v_data[devminor]); - */ - - return true; - } - - // }}} - - // {{{ _maliciousFilename() - /** - * Detect and report a malicious file name - * - * @param string $file - * - * @return bool - * @access private - */ - function _maliciousFilename($file) - { - if (strpos($file, '/../') !== false) { - return true; - } - if (strpos($file, '../') === 0) { - return true; - } - return false; - } - - // }}} - - // {{{ _readLongHeader() - function _readLongHeader(&$v_header) - { - $v_filename = ''; - $n = floor($v_header['size'] / 512); - for ($i = 0; $i < $n; $i++) { - $v_content = $this->_readBlock(); - $v_filename .= $v_content; - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - $v_filename .= trim($v_content); - } - - // ----- Read the next header - $v_binary_data = $this->_readBlock(); - - if (!$this->_readHeader($v_binary_data, $v_header)) { - return false; - } - - $v_filename = trim($v_filename); - $v_header['filename'] = $v_filename; - if ($this->_maliciousFilename($v_filename)) { - $this->_error( - 'Malicious .tar detected, file "' . $v_filename . - '" will not install in desired directory tree' - ); - return false; - } - - return true; - } - - // }}} - - // {{{ _extractInString() - /** - * This method extract from the archive one file identified by $p_filename. - * The return value is a string with the file content, or null on error. - * - * @param string $p_filename The path of the file to extract in a string. - * - * @return a string with the file content or null. - * @access private - */ - function _extractInString($p_filename) - { - $v_result_str = ""; - - While (strlen($v_binary_data = $this->_readBlock()) != 0) { - if (!$this->_readHeader($v_binary_data, $v_header)) { - return null; - } - - if ($v_header['filename'] == '') { - continue; - } - - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) { - return null; - } - } - - if ($v_header['filename'] == $p_filename) { - if ($v_header['typeflag'] == "5") { - $this->_error( - 'Unable to extract in string a directory ' - . 'entry {' . $v_header['filename'] . '}' - ); - return null; - } else { - $n = floor($v_header['size'] / 512); - for ($i = 0; $i < $n; $i++) { - $v_result_str .= $this->_readBlock(); - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - $v_result_str .= substr( - $v_content, - 0, - ($v_header['size'] % 512) - ); - } - return $v_result_str; - } - } else { - $this->_jumpBlock(ceil(($v_header['size'] / 512))); - } - } - - return null; - } - - // }}} - - // {{{ _extractList() - function _extractList( - $p_path, - &$p_list_detail, - $p_mode, - $p_file_list, - $p_remove_path, - $p_preserve = false - ) { - $v_result = true; - $v_nb = 0; - $v_extract_all = true; - $v_listing = false; - - $p_path = $this->_translateWinPath($p_path, false); - if ($p_path == '' || (substr($p_path, 0, 1) != '/' - && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':')) - ) { - $p_path = "./" . $p_path; - } - $p_remove_path = $this->_translateWinPath($p_remove_path); - - // ----- Look for path to remove format (should end by /) - if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) { - $p_remove_path .= '/'; - } - $p_remove_path_size = strlen($p_remove_path); - - switch ($p_mode) { - case "complete" : - $v_extract_all = true; - $v_listing = false; - break; - case "partial" : - $v_extract_all = false; - $v_listing = false; - break; - case "list" : - $v_extract_all = false; - $v_listing = true; - break; - default : - $this->_error('Invalid extract mode (' . $p_mode . ')'); - return false; - } - - clearstatcache(); - - while (strlen($v_binary_data = $this->_readBlock()) != 0) { - $v_extract_file = false; - $v_extraction_stopped = 0; - - if (!$this->_readHeader($v_binary_data, $v_header)) { - return false; - } - - if ($v_header['filename'] == '') { - continue; - } - - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) { - return false; - } - } - - // ignore extended / pax headers - if ($v_header['typeflag'] == 'x' || $v_header['typeflag'] == 'g') { - $this->_jumpBlock(ceil(($v_header['size'] / 512))); - continue; - } - - if ((!$v_extract_all) && (is_array($p_file_list))) { - // ----- By default no unzip if the file is not found - $v_extract_file = false; - - for ($i = 0; $i < sizeof($p_file_list); $i++) { - // ----- Look if it is a directory - if (substr($p_file_list[$i], -1) == '/') { - // ----- Look if the directory is in the filename path - if ((strlen($v_header['filename']) > strlen($p_file_list[$i])) - && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) - == $p_file_list[$i]) - ) { - $v_extract_file = true; - break; - } - } // ----- It is a file, so compare the file names - elseif ($p_file_list[$i] == $v_header['filename']) { - $v_extract_file = true; - break; - } - } - } else { - $v_extract_file = true; - } - - // ----- Look if this file need to be extracted - if (($v_extract_file) && (!$v_listing)) { - if (($p_remove_path != '') - && (substr($v_header['filename'] . '/', 0, $p_remove_path_size) - == $p_remove_path) - ) { - $v_header['filename'] = substr( - $v_header['filename'], - $p_remove_path_size - ); - if ($v_header['filename'] == '') { - continue; - } - } - if (($p_path != './') && ($p_path != '/')) { - while (substr($p_path, -1) == '/') { - $p_path = substr($p_path, 0, strlen($p_path) - 1); - } - - if (substr($v_header['filename'], 0, 1) == '/') { - $v_header['filename'] = $p_path . $v_header['filename']; - } else { - $v_header['filename'] = $p_path . '/' . $v_header['filename']; - } - } - if (file_exists($v_header['filename'])) { - if ((@is_dir($v_header['filename'])) - && ($v_header['typeflag'] == '') - ) { - $this->_error( - 'File ' . $v_header['filename'] - . ' already exists as a directory' - ); - return false; - } - if (($this->_isArchive($v_header['filename'])) - && ($v_header['typeflag'] == "5") - ) { - $this->_error( - 'Directory ' . $v_header['filename'] - . ' already exists as a file' - ); - return false; - } - if (!is_writeable($v_header['filename'])) { - $this->_error( - 'File ' . $v_header['filename'] - . ' already exists and is write protected' - ); - return false; - } - if (filemtime($v_header['filename']) > $v_header['mtime']) { - // To be completed : An error or silent no replace ? - } - } // ----- Check the directory availability and create it if necessary - elseif (($v_result - = $this->_dirCheck( - ($v_header['typeflag'] == "5" - ? $v_header['filename'] - : dirname($v_header['filename'])) - )) != 1 - ) { - $this->_error('Unable to create path for ' . $v_header['filename']); - return false; - } - - if ($v_extract_file) { - if ($v_header['typeflag'] == "5") { - if (!@file_exists($v_header['filename'])) { - if (!@mkdir($v_header['filename'], 0777)) { - $this->_error( - 'Unable to create directory {' - . $v_header['filename'] . '}' - ); - return false; - } - } - } elseif ($v_header['typeflag'] == "2") { - if (@file_exists($v_header['filename'])) { - @unlink($v_header['filename']); - } - if (!@symlink($v_header['link'], $v_header['filename'])) { - $this->_error( - 'Unable to extract symbolic link {' - . $v_header['filename'] . '}' - ); - return false; - } - } else { - if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { - $this->_error( - 'Error while opening {' . $v_header['filename'] - . '} in write binary mode' - ); - return false; - } else { - $n = floor($v_header['size'] / 512); - for ($i = 0; $i < $n; $i++) { - $v_content = $this->_readBlock(); - fwrite($v_dest_file, $v_content, 512); - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); - } - - @fclose($v_dest_file); - - if ($p_preserve) { - @chown($v_header['filename'], $v_header['uid']); - @chgrp($v_header['filename'], $v_header['gid']); - } - - // ----- Change the file mode, mtime - @touch($v_header['filename'], $v_header['mtime']); - if ($v_header['mode'] & 0111) { - // make file executable, obey umask - $mode = fileperms($v_header['filename']) | (~umask() & 0111); - @chmod($v_header['filename'], $mode); - } - } - - // ----- Check the file size - clearstatcache(); - if (!is_file($v_header['filename'])) { - $this->_error( - 'Extracted file ' . $v_header['filename'] - . 'does not exist. Archive may be corrupted.' - ); - return false; - } - - $filesize = filesize($v_header['filename']); - if ($filesize != $v_header['size']) { - $this->_error( - 'Extracted file ' . $v_header['filename'] - . ' does not have the correct file size \'' - . $filesize - . '\' (' . $v_header['size'] - . ' expected). Archive may be corrupted.' - ); - return false; - } - } - } else { - $this->_jumpBlock(ceil(($v_header['size'] / 512))); - } - } else { - $this->_jumpBlock(ceil(($v_header['size'] / 512))); - } - - /* TBC : Seems to be unused ... - if ($this->_compress) - $v_end_of_file = @gzeof($this->_file); - else - $v_end_of_file = @feof($this->_file); - */ - - if ($v_listing || $v_extract_file || $v_extraction_stopped) { - // ----- Log extracted files - if (($v_file_dir = dirname($v_header['filename'])) - == $v_header['filename'] - ) { - $v_file_dir = ''; - } - if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) { - $v_file_dir = '/'; - } - - $p_list_detail[$v_nb++] = $v_header; - if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { - return true; - } - } - } - - return true; - } - - // }}} - - // {{{ _openAppend() - function _openAppend() - { - if (filesize($this->_tarname) == 0) { - return $this->_openWrite(); - } - - if ($this->_compress) { - $this->_close(); - - if (!@rename($this->_tarname, $this->_tarname . ".tmp")) { - $this->_error( - 'Error while renaming \'' . $this->_tarname - . '\' to temporary file \'' . $this->_tarname - . '.tmp\'' - ); - return false; - } - - if ($this->_compress_type == 'gz') { - $v_temp_tar = @gzopen($this->_tarname . ".tmp", "rb"); - } elseif ($this->_compress_type == 'bz2') { - $v_temp_tar = @bzopen($this->_tarname . ".tmp", "r"); - } elseif ($this->_compress_type == 'lzma2') { - $v_temp_tar = @xzopen($this->_tarname . ".tmp", "r"); - } - - - if ($v_temp_tar == 0) { - $this->_error( - 'Unable to open file \'' . $this->_tarname - . '.tmp\' in binary read mode' - ); - @rename($this->_tarname . ".tmp", $this->_tarname); - return false; - } - - if (!$this->_openWrite()) { - @rename($this->_tarname . ".tmp", $this->_tarname); - return false; - } - - if ($this->_compress_type == 'gz') { - $end_blocks = 0; - - while (!@gzeof($v_temp_tar)) { - $v_buffer = @gzread($v_temp_tar, 512); - if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { - $end_blocks++; - // do not copy end blocks, we will re-make them - // after appending - continue; - } elseif ($end_blocks > 0) { - for ($i = 0; $i < $end_blocks; $i++) { - $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); - } - $end_blocks = 0; - } - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - } - - @gzclose($v_temp_tar); - } elseif ($this->_compress_type == 'bz2') { - $end_blocks = 0; - - while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { - if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { - $end_blocks++; - // do not copy end blocks, we will re-make them - // after appending - continue; - } elseif ($end_blocks > 0) { - for ($i = 0; $i < $end_blocks; $i++) { - $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); - } - $end_blocks = 0; - } - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - } - - @bzclose($v_temp_tar); - } elseif ($this->_compress_type == 'lzma2') { - $end_blocks = 0; - - while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) { - if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { - $end_blocks++; - // do not copy end blocks, we will re-make them - // after appending - continue; - } elseif ($end_blocks > 0) { - for ($i = 0; $i < $end_blocks; $i++) { - $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); - } - $end_blocks = 0; - } - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - } - - @xzclose($v_temp_tar); - } - - if (!@unlink($this->_tarname . ".tmp")) { - $this->_error( - 'Error while deleting temporary file \'' - . $this->_tarname . '.tmp\'' - ); - } - - } else { - // ----- For not compressed tar, just add files before the last - // one or two 512 bytes block - if (!$this->_openReadWrite()) { - return false; - } - - clearstatcache(); - $v_size = filesize($this->_tarname); - - // We might have zero, one or two end blocks. - // The standard is two, but we should try to handle - // other cases. - fseek($this->_file, $v_size - 1024); - if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { - fseek($this->_file, $v_size - 1024); - } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { - fseek($this->_file, $v_size - 512); - } - } - - return true; - } - - // }}} - - // {{{ _append() - function _append($p_filelist, $p_add_dir = '', $p_remove_dir = '') - { - if (!$this->_openAppend()) { - return false; - } - - if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) { - $this->_writeFooter(); - } - - $this->_close(); - - return true; - } - - // }}} - - // {{{ _dirCheck() - - /** - * Check if a directory exists and create it (including parent - * dirs) if not. - * - * @param string $p_dir directory to check - * - * @return bool true if the directory exists or was created - */ - function _dirCheck($p_dir) - { - clearstatcache(); - if ((@is_dir($p_dir)) || ($p_dir == '')) { - return true; - } - - $p_parent_dir = dirname($p_dir); - - if (($p_parent_dir != $p_dir) && - ($p_parent_dir != '') && - (!$this->_dirCheck($p_parent_dir)) - ) { - return false; - } - - if (!@mkdir($p_dir, 0777)) { - $this->_error("Unable to create directory '$p_dir'"); - return false; - } - - return true; - } - - // }}} - - // {{{ _pathReduction() - - /** - * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", - * rand emove double slashes. - * - * @param string $p_dir path to reduce - * - * @return string reduced path - * - * @access private - * - */ - function _pathReduction($p_dir) - { - $v_result = ''; - - // ----- Look for not empty path - if ($p_dir != '') { - // ----- Explode path by directory names - $v_list = explode('/', $p_dir); - - // ----- Study directories from last to first - for ($i = sizeof($v_list) - 1; $i >= 0; $i--) { - // ----- Look for current path - if ($v_list[$i] == ".") { - // ----- Ignore this directory - // Should be the first $i=0, but no check is done - } else { - if ($v_list[$i] == "..") { - // ----- Ignore it and ignore the $i-1 - $i--; - } else { - if (($v_list[$i] == '') - && ($i != (sizeof($v_list) - 1)) - && ($i != 0) - ) { - // ----- Ignore only the double '//' in path, - // but not the first and last / - } else { - $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? '/' - . $v_result : ''); - } - } - } - } - } - - if (defined('OS_WINDOWS') && OS_WINDOWS) { - $v_result = strtr($v_result, '\\', '/'); - } - - return $v_result; - } - - // }}} - - // {{{ _translateWinPath() - function _translateWinPath($p_path, $p_remove_disk_letter = true) - { - if (defined('OS_WINDOWS') && OS_WINDOWS) { - // ----- Look for potential disk letter - if (($p_remove_disk_letter) - && (($v_position = strpos($p_path, ':')) != false) - ) { - $p_path = substr($p_path, $v_position + 1); - } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } - } - return $p_path; - } - // }}} - -} - -?> diff --git a/data/module/Cache/Lite.php b/data/module/Cache/Lite.php deleted file mode 100644 index 0ca762d380..0000000000 --- a/data/module/Cache/Lite.php +++ /dev/null @@ -1,886 +0,0 @@ - -* -* Nota : A chinese documentation (thanks to RainX ) is -* available at : -* http://rainx.phpmore.com/manual/cache_lite.html -* -* @package Cache_Lite -* @category Caching -* @author Fabien MARTY -* @author Markus Tacker -*/ - -define('CACHE_LITE_ERROR_RETURN', 1); -define('CACHE_LITE_ERROR_DIE', 8); - -class Cache_Lite -{ - - // --- Private properties --- - - /** - * Directory where to put the cache files - * (make sure to add a trailing slash) - * - * @var string $_cacheDir - */ - var $_cacheDir = '/tmp/'; - - /** - * Enable / disable caching - * - * (can be very usefull for the debug of cached scripts) - * - * @var boolean $_caching - */ - var $_caching = true; - - /** - * Cache lifetime (in seconds) - * - * If null, the cache is valid forever. - * - * @var int $_lifeTime - */ - var $_lifeTime = 3600; - - /** - * Enable / disable fileLocking - * - * (can avoid cache corruption under bad circumstances) - * - * @var boolean $_fileLocking - */ - var $_fileLocking = true; - - /** - * Timestamp of the last valid cache - * - * @var int $_refreshTime - */ - var $_refreshTime; - - /** - * File name (with path) - * - * @var string $_file - */ - var $_file; - - /** - * File name (without path) - * - * @var string $_fileName - */ - var $_fileName; - - /** - * Enable / disable write control (the cache is read just after writing to detect corrupt entries) - * - * Enable write control will lightly slow the cache writing but not the cache reading - * Write control can detect some corrupt cache files but maybe it's not a perfect control - * - * @var boolean $_writeControl - */ - var $_writeControl = true; - - /** - * Enable / disable read control - * - * If enabled, a control key is embeded in cache file and this key is compared with the one - * calculated after the reading. - * - * @var boolean $_writeControl - */ - var $_readControl = true; - - /** - * Type of read control (only if read control is enabled) - * - * Available values are : - * 'md5' for a md5 hash control (best but slowest) - * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice) - * 'strlen' for a length only test (fastest) - * - * @var boolean $_readControlType - */ - var $_readControlType = 'crc32'; - - /** - * Pear error mode (when raiseError is called) - * - * (see PEAR doc) - * - * @see setToDebug() - * @var int $_pearErrorMode - */ - var $_pearErrorMode = CACHE_LITE_ERROR_RETURN; - - /** - * Current cache id - * - * @var string $_id - */ - var $_id; - - /** - * Current cache group - * - * @var string $_group - */ - var $_group; - - /** - * Enable / Disable "Memory Caching" - * - * NB : There is no lifetime for memory caching ! - * - * @var boolean $_memoryCaching - */ - var $_memoryCaching = false; - - /** - * Enable / Disable "Only Memory Caching" - * (be carefull, memory caching is "beta quality") - * - * @var boolean $_onlyMemoryCaching - */ - var $_onlyMemoryCaching = false; - - /** - * Memory caching array - * - * @var array $_memoryCachingArray - */ - var $_memoryCachingArray = array(); - - /** - * Memory caching counter - * - * @var int $memoryCachingCounter - */ - var $_memoryCachingCounter = 0; - - /** - * Memory caching limit - * - * @var int $memoryCachingLimit - */ - var $_memoryCachingLimit = 1000; - - /** - * File Name protection - * - * if set to true, you can use any cache id or group name - * if set to false, it can be faster but cache ids and group names - * will be used directly in cache file names so be carefull with - * special characters... - * - * @var boolean $fileNameProtection - */ - var $_fileNameProtection = true; - - /** - * Enable / disable automatic serialization - * - * it can be used to save directly datas which aren't strings - * (but it's slower) - * - * @var boolean $_serialize - */ - var $_automaticSerialization = false; - - /** - * Disable / Tune the automatic cleaning process - * - * The automatic cleaning process destroy too old (for the given life time) - * cache files when a new cache file is written. - * 0 => no automatic cache cleaning - * 1 => systematic cache cleaning - * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write - * - * @var int $_automaticCleaning - */ - var $_automaticCleaningFactor = 0; - - /** - * Nested directory level - * - * Set the hashed directory structure level. 0 means "no hashed directory - * structure", 1 means "one level of directory", 2 means "two levels"... - * This option can speed up Cache_Lite only when you have many thousands of - * cache file. Only specific benchs can help you to choose the perfect value - * for you. Maybe, 1 or 2 is a good start. - * - * @var int $_hashedDirectoryLevel - */ - var $_hashedDirectoryLevel = 0; - - /** - * Umask for hashed directory structure - * - * @var int $_hashedDirectoryUmask - */ - var $_hashedDirectoryUmask = 0700; - - /** - * API break for error handling in CACHE_LITE_ERROR_RETURN mode - * - * In CACHE_LITE_ERROR_RETURN mode, error handling was not good because - * for example save() method always returned a boolean (a PEAR_Error object - * would be better in CACHE_LITE_ERROR_RETURN mode). To correct this without - * breaking the API, this option (false by default) can change this handling. - * - * @var boolean - */ - var $_errorHandlingAPIBreak = false; - - var $_hashedDirectoryGroup = NULL; - - var $_cacheFileMode = NULL; - - var $_cacheFileGroup = NULL; - - // --- Public methods --- - - /** - * Constructor - * - * $options is an assoc. Available options are : - * $options = array( - * 'cacheDir' => directory where to put the cache files (string), - * 'caching' => enable / disable caching (boolean), - * 'lifeTime' => cache lifetime in seconds (int), - * 'fileLocking' => enable / disable fileLocking (boolean), - * 'writeControl' => enable / disable write control (boolean), - * 'readControl' => enable / disable read control (boolean), - * 'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string), - * 'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int), - * 'memoryCaching' => enable / disable memory caching (boolean), - * 'onlyMemoryCaching' => enable / disable only memory caching (boolean), - * 'memoryCachingLimit' => max nbr of records to store into memory caching (int), - * 'fileNameProtection' => enable / disable automatic file name protection (boolean), - * 'automaticSerialization' => enable / disable automatic serialization (boolean), - * 'automaticCleaningFactor' => distable / tune automatic cleaning process (int), - * 'hashedDirectoryLevel' => level of the hashed directory system (int), - * 'hashedDirectoryUmask' => umask for hashed directory structure (int), - * 'errorHandlingAPIBreak' => API break for better error handling ? (boolean) - * 'hashedDirectoryGroup' => group of hashed directory structure (int | string) (see function chgrp) - * 'cacheFileMode' => filesystem mode of newly created cache files (int) - * 'cacheFileGroup' => group of newly created cache files (int | string) (see function chgrp) - * ); - * - * If sys_get_temp_dir() is available and the - * 'cacheDir' option is not provided in the - * constructor options array its output is used - * to determine the suitable temporary directory. - * - * @see http://de.php.net/sys_get_temp_dir - * @see http://pear.php.net/bugs/bug.php?id=18328 - * - * @param array $options options - * @access public - */ - function Cache_Lite($options = array(NULL)) - { - foreach($options as $key => $value) { - $this->setOption($key, $value); - } - if (!isset($options['cacheDir']) && function_exists('sys_get_temp_dir')) { - $this->setOption('cacheDir', sys_get_temp_dir() . DIRECTORY_SEPARATOR); - } - } - - /** - * Generic way to set a Cache_Lite option - * - * see Cache_Lite constructor for available options - * - * @var string $name name of the option - * @var mixed $value value of the option - * @access public - */ - function setOption($name, $value) - { - $availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode', 'hashedDirectoryGroup', 'cacheFileMode', 'cacheFileGroup'); - if (in_array($name, $availableOptions)) { - $property = '_'.$name; - $this->$property = $value; - } - } - - /** - * Test if a cache is available and (if yes) return it - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string data of the cache (else : false) - * @access public - */ - function get($id, $group = 'default', $doNotTestCacheValidity = false) - { - $this->_id = $id; - $this->_group = $group; - $data = false; - if ($this->_caching) { - $this->_setRefreshTime(); - $this->_setFileName($id, $group); - clearstatcache(); - if ($this->_memoryCaching) { - if (isset($this->_memoryCachingArray[$this->_file])) { - if ($this->_automaticSerialization) { - return unserialize($this->_memoryCachingArray[$this->_file]); - } - return $this->_memoryCachingArray[$this->_file]; - } - if ($this->_onlyMemoryCaching) { - return false; - } - } - if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) { - if (file_exists($this->_file)) { - $data = $this->_read(); - } - } else { - if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) { - $data = $this->_read(); - } - } - if (($data) and ($this->_memoryCaching)) { - $this->_memoryCacheAdd($data); - } - if (($this->_automaticSerialization) and (is_string($data))) { - $data = unserialize($data); - } - return $data; - } - return false; - } - - /** - * Save some data in a cache file - * - * @param string $data data to put in cache (can be another type than strings if automaticSerialization is on) - * @param string $id cache id - * @param string $group name of the cache group - * @return boolean true if no problem (else : false or a PEAR_Error object) - * @access public - */ - function save($data, $id = NULL, $group = 'default') - { - if ($this->_caching) { - if ($this->_automaticSerialization) { - $data = serialize($data); - } - if (isset($id)) { - $this->_setFileName($id, $group); - } - if ($this->_memoryCaching) { - $this->_memoryCacheAdd($data); - if ($this->_onlyMemoryCaching) { - return true; - } - } - if ($this->_automaticCleaningFactor>0 && ($this->_automaticCleaningFactor==1 || mt_rand(1, $this->_automaticCleaningFactor)==1)) { - $this->clean(false, 'old'); - } - if ($this->_writeControl) { - $res = $this->_writeAndControl($data); - if (is_bool($res)) { - if ($res) { - return true; - } - // if $res if false, we need to invalidate the cache - @touch($this->_file, time() - 2*abs($this->_lifeTime)); - return false; - } - } else { - $res = $this->_write($data); - } - if (is_object($res)) { - // $res is a PEAR_Error object - if (!($this->_errorHandlingAPIBreak)) { - return false; // we return false (old API) - } - } - return $res; - } - return false; - } - - /** - * Remove a cache file - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $checkbeforeunlink check if file exists before removing it - * @return boolean true if no problem - * @access public - */ - function remove($id, $group = 'default', $checkbeforeunlink = false) - { - $this->_setFileName($id, $group); - if ($this->_memoryCaching) { - if (isset($this->_memoryCachingArray[$this->_file])) { - unset($this->_memoryCachingArray[$this->_file]); - $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1; - } - if ($this->_onlyMemoryCaching) { - return true; - } - } - if ( $checkbeforeunlink ) { - if (!file_exists($this->_file)) return true; - } - return $this->_unlink($this->_file); - } - - /** - * Clean the cache - * - * if no group is specified all cache files will be destroyed - * else only cache files of the specified group will be destroyed - * - * @param string $group name of the cache group - * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', - * 'callback_myFunction' - * @return boolean true if no problem - * @access public - */ - function clean($group = false, $mode = 'ingroup') - { - return $this->_cleanDir($this->_cacheDir, $group, $mode); - } - - /** - * Set to debug mode - * - * When an error is found, the script will stop and the message will be displayed - * (in debug mode only). - * - * @access public - */ - function setToDebug() - { - $this->setOption('pearErrorMode', CACHE_LITE_ERROR_DIE); - } - - /** - * Set a new life time - * - * @param int $newLifeTime new life time (in seconds) - * @access public - */ - function setLifeTime($newLifeTime) - { - $this->_lifeTime = $newLifeTime; - $this->_setRefreshTime(); - } - - /** - * Save the state of the caching memory array into a cache file cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @access public - */ - function saveMemoryCachingState($id, $group = 'default') - { - if ($this->_caching) { - $array = array( - 'counter' => $this->_memoryCachingCounter, - 'array' => $this->_memoryCachingArray - ); - $data = serialize($array); - $this->save($data, $id, $group); - } - } - - /** - * Load the state of the caching memory array from a given cache file cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @access public - */ - function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false) - { - if ($this->_caching) { - if ($data = $this->get($id, $group, $doNotTestCacheValidity)) { - $array = unserialize($data); - $this->_memoryCachingCounter = $array['counter']; - $this->_memoryCachingArray = $array['array']; - } - } - } - - /** - * Return the cache last modification time - * - * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY ! - * - * @return int last modification time - */ - function lastModified() - { - return @filemtime($this->_file); - } - - /** - * Trigger a PEAR error - * - * To improve performances, the PEAR.php file is included dynamically. - * The file is so included only when an error is triggered. So, in most - * cases, the file isn't included and perfs are much better. - * - * @param string $msg error message - * @param int $code error code - * @access public - */ - function raiseError($msg, $code) - { - include_once('PEAR.php'); - return PEAR::raiseError($msg, $code, $this->_pearErrorMode); - } - - /** - * Extend the life of a valid cache file - * - * see http://pear.php.net/bugs/bug.php?id=6681 - * - * @access public - */ - function extendLife() - { - @touch($this->_file); - } - - // --- Private methods --- - - /** - * Compute & set the refresh time - * - * @access private - */ - function _setRefreshTime() - { - if (is_null($this->_lifeTime)) { - $this->_refreshTime = null; - } else { - $this->_refreshTime = time() - $this->_lifeTime; - } - } - - /** - * Remove a file - * - * @param string $file complete file path and name - * @return boolean true if no problem - * @access private - */ - function _unlink($file) - { - if (!@unlink($file)) { - return $this->raiseError('Cache_Lite : Unable to remove cache !', -3); - } - return true; - } - - /** - * Recursive function for cleaning cache file in the given directory - * - * @param string $dir directory complete path (with a trailing slash) - * @param string $group name of the cache group - * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', - 'callback_myFunction' - * @return boolean true if no problem - * @access private - */ - function _cleanDir($dir, $group = false, $mode = 'ingroup') - { - if ($this->_fileNameProtection) { - $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_'; - } else { - $motif = ($group) ? 'cache_'.$group.'_' : 'cache_'; - } - if ($this->_memoryCaching) { - foreach($this->_memoryCachingArray as $key => $v) { - if (strpos($key, $motif) !== false) { - unset($this->_memoryCachingArray[$key]); - $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1; - } - } - if ($this->_onlyMemoryCaching) { - return true; - } - } - if (!($dh = opendir($dir))) { - return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4); - } - $result = true; - while (($file = readdir($dh)) !== false) { - if (($file != '.') && ($file != '..')) { - if (substr($file, 0, 6)=='cache_') { - $file2 = $dir . $file; - if (is_file($file2)) { - switch (substr($mode, 0, 9)) { - case 'old': - // files older than lifeTime get deleted from cache - if (!is_null($this->_lifeTime)) { - if ((time() - @filemtime($file2)) > $this->_lifeTime) { - $result = ($result and ($this->_unlink($file2))); - } - } - break; - case 'notingrou': - if (strpos($file2, $motif) === false) { - $result = ($result and ($this->_unlink($file2))); - } - break; - case 'callback_': - $func = substr($mode, 9, strlen($mode) - 9); - if ($func($file2, $group)) { - $result = ($result and ($this->_unlink($file2))); - } - break; - case 'ingroup': - default: - if (strpos($file2, $motif) !== false) { - $result = ($result and ($this->_unlink($file2))); - } - break; - } - } - if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) { - $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode))); - } - } - } - } - return $result; - } - - /** - * Touch the cache file while are recreating it to avoid - * launch this task more then once when necessary - * When the cache recreated and Added in Cache Memory - * @return void - * @access private - */ - function _touchCacheFile(){ - if (file_exists($this->_file)) { - @touch($this->_file); - } - } - /** - * Add some date in the memory caching array - * - * @param string $data data to cache - * @access private - */ - function _memoryCacheAdd($data) - { - $this->_touchCacheFile(); - $this->_memoryCachingArray[$this->_file] = $data; - if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) { - list($key, ) = each($this->_memoryCachingArray); - unset($this->_memoryCachingArray[$key]); - } else { - $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1; - } - } - - /** - * Make a file name (with path) - * - * @param string $id cache id - * @param string $group name of the group - * @access private - */ - function _setFileName($id, $group) - { - - if ($this->_fileNameProtection) { - $suffix = 'cache_'.md5($group).'_'.md5($id); - } else { - $suffix = 'cache_'.$group.'_'.$id; - } - $root = $this->_cacheDir; - if ($this->_hashedDirectoryLevel>0) { - $hash = md5($suffix); - for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) { - $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/'; - } - } - $this->_fileName = $suffix; - $this->_file = $root.$suffix; - } - - /** - * Read the cache file and return the content - * - * @return string content of the cache file (else : false or a PEAR_Error object) - * @access private - */ - function _read() - { - $fp = @fopen($this->_file, "rb"); - if ($fp) { - if ($this->_fileLocking) @flock($fp, LOCK_SH); - clearstatcache(); - $length = @filesize($this->_file); - $mqr = get_magic_quotes_runtime(); - if ($mqr) { - set_magic_quotes_runtime(0); - } - if ($this->_readControl) { - $hashControl = @fread($fp, 32); - $length = $length - 32; - } - - if ($length) { - $data = ''; - // See https://bugs.php.net/bug.php?id=30936 - // The 8192 magic number is the chunk size used internally by PHP. - while(!feof($fp)) $data .= fread($fp, 8192); - } else { - $data = ''; - } - if ($mqr) { - set_magic_quotes_runtime($mqr); - } - if ($this->_fileLocking) @flock($fp, LOCK_UN); - @fclose($fp); - if ($this->_readControl) { - $hashData = $this->_hash($data, $this->_readControlType); - if ($hashData != $hashControl) { - if (!(is_null($this->_lifeTime))) { - @touch($this->_file, time() - 2*abs($this->_lifeTime)); - } else { - @unlink($this->_file); - } - return false; - } - } - return $data; - } - return $this->raiseError('Cache_Lite : Unable to read cache !', -2); - } - - /** - * Write the given data in the cache file - * - * @param string $data data to put in cache - * @return boolean true if ok (a PEAR_Error object else) - * @access private - */ - function _write($data) - { - if ($this->_hashedDirectoryLevel > 0) { - $hash = md5($this->_fileName); - $root = $this->_cacheDir; - for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) { - $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/'; - if (!(@is_dir($root))) { - if (@mkdir($root)) - { - @chmod($root, $this->_hashedDirectoryUmask); - if (! is_null($this->_hashedDirectoryGroup)) - @chgrp($root, $this->_hashedDirectoryGroup); - } - } - } - } - // if both _cacheFileMode and _cacheFileGroup is null, then we don't need to call - // file_exists (see below: if ($is_newfile) ...) - $is_newfile = (! is_null($this->_cacheFileMode) || !is_null($this->_cacheFileGroup)) - && ! @file_exists($this->_file); - $fp = @fopen($this->_file, "wb"); - if ($fp) { - if ($this->_fileLocking) @flock($fp, LOCK_EX); - if ($is_newfile) - { - if (! is_null($this->_cacheFileMode)) - @chmod($this->_file, $this->_cacheFileMode); - if (! is_null($this->_cacheFileGroup)) - @chgrp($this->_file, $this->_cacheFileGroup); - } - if ($this->_readControl) { - @fwrite($fp, $this->_hash($data, $this->_readControlType), 32); - } - $mqr = get_magic_quotes_runtime(); - if ($mqr) { - set_magic_quotes_runtime(0); - } - @fwrite($fp, $data); - if ($mqr) { - set_magic_quotes_runtime($mqr); - } - if ($this->_fileLocking) @flock($fp, LOCK_UN); - @fclose($fp); - return true; - } - return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1); - } - - /** - * Write the given data in the cache file and control it just after to avoir corrupted cache entries - * - * @param string $data data to put in cache - * @return boolean true if the test is ok (else : false or a PEAR_Error object) - * @access private - */ - function _writeAndControl($data) - { - $result = $this->_write($data); - if (is_object($result)) { - return $result; # We return the PEAR_Error object - } - $dataRead = $this->_read(); - if (is_object($dataRead)) { - return $dataRead; # We return the PEAR_Error object - } - if ((is_bool($dataRead)) && (!$dataRead)) { - return false; - } - return ($dataRead==$data); - } - - /** - * Make a control key with the string containing datas - * - * @param string $data data - * @param string $controlType type of control 'md5', 'crc32' or 'strlen' - * @return string control key - * @access private - */ - function _hash($data, $controlType) - { - switch ($controlType) { - case 'md5': - return md5($data); - case 'crc32': - return sprintf('% 32d', crc32($data)); - case 'strlen': - return sprintf('% 32d', strlen($data)); - default: - return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5); - } - } - -} diff --git a/data/module/Cache/Lite/File.php b/data/module/Cache/Lite/File.php deleted file mode 100644 index 2cb2758b0b..0000000000 --- a/data/module/Cache/Lite/File.php +++ /dev/null @@ -1,90 +0,0 @@ - -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_File extends Cache_Lite -{ - - // --- Private properties --- - - /** - * Complete path of the file used for controlling the cache lifetime - * - * @var string $_masterFile - */ - var $_masterFile = ''; - - /** - * Masterfile mtime - * - * @var int $_masterFile_mtime - */ - var $_masterFile_mtime = 0; - - // --- Public methods ---- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * Comparing to Cache_Lite constructor, there is another option : - * $options = array( - * (...) see Cache_Lite constructor - * 'masterFile' => complete path of the file used for controlling the cache lifetime(string) - * ); - * - * @param array $options options - * @access public - */ - function Cache_Lite_File($options = array(NULL)) - { - $options['lifetime'] = 0; - $this->Cache_Lite($options); - if (isset($options['masterFile'])) { - $this->_masterFile = $options['masterFile']; - } else { - return $this->raiseError('Cache_Lite_File : masterFile option must be set !'); - } - if (!($this->_masterFile_mtime = @filemtime($this->_masterFile))) { - return $this->raiseError('Cache_Lite_File : Unable to read masterFile : '.$this->_masterFile, -3); - } - } - - /** - * Test if a cache is available and (if yes) return it - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string data of the cache (else : false) - * @access public - */ - function get($id, $group = 'default', $doNotTestCacheValidity = false) - { - if ($data = parent::get($id, $group, true)) { - if ($filemtime = $this->lastModified()) { - if ($filemtime > $this->_masterFile_mtime) { - return $data; - } - } - } - return false; - } - -} diff --git a/data/module/Cache/Lite/Function.php b/data/module/Cache/Lite/Function.php deleted file mode 100644 index 6c4861a438..0000000000 --- a/data/module/Cache/Lite/Function.php +++ /dev/null @@ -1,208 +0,0 @@ - -* @author Fabien MARTY -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_Function extends Cache_Lite -{ - - // --- Private properties --- - - /** - * Default cache group for function caching - * - * @var string $_defaultGroup - */ - var $_defaultGroup = 'Cache_Lite_Function'; - - /** - * Don't cache the method call when its output contains the string "NOCACHE" - * - * if set to true, the output of the method will never be displayed (because the output is used - * to control the cache) - * - * @var boolean $_dontCacheWhenTheOutputContainsNOCACHE - */ - var $_dontCacheWhenTheOutputContainsNOCACHE = false; - - /** - * Don't cache the method call when its result is false - * - * @var boolean $_dontCacheWhenTheResultIsFalse - */ - var $_dontCacheWhenTheResultIsFalse = false; - - /** - * Don't cache the method call when its result is null - * - * @var boolean $_dontCacheWhenTheResultIsNull - */ - var $_dontCacheWhenTheResultIsNull = false; - - /** - * Debug the Cache_Lite_Function caching process - * - * @var boolean $_debugCacheLiteFunction - */ - var $_debugCacheLiteFunction = false; - - // --- Public methods ---- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * Comparing to Cache_Lite constructor, there is another option : - * $options = array( - * (...) see Cache_Lite constructor - * 'debugCacheLiteFunction' => (bool) debug the caching process, - * 'defaultGroup' => default cache group for function caching (string), - * 'dontCacheWhenTheOutputContainsNOCACHE' => (bool) don't cache when the function output contains "NOCACHE", - * 'dontCacheWhenTheResultIsFalse' => (bool) don't cache when the function result is false, - * 'dontCacheWhenTheResultIsNull' => (bool don't cache when the function result is null - * ); - * - * @param array $options options - * @access public - */ - function Cache_Lite_Function($options = array(NULL)) - { - $availableOptions = array('debugCacheLiteFunction', 'defaultGroup', 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 'dontCacheWhenTheResultIsNull'); - while (list($name, $value) = each($options)) { - if (in_array($name, $availableOptions)) { - $property = '_'.$name; - $this->$property = $value; - } - } - reset($options); - $this->Cache_Lite($options); - } - - /** - * Calls a cacheable function or method (or not if there is already a cache for it) - * - * Arguments of this method are read with func_get_args. So it doesn't appear - * in the function definition. Synopsis : - * call('functionName', $arg1, $arg2, ...) - * (arg1, arg2... are arguments of 'functionName') - * - * @return mixed result of the function/method - * @access public - */ - function call() - { - $arguments = func_get_args(); - $id = $this->_makeId($arguments); - $data = $this->get($id, $this->_defaultGroup); - if ($data !== false) { - if ($this->_debugCacheLiteFunction) { - echo "Cache hit !\n"; - } - $array = unserialize($data); - $output = $array['output']; - $result = $array['result']; - } else { - if ($this->_debugCacheLiteFunction) { - echo "Cache missed !\n"; - } - ob_start(); - ob_implicit_flush(false); - $target = array_shift($arguments); - if (is_array($target)) { - // in this case, $target is for example array($obj, 'method') - $object = $target[0]; - $method = $target[1]; - $result = call_user_func_array(array(&$object, $method), $arguments); - } else { - if (strstr($target, '::')) { // classname::staticMethod - list($class, $method) = explode('::', $target); - $result = call_user_func_array(array($class, $method), $arguments); - } else if (strstr($target, '->')) { // object->method - // use a stupid name ($objet_123456789 because) of problems where the object - // name is the same as this var name - list($object_123456789, $method) = explode('->', $target); - global $$object_123456789; - $result = call_user_func_array(array($$object_123456789, $method), $arguments); - } else { // function - $result = call_user_func_array($target, $arguments); - } - } - $output = ob_get_contents(); - ob_end_clean(); - if ($this->_dontCacheWhenTheResultIsFalse) { - if ((is_bool($result)) && (!($result))) { - echo($output); - return $result; - } - } - if ($this->_dontCacheWhenTheResultIsNull) { - if (is_null($result)) { - echo($output); - return $result; - } - } - if ($this->_dontCacheWhenTheOutputContainsNOCACHE) { - if (strpos($output, 'NOCACHE') > -1) { - return $result; - } - } - $array['output'] = $output; - $array['result'] = $result; - $this->save(serialize($array), $id, $this->_defaultGroup); - } - echo($output); - return $result; - } - - /** - * Drop a cache file - * - * Arguments of this method are read with func_get_args. So it doesn't appear - * in the function definition. Synopsis : - * remove('functionName', $arg1, $arg2, ...) - * (arg1, arg2... are arguments of 'functionName') - * - * @return boolean true if no problem - * @access public - */ - function drop() - { - $id = $this->_makeId(func_get_args()); - return $this->remove($id, $this->_defaultGroup); - } - - /** - * Make an id for the cache - * - * @var array result of func_get_args for the call() or the remove() method - * @return string id - * @access private - */ - function _makeId($arguments) - { - $id = serialize($arguments); // Generate a cache id - if (!$this->_fileNameProtection) { - $id = md5($id); - // if fileNameProtection is set to false, then the id has to be hashed - // because it's a very bad file name in most cases - } - return $id; - } - -} diff --git a/data/module/Cache/Lite/NestedOutput.php b/data/module/Cache/Lite/NestedOutput.php deleted file mode 100644 index 81ece30d63..0000000000 --- a/data/module/Cache/Lite/NestedOutput.php +++ /dev/null @@ -1,56 +0,0 @@ - -*/ - -require_once('Cache/Lite/Output.php'); - -class Cache_Lite_NestedOutput extends Cache_Lite_Output -{ - private $nestedIds = array(); - private $nestedGroups = array(); - - /** - * Start the cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return boolean|string false if the cache is not hit else the data - * @access public - */ - function start($id, $group = 'default', $doNotTestCacheValidity = false) - { - $this->nestedIds[] = $id; - $this->nestedGroups[] = $group; - $data = $this->get($id, $group, $doNotTestCacheValidity); - if ($data !== false) { - return $data; - } - ob_start(); - ob_implicit_flush(false); - return false; - } - - /** - * Stop the cache - * - * @param boolen - * @return string return contents of cache - */ - function end() - { - $data = ob_get_contents(); - ob_end_clean(); - $id = array_pop($this->nestedIds); - $group = array_pop($this->nestedGroups); - $this->save($data, $id, $group); - return $data; - } - -} diff --git a/data/module/Cache/Lite/Output.php b/data/module/Cache/Lite/Output.php deleted file mode 100644 index 87d7c19d8e..0000000000 --- a/data/module/Cache/Lite/Output.php +++ /dev/null @@ -1,68 +0,0 @@ - -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_Output extends Cache_Lite -{ - - // --- Public methods --- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * @param array $options options - * @access public - */ - function Cache_Lite_Output($options) - { - $this->Cache_Lite($options); - } - - /** - * Start the cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return boolean true if the cache is hit (false else) - * @access public - */ - function start($id, $group = 'default', $doNotTestCacheValidity = false) - { - $data = $this->get($id, $group, $doNotTestCacheValidity); - if ($data !== false) { - echo($data); - return true; - } - ob_start(); - ob_implicit_flush(false); - return false; - } - - /** - * Stop the cache - * - * @access public - */ - function end() - { - $data = ob_get_contents(); - ob_end_clean(); - $this->save($data, $this->_id, $this->_group); - echo($data); - } - -} diff --git a/data/module/HTTP/Request.php b/data/module/HTTP/Request.php index ef6109f22a..912096f85a 100644 --- a/data/module/HTTP/Request.php +++ b/data/module/HTTP/Request.php @@ -409,7 +409,7 @@ function reset($url, $params = array()) */ function setURL($url) { - $this->_url = &new Net_URL($url, $this->_useBrackets); + $this->_url = new Net_URL($url, $this->_useBrackets); if (!empty($this->_url->user) || !empty($this->_url->pass)) { $this->setBasicAuth($this->_url->user, $this->_url->pass); @@ -559,13 +559,13 @@ function addPostData($name, $value, $preencoded = false) $this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value); } } - + function addPostDataArray($array, $preencoded = false) { foreach($array as $key => $val){ $this->addPostData($key, $val, $preencoded); } - } + } /** * Recursively applies the callback function to the value @@ -740,7 +740,7 @@ function sendRequest($saveBody = true) $err = null; } else { $this->_notify('connect'); - $this->_sock =& new Net_Socket(); + $this->_sock = new Net_Socket(); $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions); } PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest()); @@ -753,7 +753,7 @@ function sendRequest($saveBody = true) $this->_notify('sentRequest'); // Read the response - $this->_response = &new HTTP_Response($this->_sock, $this->_listeners); + $this->_response = new HTTP_Response($this->_sock, $this->_listeners); $err = $this->_response->process( $this->_saveBody && $saveBody, HTTP_REQUEST_METHOD_HEAD != $this->_method @@ -798,7 +798,7 @@ function sendRequest($saveBody = true) // Absolute URL if (preg_match('/^https?:\/\//i', $redirect)) { - $this->_url = &new Net_URL($redirect); + $this->_url = new Net_URL($redirect); $this->addHeader('Host', $this->_generateHostHeader()); // Absolute path } elseif ($redirect{0} == '/') { diff --git a/data/module/Mail.php b/data/module/Mail.php deleted file mode 100644 index 75132ac2a6..0000000000 --- a/data/module/Mail.php +++ /dev/null @@ -1,270 +0,0 @@ - - * @copyright 1997-2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $ - * @link http://pear.php.net/package/Mail/ - */ - -require_once 'PEAR.php'; - -/** - * PEAR's Mail:: interface. Defines the interface for implementing - * mailers under the PEAR hierarchy, and provides supporting functions - * useful in multiple mailer backends. - * - * @access public - * @version $Revision: 294747 $ - * @package Mail - */ -class Mail -{ - /** - * Line terminator used for separating header lines. - * @var string - */ - var $sep = "\r\n"; - - /** - * Provides an interface for generating Mail:: objects of various - * types - * - * @param string $driver The kind of Mail:: object to instantiate. - * @param array $params The parameters to pass to the Mail:: object. - * @return object Mail a instance of the driver class or if fails a PEAR Error - * @access public - */ - function &factory($driver, $params = array()) - { - $driver = strtolower($driver); - @include_once 'Mail/' . $driver . '.php'; - $class = 'Mail_' . $driver; - if (class_exists($class)) { - $mailer = new $class($params); - return $mailer; - } else { - return PEAR::raiseError('Unable to find class for driver ' . $driver); - } - } - - /** - * Implements Mail::send() function using php's built-in mail() - * command. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (ie, 'Subject'), and the array value - * is the header value (ie, 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * Mime parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * - * @access public - * @deprecated use Mail_mail::send instead - */ - function send($recipients, $headers, $body) - { - if (!is_array($headers)) { - return PEAR::raiseError('$headers must be an array'); - } - - $result = $this->_sanitizeHeaders($headers); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - // if we're passed an array of recipients, implode it. - if (is_array($recipients)) { - $recipients = implode(', ', $recipients); - } - - // get the Subject out of the headers array so that we can - // pass it as a seperate argument to mail(). - $subject = ''; - if (isset($headers['Subject'])) { - $subject = $headers['Subject']; - unset($headers['Subject']); - } - - // flatten the headers out. - list(, $text_headers) = Mail::prepareHeaders($headers); - - return mail($recipients, $subject, $body, $text_headers); - } - - /** - * Sanitize an array of mail headers by removing any additional header - * strings present in a legitimate header's value. The goal of this - * filter is to prevent mail injection attacks. - * - * @param array $headers The associative array of headers to sanitize. - * - * @access private - */ - function _sanitizeHeaders(&$headers) - { - foreach ($headers as $key => $value) { - $headers[$key] = - preg_replace('=((||0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i', - null, $value); - } - } - - /** - * Take an array of mail headers and return a string containing - * text usable in sending a message. - * - * @param array $headers The array of headers to prepare, in an associative - * array, where the array key is the header name (ie, - * 'Subject'), and the array value is the header - * value (ie, 'test'). The header produced from those - * values would be 'Subject: test'. - * - * @return mixed Returns false if it encounters a bad address, - * otherwise returns an array containing two - * elements: Any From: address found in the headers, - * and the plain text version of the headers. - * @access private - */ - function prepareHeaders($headers) - { - $lines = array(); - $from = null; - - foreach ($headers as $key => $value) { - if (strcasecmp($key, 'From') === 0) { - include_once 'Mail/RFC822.php'; - $parser = new Mail_RFC822(); - $addresses = $parser->parseAddressList($value, 'localhost', false); - if (is_a($addresses, 'PEAR_Error')) { - return $addresses; - } - - $from = $addresses[0]->mailbox . '@' . $addresses[0]->host; - - // Reject envelope From: addresses with spaces. - if (strstr($from, ' ')) { - return false; - } - - $lines[] = $key . ': ' . $value; - } elseif (strcasecmp($key, 'Received') === 0) { - $received = array(); - if (is_array($value)) { - foreach ($value as $line) { - $received[] = $key . ': ' . $line; - } - } - else { - $received[] = $key . ': ' . $value; - } - // Put Received: headers at the top. Spam detectors often - // flag messages with Received: headers after the Subject: - // as spam. - $lines = array_merge($received, $lines); - } else { - // If $value is an array (i.e., a list of addresses), convert - // it to a comma-delimited string of its elements (addresses). - if (is_array($value)) { - $value = implode(', ', $value); - } - $lines[] = $key . ': ' . $value; - } - } - - return array($from, join($this->sep, $lines)); - } - - /** - * Take a set of recipients and parse them, returning an array of - * bare addresses (forward paths) that can be passed to sendmail - * or an smtp server with the rcpt to: command. - * - * @param mixed Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. - * - * @return mixed An array of forward paths (bare addresses) or a PEAR_Error - * object if the address list could not be parsed. - * @access private - */ - function parseRecipients($recipients) - { - include_once 'Mail/RFC822.php'; - - // if we're passed an array, assume addresses are valid and - // implode them before parsing. - if (is_array($recipients)) { - $recipients = implode(', ', $recipients); - } - - // Parse recipients, leaving out all personal info. This is - // for smtp recipients, etc. All relevant personal information - // should already be in the headers. - $addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false); - - // If parseAddressList() returned a PEAR_Error object, just return it. - if (is_a($addresses, 'PEAR_Error')) { - return $addresses; - } - - $recipients = array(); - if (is_array($addresses)) { - foreach ($addresses as $ob) { - $recipients[] = $ob->mailbox . '@' . $ob->host; - } - } - - return $recipients; - } - -} diff --git a/data/module/Mail/RFC822.php b/data/module/Mail/RFC822.php deleted file mode 100644 index 58d36465cb..0000000000 --- a/data/module/Mail/RFC822.php +++ /dev/null @@ -1,951 +0,0 @@ - - * @author Chuck Hagenbuch - * @author Chuck Hagenbuch - * @version $Revision: 294749 $ - * @license BSD - * @package Mail - */ -class Mail_RFC822 { - - /** - * The address being parsed by the RFC822 object. - * @var string $address - */ - var $address = ''; - - /** - * The default domain to use for unqualified addresses. - * @var string $default_domain - */ - var $default_domain = 'localhost'; - - /** - * Should we return a nested array showing groups, or flatten everything? - * @var boolean $nestGroups - */ - var $nestGroups = true; - - /** - * Whether or not to validate atoms for non-ascii characters. - * @var boolean $validate - */ - var $validate = true; - - /** - * The array of raw addresses built up as we parse. - * @var array $addresses - */ - var $addresses = array(); - - /** - * The final array of parsed address information that we build up. - * @var array $structure - */ - var $structure = array(); - - /** - * The current error message, if any. - * @var string $error - */ - var $error = null; - - /** - * An internal counter/pointer. - * @var integer $index - */ - var $index = null; - - /** - * The number of groups that have been found in the address list. - * @var integer $num_groups - * @access public - */ - var $num_groups = 0; - - /** - * A variable so that we can tell whether or not we're inside a - * Mail_RFC822 object. - * @var boolean $mailRFC822 - */ - var $mailRFC822 = true; - - /** - * A limit after which processing stops - * @var int $limit - */ - var $limit = null; - - /** - * Sets up the object. The address must either be set here or when - * calling parseAddressList(). One or the other. - * - * @access public - * @param string $address The address(es) to validate. - * @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost. - * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. - * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. - * - * @return object Mail_RFC822 A new Mail_RFC822 object. - */ - function Mail_RFC822($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) - { - if (isset($address)) $this->address = $address; - if (isset($default_domain)) $this->default_domain = $default_domain; - if (isset($nest_groups)) $this->nestGroups = $nest_groups; - if (isset($validate)) $this->validate = $validate; - if (isset($limit)) $this->limit = $limit; - } - - /** - * Starts the whole process. The address must either be set here - * or when creating the object. One or the other. - * - * @access public - * @param string $address The address(es) to validate. - * @param string $default_domain Default domain/host etc. - * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. - * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. - * - * @return array A structured array of addresses. - */ - function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) - { - if (!isset($this) || !isset($this->mailRFC822)) { - $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); - return $obj->parseAddressList(); - } - - if (isset($address)) $this->address = $address; - if (isset($default_domain)) $this->default_domain = $default_domain; - if (isset($nest_groups)) $this->nestGroups = $nest_groups; - if (isset($validate)) $this->validate = $validate; - if (isset($limit)) $this->limit = $limit; - - $this->structure = array(); - $this->addresses = array(); - $this->error = null; - $this->index = null; - - // Unfold any long lines in $this->address. - $this->address = preg_replace('/\r?\n/', "\r\n", $this->address); - $this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address); - - while ($this->address = $this->_splitAddresses($this->address)); - - if ($this->address === false || isset($this->error)) { - require_once 'PEAR.php'; - return PEAR::raiseError($this->error); - } - - // Validate each address individually. If we encounter an invalid - // address, stop iterating and return an error immediately. - foreach ($this->addresses as $address) { - $valid = $this->_validateAddress($address); - - if ($valid === false || isset($this->error)) { - require_once 'PEAR.php'; - return PEAR::raiseError($this->error); - } - - if (!$this->nestGroups) { - $this->structure = array_merge($this->structure, $valid); - } else { - $this->structure[] = $valid; - } - } - - return $this->structure; - } - - /** - * Splits an address into separate addresses. - * - * @access private - * @param string $address The addresses to split. - * @return boolean Success or failure. - */ - function _splitAddresses($address) - { - if (!empty($this->limit) && count($this->addresses) == $this->limit) { - return ''; - } - - if ($this->_isGroup($address) && !isset($this->error)) { - $split_char = ';'; - $is_group = true; - } elseif (!isset($this->error)) { - $split_char = ','; - $is_group = false; - } elseif (isset($this->error)) { - return false; - } - - // Split the string based on the above ten or so lines. - $parts = explode($split_char, $address); - $string = $this->_splitCheck($parts, $split_char); - - // If a group... - if ($is_group) { - // If $string does not contain a colon outside of - // brackets/quotes etc then something's fubar. - - // First check there's a colon at all: - if (strpos($string, ':') === false) { - $this->error = 'Invalid address: ' . $string; - return false; - } - - // Now check it's outside of brackets/quotes: - if (!$this->_splitCheck(explode(':', $string), ':')) { - return false; - } - - // We must have a group at this point, so increase the counter: - $this->num_groups++; - } - - // $string now contains the first full address/group. - // Add to the addresses array. - $this->addresses[] = array( - 'address' => trim($string), - 'group' => $is_group - ); - - // Remove the now stored address from the initial line, the +1 - // is to account for the explode character. - $address = trim(substr($address, strlen($string) + 1)); - - // If the next char is a comma and this was a group, then - // there are more addresses, otherwise, if there are any more - // chars, then there is another address. - if ($is_group && substr($address, 0, 1) == ','){ - $address = trim(substr($address, 1)); - return $address; - - } elseif (strlen($address) > 0) { - return $address; - - } else { - return ''; - } - - // If you got here then something's off - return false; - } - - /** - * Checks for a group at the start of the string. - * - * @access private - * @param string $address The address to check. - * @return boolean Whether or not there is a group at the start of the string. - */ - function _isGroup($address) - { - // First comma not in quotes, angles or escaped: - $parts = explode(',', $address); - $string = $this->_splitCheck($parts, ','); - - // Now we have the first address, we can reliably check for a - // group by searching for a colon that's not escaped or in - // quotes or angle brackets. - if (count($parts = explode(':', $string)) > 1) { - $string2 = $this->_splitCheck($parts, ':'); - return ($string2 !== $string); - } else { - return false; - } - } - - /** - * A common function that will check an exploded string. - * - * @access private - * @param array $parts The exloded string. - * @param string $char The char that was exploded on. - * @return mixed False if the string contains unclosed quotes/brackets, or the string on success. - */ - function _splitCheck($parts, $char) - { - $string = $parts[0]; - - for ($i = 0; $i < count($parts); $i++) { - if ($this->_hasUnclosedQuotes($string) - || $this->_hasUnclosedBrackets($string, '<>') - || $this->_hasUnclosedBrackets($string, '[]') - || $this->_hasUnclosedBrackets($string, '()') - || substr($string, -1) == '\\') { - if (isset($parts[$i + 1])) { - $string = $string . $char . $parts[$i + 1]; - } else { - $this->error = 'Invalid address spec. Unclosed bracket or quotes'; - return false; - } - } else { - $this->index = $i; - break; - } - } - - return $string; - } - - /** - * Checks if a string has unclosed quotes or not. - * - * @access private - * @param string $string The string to check. - * @return boolean True if there are unclosed quotes inside the string, - * false otherwise. - */ - function _hasUnclosedQuotes($string) - { - $string = trim($string); - $iMax = strlen($string); - $in_quote = false; - $i = $slashes = 0; - - for (; $i < $iMax; ++$i) { - switch ($string[$i]) { - case '\\': - ++$slashes; - break; - - case '"': - if ($slashes % 2 == 0) { - $in_quote = !$in_quote; - } - // Fall through to default action below. - - default: - $slashes = 0; - break; - } - } - - return $in_quote; - } - - /** - * Checks if a string has an unclosed brackets or not. IMPORTANT: - * This function handles both angle brackets and square brackets; - * - * @access private - * @param string $string The string to check. - * @param string $chars The characters to check for. - * @return boolean True if there are unclosed brackets inside the string, false otherwise. - */ - function _hasUnclosedBrackets($string, $chars) - { - $num_angle_start = substr_count($string, $chars[0]); - $num_angle_end = substr_count($string, $chars[1]); - - $this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]); - $this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]); - - if ($num_angle_start < $num_angle_end) { - $this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')'; - return false; - } else { - return ($num_angle_start > $num_angle_end); - } - } - - /** - * Sub function that is used only by hasUnclosedBrackets(). - * - * @access private - * @param string $string The string to check. - * @param integer &$num The number of occurences. - * @param string $char The character to count. - * @return integer The number of occurences of $char in $string, adjusted for backslashes. - */ - function _hasUnclosedBracketsSub($string, &$num, $char) - { - $parts = explode($char, $string); - for ($i = 0; $i < count($parts); $i++){ - if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i])) - $num--; - if (isset($parts[$i + 1])) - $parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1]; - } - - return $num; - } - - /** - * Function to begin checking the address. - * - * @access private - * @param string $address The address to validate. - * @return mixed False on failure, or a structured array of address information on success. - */ - function _validateAddress($address) - { - $is_group = false; - $addresses = array(); - - if ($address['group']) { - $is_group = true; - - // Get the group part of the name - $parts = explode(':', $address['address']); - $groupname = $this->_splitCheck($parts, ':'); - $structure = array(); - - // And validate the group part of the name. - if (!$this->_validatePhrase($groupname)){ - $this->error = 'Group name did not validate.'; - return false; - } else { - // Don't include groups if we are not nesting - // them. This avoids returning invalid addresses. - if ($this->nestGroups) { - $structure = new stdClass; - $structure->groupname = $groupname; - } - } - - $address['address'] = ltrim(substr($address['address'], strlen($groupname . ':'))); - } - - // If a group then split on comma and put into an array. - // Otherwise, Just put the whole address in an array. - if ($is_group) { - while (strlen($address['address']) > 0) { - $parts = explode(',', $address['address']); - $addresses[] = $this->_splitCheck($parts, ','); - $address['address'] = trim(substr($address['address'], strlen(end($addresses) . ','))); - } - } else { - $addresses[] = $address['address']; - } - - // Check that $addresses is set, if address like this: - // Groupname:; - // Then errors were appearing. - if (!count($addresses)){ - $this->error = 'Empty group.'; - return false; - } - - // Trim the whitespace from all of the address strings. - array_map('trim', $addresses); - - // Validate each mailbox. - // Format could be one of: name - // geezer@domain.com - // geezer - // ... or any other format valid by RFC 822. - for ($i = 0; $i < count($addresses); $i++) { - if (!$this->validateMailbox($addresses[$i])) { - if (empty($this->error)) { - $this->error = 'Validation failed for: ' . $addresses[$i]; - } - return false; - } - } - - // Nested format - if ($this->nestGroups) { - if ($is_group) { - $structure->addresses = $addresses; - } else { - $structure = $addresses[0]; - } - - // Flat format - } else { - if ($is_group) { - $structure = array_merge($structure, $addresses); - } else { - $structure = $addresses; - } - } - - return $structure; - } - - /** - * Function to validate a phrase. - * - * @access private - * @param string $phrase The phrase to check. - * @return boolean Success or failure. - */ - function _validatePhrase($phrase) - { - // Splits on one or more Tab or space. - $parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY); - - $phrase_parts = array(); - while (count($parts) > 0){ - $phrase_parts[] = $this->_splitCheck($parts, ' '); - for ($i = 0; $i < $this->index + 1; $i++) - array_shift($parts); - } - - foreach ($phrase_parts as $part) { - // If quoted string: - if (substr($part, 0, 1) == '"') { - if (!$this->_validateQuotedString($part)) { - return false; - } - continue; - } - - // Otherwise it's an atom: - if (!$this->_validateAtom($part)) return false; - } - - return true; - } - - /** - * Function to validate an atom which from rfc822 is: - * atom = 1* - * - * If validation ($this->validate) has been turned off, then - * validateAtom() doesn't actually check anything. This is so that you - * can split a list of addresses up before encoding personal names - * (umlauts, etc.), for example. - * - * @access private - * @param string $atom The string to check. - * @return boolean Success or failure. - */ - function _validateAtom($atom) - { - if (!$this->validate) { - // Validation has been turned off; assume the atom is okay. - return true; - } - - // Check for any char from ASCII 0 - ASCII 127 - if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) { - return false; - } - - // Check for specials: - if (preg_match('/[][()<>@,;\\:". ]/', $atom)) { - return false; - } - - // Check for control characters (ASCII 0-31): - if (preg_match('/[\\x00-\\x1F]+/', $atom)) { - return false; - } - - return true; - } - - /** - * Function to validate quoted string, which is: - * quoted-string = <"> *(qtext/quoted-pair) <"> - * - * @access private - * @param string $qstring The string to check - * @return boolean Success or failure. - */ - function _validateQuotedString($qstring) - { - // Leading and trailing " - $qstring = substr($qstring, 1, -1); - - // Perform check, removing quoted characters first. - return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring)); - } - - /** - * Function to validate a mailbox, which is: - * mailbox = addr-spec ; simple address - * / phrase route-addr ; name and route-addr - * - * @access public - * @param string &$mailbox The string to check. - * @return boolean Success or failure. - */ - function validateMailbox(&$mailbox) - { - // A couple of defaults. - $phrase = ''; - $comment = ''; - $comments = array(); - - // Catch any RFC822 comments and store them separately. - $_mailbox = $mailbox; - while (strlen(trim($_mailbox)) > 0) { - $parts = explode('(', $_mailbox); - $before_comment = $this->_splitCheck($parts, '('); - if ($before_comment != $_mailbox) { - // First char should be a (. - $comment = substr(str_replace($before_comment, '', $_mailbox), 1); - $parts = explode(')', $comment); - $comment = $this->_splitCheck($parts, ')'); - $comments[] = $comment; - - // +2 is for the brackets - $_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2); - } else { - break; - } - } - - foreach ($comments as $comment) { - $mailbox = str_replace("($comment)", '', $mailbox); - } - - $mailbox = trim($mailbox); - - // Check for name + route-addr - if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') { - $parts = explode('<', $mailbox); - $name = $this->_splitCheck($parts, '<'); - - $phrase = trim($name); - $route_addr = trim(substr($mailbox, strlen($name.'<'), -1)); - - if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) { - return false; - } - - // Only got addr-spec - } else { - // First snip angle brackets if present. - if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') { - $addr_spec = substr($mailbox, 1, -1); - } else { - $addr_spec = $mailbox; - } - - if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { - return false; - } - } - - // Construct the object that will be returned. - $mbox = new stdClass(); - - // Add the phrase (even if empty) and comments - $mbox->personal = $phrase; - $mbox->comment = isset($comments) ? $comments : array(); - - if (isset($route_addr)) { - $mbox->mailbox = $route_addr['local_part']; - $mbox->host = $route_addr['domain']; - $route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : ''; - } else { - $mbox->mailbox = $addr_spec['local_part']; - $mbox->host = $addr_spec['domain']; - } - - $mailbox = $mbox; - return true; - } - - /** - * This function validates a route-addr which is: - * route-addr = "<" [route] addr-spec ">" - * - * Angle brackets have already been removed at the point of - * getting to this function. - * - * @access private - * @param string $route_addr The string to check. - * @return mixed False on failure, or an array containing validated address/route information on success. - */ - function _validateRouteAddr($route_addr) - { - // Check for colon. - if (strpos($route_addr, ':') !== false) { - $parts = explode(':', $route_addr); - $route = $this->_splitCheck($parts, ':'); - } else { - $route = $route_addr; - } - - // If $route is same as $route_addr then the colon was in - // quotes or brackets or, of course, non existent. - if ($route === $route_addr){ - unset($route); - $addr_spec = $route_addr; - if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { - return false; - } - } else { - // Validate route part. - if (($route = $this->_validateRoute($route)) === false) { - return false; - } - - $addr_spec = substr($route_addr, strlen($route . ':')); - - // Validate addr-spec part. - if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) { - return false; - } - } - - if (isset($route)) { - $return['adl'] = $route; - } else { - $return['adl'] = ''; - } - - $return = array_merge($return, $addr_spec); - return $return; - } - - /** - * Function to validate a route, which is: - * route = 1#("@" domain) ":" - * - * @access private - * @param string $route The string to check. - * @return mixed False on failure, or the validated $route on success. - */ - function _validateRoute($route) - { - // Split on comma. - $domains = explode(',', trim($route)); - - foreach ($domains as $domain) { - $domain = str_replace('@', '', trim($domain)); - if (!$this->_validateDomain($domain)) return false; - } - - return $route; - } - - /** - * Function to validate a domain, though this is not quite what - * you expect of a strict internet domain. - * - * domain = sub-domain *("." sub-domain) - * - * @access private - * @param string $domain The string to check. - * @return mixed False on failure, or the validated domain on success. - */ - function _validateDomain($domain) - { - // Note the different use of $subdomains and $sub_domains - $subdomains = explode('.', $domain); - - while (count($subdomains) > 0) { - $sub_domains[] = $this->_splitCheck($subdomains, '.'); - for ($i = 0; $i < $this->index + 1; $i++) - array_shift($subdomains); - } - - foreach ($sub_domains as $sub_domain) { - if (!$this->_validateSubdomain(trim($sub_domain))) - return false; - } - - // Managed to get here, so return input. - return $domain; - } - - /** - * Function to validate a subdomain: - * subdomain = domain-ref / domain-literal - * - * @access private - * @param string $subdomain The string to check. - * @return boolean Success or failure. - */ - function _validateSubdomain($subdomain) - { - if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){ - if (!$this->_validateDliteral($arr[1])) return false; - } else { - if (!$this->_validateAtom($subdomain)) return false; - } - - // Got here, so return successful. - return true; - } - - /** - * Function to validate a domain literal: - * domain-literal = "[" *(dtext / quoted-pair) "]" - * - * @access private - * @param string $dliteral The string to check. - * @return boolean Success or failure. - */ - function _validateDliteral($dliteral) - { - return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\'; - } - - /** - * Function to validate an addr-spec. - * - * addr-spec = local-part "@" domain - * - * @access private - * @param string $addr_spec The string to check. - * @return mixed False on failure, or the validated addr-spec on success. - */ - function _validateAddrSpec($addr_spec) - { - $addr_spec = trim($addr_spec); - - // Split on @ sign if there is one. - if (strpos($addr_spec, '@') !== false) { - $parts = explode('@', $addr_spec); - $local_part = $this->_splitCheck($parts, '@'); - $domain = substr($addr_spec, strlen($local_part . '@')); - - // No @ sign so assume the default domain. - } else { - $local_part = $addr_spec; - $domain = $this->default_domain; - } - - if (($local_part = $this->_validateLocalPart($local_part)) === false) return false; - if (($domain = $this->_validateDomain($domain)) === false) return false; - - // Got here so return successful. - return array('local_part' => $local_part, 'domain' => $domain); - } - - /** - * Function to validate the local part of an address: - * local-part = word *("." word) - * - * @access private - * @param string $local_part - * @return mixed False on failure, or the validated local part on success. - */ - function _validateLocalPart($local_part) - { - $parts = explode('.', $local_part); - $words = array(); - - // Split the local_part into words. - while (count($parts) > 0){ - $words[] = $this->_splitCheck($parts, '.'); - for ($i = 0; $i < $this->index + 1; $i++) { - array_shift($parts); - } - } - - // Validate each word. - foreach ($words as $word) { - // If this word contains an unquoted space, it is invalid. (6.2.4) - if (strpos($word, ' ') && $word[0] !== '"') - { - return false; - } - - if ($this->_validatePhrase(trim($word)) === false) return false; - } - - // Managed to get here, so return the input. - return $local_part; - } - - /** - * Returns an approximate count of how many addresses are in the - * given string. This is APPROXIMATE as it only splits based on a - * comma which has no preceding backslash. Could be useful as - * large amounts of addresses will end up producing *large* - * structures when used with parseAddressList(). - * - * @param string $data Addresses to count - * @return int Approximate count - */ - function approximateCount($data) - { - return count(preg_split('/(?@. This can be sufficient for most - * people. Optional stricter mode can be utilised which restricts - * mailbox characters allowed to alphanumeric, full stop, hyphen - * and underscore. - * - * @param string $data Address to check - * @param boolean $strict Optional stricter mode - * @return mixed False if it fails, an indexed array - * username/domain if it matches - */ - function isValidInetAddress($data, $strict = false) - { - $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i'; - if (preg_match($regex, trim($data), $matches)) { - return array($matches[1], $matches[2]); - } else { - return false; - } - } - -} diff --git a/data/module/Mail/mail.php b/data/module/Mail/mail.php deleted file mode 100644 index 1754706425..0000000000 --- a/data/module/Mail/mail.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Mail/ - */ - -/** - * internal PHP-mail() implementation of the PEAR Mail:: interface. - * @package Mail - * @version $Revision$ - */ -class Mail_mail extends Mail { - - /** - * Any arguments to pass to the mail() function. - * @var string - */ - var $_params = ''; - - /** - * Constructor. - * - * Instantiates a new Mail_mail:: object based on the parameters - * passed in. - * - * @param array $params Extra arguments for the mail() function. - */ - function Mail_mail($params = null) - { - // The other mail implementations accept parameters as arrays. - // In the interest of being consistent, explode an array into - // a string of parameter arguments. - if (is_array($params)) { - $this->_params = join(' ', $params); - } else { - $this->_params = $params; - } - - /* Because the mail() function may pass headers as command - * line arguments, we can't guarantee the use of the standard - * "\r\n" separator. Instead, we use the system's native line - * separator. */ - if (defined('PHP_EOL')) { - $this->sep = PHP_EOL; - } else { - $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; - } - } - - /** - * Implements Mail_mail::send() function using php's built-in mail() - * command. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (ie, 'Subject'), and the array value - * is the header value (ie, 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * Mime parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * - * @access public - */ - function send($recipients, $headers, $body) - { - if (!is_array($headers)) { - return PEAR::raiseError('$headers must be an array'); - } - - $result = $this->_sanitizeHeaders($headers); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - // If we're passed an array of recipients, implode it. - if (is_array($recipients)) { - $recipients = implode(', ', $recipients); - } - - // Get the Subject out of the headers array so that we can - // pass it as a seperate argument to mail(). - $subject = ''; - if (isset($headers['Subject'])) { - $subject = $headers['Subject']; - unset($headers['Subject']); - } - - // Also remove the To: header. The mail() function will add its own - // To: header based on the contents of $recipients. - unset($headers['To']); - - // Flatten the headers out. - $headerElements = $this->prepareHeaders($headers); - if (is_a($headerElements, 'PEAR_Error')) { - return $headerElements; - } - list(, $text_headers) = $headerElements; - - // We only use mail()'s optional fifth parameter if the additional - // parameters have been provided and we're not running in safe mode. - if (empty($this->_params) || ini_get('safe_mode')) { - $result = mail($recipients, $subject, $body, $text_headers); - } else { - $result = mail($recipients, $subject, $body, $text_headers, - $this->_params); - } - - // If the mail() function returned failure, we need to create a - // PEAR_Error object and return it instead of the boolean result. - if ($result === false) { - $result = PEAR::raiseError('mail() returned failure'); - } - - return $result; - } - -} diff --git a/data/module/Mail/mime.php b/data/module/Mail/mime.php deleted file mode 100644 index c5dd305fab..0000000000 --- a/data/module/Mail/mime.php +++ /dev/null @@ -1,1468 +0,0 @@ - - * Copyright (c) 2003-2006, PEAR - * 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 the authors, 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 Mail - * @package Mail_Mime - * @author Richard Heyes - * @author Tomas V.V. Cox - * @author Cipriano Groenendal - * @author Sean Coates - * @author Aleksander Machniak - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Mail_mime - * - * This class is based on HTML Mime Mail class from - * Richard Heyes which was based also - * in the mime_mail.class by Tobias Ratschiller - * and Sascha Schumann - */ - - -/** - * require PEAR - * - * This package depends on PEAR to raise errors. - */ -require_once 'PEAR.php'; - -/** - * require Mail_mimePart - * - * Mail_mimePart contains the code required to - * create all the different parts a mail can - * consist of. - */ -require_once 'Mail/mimePart.php'; - - -/** - * The Mail_Mime class provides an OO interface to create MIME - * enabled email messages. This way you can create emails that - * contain plain-text bodies, HTML bodies, attachments, inline - * images and specific headers. - * - * @category Mail - * @package Mail_Mime - * @author Richard Heyes - * @author Tomas V.V. Cox - * @author Cipriano Groenendal - * @author Sean Coates - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/Mail_mime - */ -class Mail_mime -{ - /** - * Contains the plain text part of the email - * - * @var string - * @access private - */ - var $_txtbody; - - /** - * Contains the html part of the email - * - * @var string - * @access private - */ - var $_htmlbody; - - /** - * list of the attached images - * - * @var array - * @access private - */ - var $_html_images = array(); - - /** - * list of the attachements - * - * @var array - * @access private - */ - var $_parts = array(); - - /** - * Headers for the mail - * - * @var array - * @access private - */ - var $_headers = array(); - - /** - * Build parameters - * - * @var array - * @access private - */ - var $_build_params = array( - // What encoding to use for the headers - // Options: quoted-printable or base64 - 'head_encoding' => 'quoted-printable', - // What encoding to use for plain text - // Options: 7bit, 8bit, base64, or quoted-printable - 'text_encoding' => 'quoted-printable', - // What encoding to use for html - // Options: 7bit, 8bit, base64, or quoted-printable - 'html_encoding' => 'quoted-printable', - // The character set to use for html - 'html_charset' => 'ISO-8859-1', - // The character set to use for text - 'text_charset' => 'ISO-8859-1', - // The character set to use for headers - 'head_charset' => 'ISO-8859-1', - // End-of-line sequence - 'eol' => "\r\n", - // Delay attachment files IO until building the message - 'delay_file_io' => false - ); - - /** - * Constructor function - * - * @param mixed $params Build parameters that change the way the email - * is built. Should be an associative array. - * See $_build_params. - * - * @return void - * @access public - */ - function Mail_mime($params = array()) - { - // Backward-compatible EOL setting - if (is_string($params)) { - $this->_build_params['eol'] = $params; - } else if (defined('MAIL_MIME_CRLF') && !isset($params['eol'])) { - $this->_build_params['eol'] = MAIL_MIME_CRLF; - } - - // Update build parameters - if (!empty($params) && is_array($params)) { - while (list($key, $value) = each($params)) { - $this->_build_params[$key] = $value; - } - } - } - - /** - * Set build parameter value - * - * @param string $name Parameter name - * @param string $value Parameter value - * - * @return void - * @access public - * @since 1.6.0 - */ - function setParam($name, $value) - { - $this->_build_params[$name] = $value; - } - - /** - * Get build parameter value - * - * @param string $name Parameter name - * - * @return mixed Parameter value - * @access public - * @since 1.6.0 - */ - function getParam($name) - { - return isset($this->_build_params[$name]) ? $this->_build_params[$name] : null; - } - - /** - * Accessor function to set the body text. Body text is used if - * it's not an html mail being sent or else is used to fill the - * text/plain part that emails clients who don't support - * html should show. - * - * @param string $data Either a string or - * the file name with the contents - * @param bool $isfile If true the first param should be treated - * as a file name, else as a string (default) - * @param bool $append If true the text or file is appended to - * the existing body, else the old body is - * overwritten - * - * @return mixed True on success or PEAR_Error object - * @access public - */ - function setTXTBody($data, $isfile = false, $append = false) - { - if (!$isfile) { - if (!$append) { - $this->_txtbody = $data; - } else { - $this->_txtbody .= $data; - } - } else { - $cont = $this->_file2str($data); - if (PEAR::isError($cont)) { - return $cont; - } - if (!$append) { - $this->_txtbody = $cont; - } else { - $this->_txtbody .= $cont; - } - } - return true; - } - - /** - * Get message text body - * - * @return string Text body - * @access public - * @since 1.6.0 - */ - function getTXTBody() - { - return $this->_txtbody; - } - - /** - * Adds a html part to the mail. - * - * @param string $data Either a string or the file name with the - * contents - * @param bool $isfile A flag that determines whether $data is a - * filename, or a string(false, default) - * - * @return bool True on success - * @access public - */ - function setHTMLBody($data, $isfile = false) - { - if (!$isfile) { - $this->_htmlbody = $data; - } else { - $cont = $this->_file2str($data); - if (PEAR::isError($cont)) { - return $cont; - } - $this->_htmlbody = $cont; - } - - return true; - } - - /** - * Get message HTML body - * - * @return string HTML body - * @access public - * @since 1.6.0 - */ - function getHTMLBody() - { - return $this->_htmlbody; - } - - /** - * Adds an image to the list of embedded images. - * - * @param string $file The image file name OR image data itself - * @param string $c_type The content type - * @param string $name The filename of the image. - * Only used if $file is the image data. - * @param bool $isfile Whether $file is a filename or not. - * Defaults to true - * @param string $content_id Desired Content-ID of MIME part - * Defaults to generated unique ID - * - * @return bool True on success - * @access public - */ - function addHTMLImage($file, - $c_type='application/octet-stream', - $name = '', - $isfile = true, - $content_id = null - ) { - $bodyfile = null; - - if ($isfile) { - // Don't load file into memory - if ($this->_build_params['delay_file_io']) { - $filedata = null; - $bodyfile = $file; - } else { - if (PEAR::isError($filedata = $this->_file2str($file))) { - return $filedata; - } - } - $filename = ($name ? $name : $file); - } else { - $filedata = $file; - $filename = $name; - } - - if (!$content_id) { - $content_id = md5(uniqid(time())); - } - - $this->_html_images[] = array( - 'body' => $filedata, - 'body_file' => $bodyfile, - 'name' => $filename, - 'c_type' => $c_type, - 'cid' => $content_id - ); - - return true; - } - - /** - * Adds a file to the list of attachments. - * - * @param string $file The file name of the file to attach - * or the file contents itself - * @param string $c_type The content type - * @param string $name The filename of the attachment - * Only use if $file is the contents - * @param bool $isfile Whether $file is a filename or not. Defaults to true - * @param string $encoding The type of encoding to use. Defaults to base64. - * Possible values: 7bit, 8bit, base64 or quoted-printable. - * @param string $disposition The content-disposition of this file - * Defaults to attachment. - * Possible values: attachment, inline. - * @param string $charset The character set of attachment's content. - * @param string $language The language of the attachment - * @param string $location The RFC 2557.4 location of the attachment - * @param string $n_encoding Encoding of the attachment's name in Content-Type - * By default filenames are encoded using RFC2231 method - * Here you can set RFC2047 encoding (quoted-printable - * or base64) instead - * @param string $f_encoding Encoding of the attachment's filename - * in Content-Disposition header. - * @param string $description Content-Description header - * @param string $h_charset The character set of the headers e.g. filename - * If not specified, $charset will be used - * - * @return mixed True on success or PEAR_Error object - * @access public - */ - function addAttachment($file, - $c_type = 'application/octet-stream', - $name = '', - $isfile = true, - $encoding = 'base64', - $disposition = 'attachment', - $charset = '', - $language = '', - $location = '', - $n_encoding = null, - $f_encoding = null, - $description = '', - $h_charset = null - ) { - $bodyfile = null; - - if ($isfile) { - // Don't load file into memory - if ($this->_build_params['delay_file_io']) { - $filedata = null; - $bodyfile = $file; - } else { - if (PEAR::isError($filedata = $this->_file2str($file))) { - return $filedata; - } - } - // Force the name the user supplied, otherwise use $file - $filename = ($name ? $name : $file); - } else { - $filedata = $file; - $filename = $name; - } - - if (!strlen($filename)) { - $msg = "The supplied filename for the attachment can't be empty"; - $err = PEAR::raiseError($msg); - return $err; - } - $filename = $this->_basename($filename); - - $this->_parts[] = array( - 'body' => $filedata, - 'body_file' => $bodyfile, - 'name' => $filename, - 'c_type' => $c_type, - 'charset' => $charset, - 'encoding' => $encoding, - 'language' => $language, - 'location' => $location, - 'disposition' => $disposition, - 'description' => $description, - 'name_encoding' => $n_encoding, - 'filename_encoding' => $f_encoding, - 'headers_charset' => $h_charset, - ); - - return true; - } - - /** - * Get the contents of the given file name as string - * - * @param string $file_name Path of file to process - * - * @return string Contents of $file_name - * @access private - */ - function &_file2str($file_name) - { - // Check state of file and raise an error properly - if (!file_exists($file_name)) { - $err = PEAR::raiseError('File not found: ' . $file_name); - return $err; - } - if (!is_file($file_name)) { - $err = PEAR::raiseError('Not a regular file: ' . $file_name); - return $err; - } - if (!is_readable($file_name)) { - $err = PEAR::raiseError('File is not readable: ' . $file_name); - return $err; - } - - // Temporarily reset magic_quotes_runtime and read file contents - if ($magic_quote_setting = get_magic_quotes_runtime()) { - @ini_set('magic_quotes_runtime', 0); - } - $cont = file_get_contents($file_name); - if ($magic_quote_setting) { - @ini_set('magic_quotes_runtime', $magic_quote_setting); - } - - return $cont; - } - - /** - * Adds a text subpart to the mimePart object and - * returns it during the build process. - * - * @param mixed &$obj The object to add the part to, or - * null if a new object is to be created. - * @param string $text The text to add. - * - * @return object The text mimePart object - * @access private - */ - function &_addTextPart(&$obj, $text) - { - $params['content_type'] = 'text/plain'; - $params['encoding'] = $this->_build_params['text_encoding']; - $params['charset'] = $this->_build_params['text_charset']; - $params['eol'] = $this->_build_params['eol']; - - if (is_object($obj)) { - $ret = $obj->addSubpart($text, $params); - return $ret; - } else { - $ret = new Mail_mimePart($text, $params); - return $ret; - } - } - - /** - * Adds a html subpart to the mimePart object and - * returns it during the build process. - * - * @param mixed &$obj The object to add the part to, or - * null if a new object is to be created. - * - * @return object The html mimePart object - * @access private - */ - function &_addHtmlPart(&$obj) - { - $params['content_type'] = 'text/html'; - $params['encoding'] = $this->_build_params['html_encoding']; - $params['charset'] = $this->_build_params['html_charset']; - $params['eol'] = $this->_build_params['eol']; - - if (is_object($obj)) { - $ret = $obj->addSubpart($this->_htmlbody, $params); - return $ret; - } else { - $ret = new Mail_mimePart($this->_htmlbody, $params); - return $ret; - } - } - - /** - * Creates a new mimePart object, using multipart/mixed as - * the initial content-type and returns it during the - * build process. - * - * @return object The multipart/mixed mimePart object - * @access private - */ - function &_addMixedPart() - { - $params = array(); - $params['content_type'] = 'multipart/mixed'; - $params['eol'] = $this->_build_params['eol']; - - // Create empty multipart/mixed Mail_mimePart object to return - $ret = new Mail_mimePart('', $params); - return $ret; - } - - /** - * Adds a multipart/alternative part to a mimePart - * object (or creates one), and returns it during - * the build process. - * - * @param mixed &$obj The object to add the part to, or - * null if a new object is to be created. - * - * @return object The multipart/mixed mimePart object - * @access private - */ - function &_addAlternativePart(&$obj) - { - $params['content_type'] = 'multipart/alternative'; - $params['eol'] = $this->_build_params['eol']; - - if (is_object($obj)) { - return $obj->addSubpart('', $params); - } else { - $ret = new Mail_mimePart('', $params); - return $ret; - } - } - - /** - * Adds a multipart/related part to a mimePart - * object (or creates one), and returns it during - * the build process. - * - * @param mixed &$obj The object to add the part to, or - * null if a new object is to be created - * - * @return object The multipart/mixed mimePart object - * @access private - */ - function &_addRelatedPart(&$obj) - { - $params['content_type'] = 'multipart/related'; - $params['eol'] = $this->_build_params['eol']; - - if (is_object($obj)) { - return $obj->addSubpart('', $params); - } else { - $ret = new Mail_mimePart('', $params); - return $ret; - } - } - - /** - * Adds an html image subpart to a mimePart object - * and returns it during the build process. - * - * @param object &$obj The mimePart to add the image to - * @param array $value The image information - * - * @return object The image mimePart object - * @access private - */ - function &_addHtmlImagePart(&$obj, $value) - { - $params['content_type'] = $value['c_type']; - $params['encoding'] = 'base64'; - $params['disposition'] = 'inline'; - $params['filename'] = $value['name']; - $params['cid'] = $value['cid']; - $params['body_file'] = $value['body_file']; - $params['eol'] = $this->_build_params['eol']; - - if (!empty($value['name_encoding'])) { - $params['name_encoding'] = $value['name_encoding']; - } - if (!empty($value['filename_encoding'])) { - $params['filename_encoding'] = $value['filename_encoding']; - } - - $ret = $obj->addSubpart($value['body'], $params); - return $ret; - } - - /** - * Adds an attachment subpart to a mimePart object - * and returns it during the build process. - * - * @param object &$obj The mimePart to add the image to - * @param array $value The attachment information - * - * @return object The image mimePart object - * @access private - */ - function &_addAttachmentPart(&$obj, $value) - { - $params['eol'] = $this->_build_params['eol']; - $params['filename'] = $value['name']; - $params['encoding'] = $value['encoding']; - $params['content_type'] = $value['c_type']; - $params['body_file'] = $value['body_file']; - $params['disposition'] = isset($value['disposition']) ? - $value['disposition'] : 'attachment'; - - // content charset - if (!empty($value['charset'])) { - $params['charset'] = $value['charset']; - } - // headers charset (filename, description) - if (!empty($value['headers_charset'])) { - $params['headers_charset'] = $value['headers_charset']; - } - if (!empty($value['language'])) { - $params['language'] = $value['language']; - } - if (!empty($value['location'])) { - $params['location'] = $value['location']; - } - if (!empty($value['name_encoding'])) { - $params['name_encoding'] = $value['name_encoding']; - } - if (!empty($value['filename_encoding'])) { - $params['filename_encoding'] = $value['filename_encoding']; - } - if (!empty($value['description'])) { - $params['description'] = $value['description']; - } - - $ret = $obj->addSubpart($value['body'], $params); - return $ret; - } - - /** - * Returns the complete e-mail, ready to send using an alternative - * mail delivery method. Note that only the mailpart that is made - * with Mail_Mime is created. This means that, - * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF - * using the $headers parameter! - * - * @param string $separation The separation between these two parts. - * @param array $params The Build parameters passed to the - * &get() function. See &get for more info. - * @param array $headers The extra headers that should be passed - * to the &headers() function. - * See that function for more info. - * @param bool $overwrite Overwrite the existing headers with new. - * - * @return mixed The complete e-mail or PEAR error object - * @access public - */ - function getMessage($separation = null, $params = null, $headers = null, - $overwrite = false - ) { - if ($separation === null) { - $separation = $this->_build_params['eol']; - } - - $body = $this->get($params); - - if (PEAR::isError($body)) { - return $body; - } - - $head = $this->txtHeaders($headers, $overwrite); - $mail = $head . $separation . $body; - return $mail; - } - - /** - * Returns the complete e-mail body, ready to send using an alternative - * mail delivery method. - * - * @param array $params The Build parameters passed to the - * &get() function. See &get for more info. - * - * @return mixed The e-mail body or PEAR error object - * @access public - * @since 1.6.0 - */ - function getMessageBody($params = null) - { - return $this->get($params, null, true); - } - - /** - * Writes (appends) the complete e-mail into file. - * - * @param string $filename Output file location - * @param array $params The Build parameters passed to the - * &get() function. See &get for more info. - * @param array $headers The extra headers that should be passed - * to the &headers() function. - * See that function for more info. - * @param bool $overwrite Overwrite the existing headers with new. - * - * @return mixed True or PEAR error object - * @access public - * @since 1.6.0 - */ - function saveMessage($filename, $params = null, $headers = null, $overwrite = false) - { - // Check state of file and raise an error properly - if (file_exists($filename) && !is_writable($filename)) { - $err = PEAR::raiseError('File is not writable: ' . $filename); - return $err; - } - - // Temporarily reset magic_quotes_runtime and read file contents - if ($magic_quote_setting = get_magic_quotes_runtime()) { - @ini_set('magic_quotes_runtime', 0); - } - - if (!($fh = fopen($filename, 'ab'))) { - $err = PEAR::raiseError('Unable to open file: ' . $filename); - return $err; - } - - // Write message headers into file (skipping Content-* headers) - $head = $this->txtHeaders($headers, $overwrite, true); - if (fwrite($fh, $head) === false) { - $err = PEAR::raiseError('Error writing to file: ' . $filename); - return $err; - } - - fclose($fh); - - if ($magic_quote_setting) { - @ini_set('magic_quotes_runtime', $magic_quote_setting); - } - - // Write the rest of the message into file - $res = $this->get($params, $filename); - - return $res ? $res : true; - } - - /** - * Writes (appends) the complete e-mail body into file. - * - * @param string $filename Output file location - * @param array $params The Build parameters passed to the - * &get() function. See &get for more info. - * - * @return mixed True or PEAR error object - * @access public - * @since 1.6.0 - */ - function saveMessageBody($filename, $params = null) - { - // Check state of file and raise an error properly - if (file_exists($filename) && !is_writable($filename)) { - $err = PEAR::raiseError('File is not writable: ' . $filename); - return $err; - } - - // Temporarily reset magic_quotes_runtime and read file contents - if ($magic_quote_setting = get_magic_quotes_runtime()) { - @ini_set('magic_quotes_runtime', 0); - } - - if (!($fh = fopen($filename, 'ab'))) { - $err = PEAR::raiseError('Unable to open file: ' . $filename); - return $err; - } - - // Write the rest of the message into file - $res = $this->get($params, $filename, true); - - return $res ? $res : true; - } - - /** - * Builds the multipart message from the list ($this->_parts) and - * returns the mime content. - * - * @param array $params Build parameters that change the way the email - * is built. Should be associative. See $_build_params. - * @param resource $filename Output file where to save the message instead of - * returning it - * @param boolean $skip_head True if you want to return/save only the message - * without headers - * - * @return mixed The MIME message content string, null or PEAR error object - * @access public - */ - function &get($params = null, $filename = null, $skip_head = false) - { - if (isset($params)) { - while (list($key, $value) = each($params)) { - $this->_build_params[$key] = $value; - } - } - - if (isset($this->_headers['From'])) { - // Bug #11381: Illegal characters in domain ID - if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $this->_headers['From'], $matches)) { - $domainID = $matches[1]; - } else { - $domainID = '@localhost'; - } - foreach ($this->_html_images as $i => $img) { - $cid = $this->_html_images[$i]['cid']; - if (!preg_match('#'.preg_quote($domainID).'$#', $cid)) { - $this->_html_images[$i]['cid'] = $cid . $domainID; - } - } - } - - if (count($this->_html_images) && isset($this->_htmlbody)) { - foreach ($this->_html_images as $key => $value) { - $regex = array(); - $regex[] = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . - preg_quote($value['name'], '#') . '\3#'; - $regex[] = '#(?i)url(?-i)\(\s*(["\']?)' . - preg_quote($value['name'], '#') . '\1\s*\)#'; - - $rep = array(); - $rep[] = '\1\2=\3cid:' . $value['cid'] .'\3'; - $rep[] = 'url(\1cid:' . $value['cid'] . '\1)'; - - $this->_htmlbody = preg_replace($regex, $rep, $this->_htmlbody); - $this->_html_images[$key]['name'] - = $this->_basename($this->_html_images[$key]['name']); - } - } - - $this->_checkParams(); - - $null = null; - $attachments = count($this->_parts) ? true : false; - $html_images = count($this->_html_images) ? true : false; - $html = strlen($this->_htmlbody) ? true : false; - $text = (!$html && strlen($this->_txtbody)) ? true : false; - - switch (true) { - case $text && !$attachments: - $message =& $this->_addTextPart($null, $this->_txtbody); - break; - - case !$text && !$html && $attachments: - $message =& $this->_addMixedPart(); - for ($i = 0; $i < count($this->_parts); $i++) { - $this->_addAttachmentPart($message, $this->_parts[$i]); - } - break; - - case $text && $attachments: - $message =& $this->_addMixedPart(); - $this->_addTextPart($message, $this->_txtbody); - for ($i = 0; $i < count($this->_parts); $i++) { - $this->_addAttachmentPart($message, $this->_parts[$i]); - } - break; - - case $html && !$attachments && !$html_images: - if (isset($this->_txtbody)) { - $message =& $this->_addAlternativePart($null); - $this->_addTextPart($message, $this->_txtbody); - $this->_addHtmlPart($message); - } else { - $message =& $this->_addHtmlPart($null); - } - break; - - case $html && !$attachments && $html_images: - // * Content-Type: multipart/alternative; - // * text - // * Content-Type: multipart/related; - // * html - // * image... - if (isset($this->_txtbody)) { - $message =& $this->_addAlternativePart($null); - $this->_addTextPart($message, $this->_txtbody); - - $ht =& $this->_addRelatedPart($message); - $this->_addHtmlPart($ht); - for ($i = 0; $i < count($this->_html_images); $i++) { - $this->_addHtmlImagePart($ht, $this->_html_images[$i]); - } - } else { - // * Content-Type: multipart/related; - // * html - // * image... - $message =& $this->_addRelatedPart($null); - $this->_addHtmlPart($message); - for ($i = 0; $i < count($this->_html_images); $i++) { - $this->_addHtmlImagePart($message, $this->_html_images[$i]); - } - } - /* - // #13444, #9725: the code below was a non-RFC compliant hack - // * Content-Type: multipart/related; - // * Content-Type: multipart/alternative; - // * text - // * html - // * image... - $message =& $this->_addRelatedPart($null); - if (isset($this->_txtbody)) { - $alt =& $this->_addAlternativePart($message); - $this->_addTextPart($alt, $this->_txtbody); - $this->_addHtmlPart($alt); - } else { - $this->_addHtmlPart($message); - } - for ($i = 0; $i < count($this->_html_images); $i++) { - $this->_addHtmlImagePart($message, $this->_html_images[$i]); - } - */ - break; - - case $html && $attachments && !$html_images: - $message =& $this->_addMixedPart(); - if (isset($this->_txtbody)) { - $alt =& $this->_addAlternativePart($message); - $this->_addTextPart($alt, $this->_txtbody); - $this->_addHtmlPart($alt); - } else { - $this->_addHtmlPart($message); - } - for ($i = 0; $i < count($this->_parts); $i++) { - $this->_addAttachmentPart($message, $this->_parts[$i]); - } - break; - - case $html && $attachments && $html_images: - $message =& $this->_addMixedPart(); - if (isset($this->_txtbody)) { - $alt =& $this->_addAlternativePart($message); - $this->_addTextPart($alt, $this->_txtbody); - $rel =& $this->_addRelatedPart($alt); - } else { - $rel =& $this->_addRelatedPart($message); - } - $this->_addHtmlPart($rel); - for ($i = 0; $i < count($this->_html_images); $i++) { - $this->_addHtmlImagePart($rel, $this->_html_images[$i]); - } - for ($i = 0; $i < count($this->_parts); $i++) { - $this->_addAttachmentPart($message, $this->_parts[$i]); - } - break; - - } - - if (!isset($message)) { - $ret = null; - return $ret; - } - - // Use saved boundary - if (!empty($this->_build_params['boundary'])) { - $boundary = $this->_build_params['boundary']; - } else { - $boundary = null; - } - - // Write output to file - if ($filename) { - // Append mimePart message headers and body into file - $headers = $message->encodeToFile($filename, $boundary, $skip_head); - if (PEAR::isError($headers)) { - return $headers; - } - $this->_headers = array_merge($this->_headers, $headers); - $ret = null; - return $ret; - } else { - $output = $message->encode($boundary, $skip_head); - if (PEAR::isError($output)) { - return $output; - } - $this->_headers = array_merge($this->_headers, $output['headers']); - $body = $output['body']; - return $body; - } - } - - /** - * Returns an array with the headers needed to prepend to the email - * (MIME-Version and Content-Type). Format of argument is: - * $array['header-name'] = 'header-value'; - * - * @param array $xtra_headers Assoc array with any extra headers (optional) - * (Don't set Content-Type for multipart messages here!) - * @param bool $overwrite Overwrite already existing headers. - * @param bool $skip_content Don't return content headers: Content-Type, - * Content-Disposition and Content-Transfer-Encoding - * - * @return array Assoc array with the mime headers - * @access public - */ - function &headers($xtra_headers = null, $overwrite = false, $skip_content = false) - { - // Add mime version header - $headers['MIME-Version'] = '1.0'; - - // Content-Type and Content-Transfer-Encoding headers should already - // be present if get() was called, but we'll re-set them to make sure - // we got them when called before get() or something in the message - // has been changed after get() [#14780] - if (!$skip_content) { - $headers += $this->_contentHeaders(); - } - - if (!empty($xtra_headers)) { - $headers = array_merge($headers, $xtra_headers); - } - - if ($overwrite) { - $this->_headers = array_merge($this->_headers, $headers); - } else { - $this->_headers = array_merge($headers, $this->_headers); - } - - $headers = $this->_headers; - - if ($skip_content) { - unset($headers['Content-Type']); - unset($headers['Content-Transfer-Encoding']); - unset($headers['Content-Disposition']); - } else if (!empty($this->_build_params['ctype'])) { - $headers['Content-Type'] = $this->_build_params['ctype']; - } - - $encodedHeaders = $this->_encodeHeaders($headers); - return $encodedHeaders; - } - - /** - * Get the text version of the headers - * (usefull if you want to use the PHP mail() function) - * - * @param array $xtra_headers Assoc array with any extra headers (optional) - * (Don't set Content-Type for multipart messages here!) - * @param bool $overwrite Overwrite the existing headers with new. - * @param bool $skip_content Don't return content headers: Content-Type, - * Content-Disposition and Content-Transfer-Encoding - * - * @return string Plain text headers - * @access public - */ - function txtHeaders($xtra_headers = null, $overwrite = false, $skip_content = false) - { - $headers = $this->headers($xtra_headers, $overwrite, $skip_content); - - // Place Received: headers at the beginning of the message - // Spam detectors often flag messages with it after the Subject: as spam - if (isset($headers['Received'])) { - $received = $headers['Received']; - unset($headers['Received']); - $headers = array('Received' => $received) + $headers; - } - - $ret = ''; - $eol = $this->_build_params['eol']; - - foreach ($headers as $key => $val) { - if (is_array($val)) { - foreach ($val as $value) { - $ret .= "$key: $value" . $eol; - } - } else { - $ret .= "$key: $val" . $eol; - } - } - - return $ret; - } - - /** - * Sets message Content-Type header. - * Use it to build messages with various content-types e.g. miltipart/raport - * not supported by _contentHeaders() function. - * - * @param string $type Type name - * @param array $params Hash array of header parameters - * - * @return void - * @access public - * @since 1.7.0 - */ - function setContentType($type, $params = array()) - { - $header = $type; - - $eol = !empty($this->_build_params['eol']) - ? $this->_build_params['eol'] : "\r\n"; - - // add parameters - $token_regexp = '#([^\x21,\x23-\x27,\x2A,\x2B,\x2D' - . ',\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])#'; - if (is_array($params)) { - foreach ($params as $name => $value) { - if ($name == 'boundary') { - $this->_build_params['boundary'] = $value; - } - if (!preg_match($token_regexp, $value)) { - $header .= ";$eol $name=$value"; - } else { - $value = addcslashes($value, '\\"'); - $header .= ";$eol $name=\"$value\""; - } - } - } - - // add required boundary parameter if not defined - if (preg_match('/^multipart\//i', $type)) { - if (empty($this->_build_params['boundary'])) { - $this->_build_params['boundary'] = '=_' . md5(rand() . microtime()); - } - - $header .= ";$eol boundary=\"".$this->_build_params['boundary']."\""; - } - - $this->_build_params['ctype'] = $header; - } - - /** - * Sets the Subject header - * - * @param string $subject String to set the subject to. - * - * @return void - * @access public - */ - function setSubject($subject) - { - $this->_headers['Subject'] = $subject; - } - - /** - * Set an email to the From (the sender) header - * - * @param string $email The email address to use - * - * @return void - * @access public - */ - function setFrom($email) - { - $this->_headers['From'] = $email; - } - - /** - * Add an email to the To header - * (multiple calls to this method are allowed) - * - * @param string $email The email direction to add - * - * @return void - * @access public - */ - function addTo($email) - { - if (isset($this->_headers['To'])) { - $this->_headers['To'] .= ", $email"; - } else { - $this->_headers['To'] = $email; - } - } - - /** - * Add an email to the Cc (carbon copy) header - * (multiple calls to this method are allowed) - * - * @param string $email The email direction to add - * - * @return void - * @access public - */ - function addCc($email) - { - if (isset($this->_headers['Cc'])) { - $this->_headers['Cc'] .= ", $email"; - } else { - $this->_headers['Cc'] = $email; - } - } - - /** - * Add an email to the Bcc (blank carbon copy) header - * (multiple calls to this method are allowed) - * - * @param string $email The email direction to add - * - * @return void - * @access public - */ - function addBcc($email) - { - if (isset($this->_headers['Bcc'])) { - $this->_headers['Bcc'] .= ", $email"; - } else { - $this->_headers['Bcc'] = $email; - } - } - - /** - * Since the PHP send function requires you to specify - * recipients (To: header) separately from the other - * headers, the To: header is not properly encoded. - * To fix this, you can use this public method to - * encode your recipients before sending to the send - * function - * - * @param string $recipients A comma-delimited list of recipients - * - * @return string Encoded data - * @access public - */ - function encodeRecipients($recipients) - { - $input = array("To" => $recipients); - $retval = $this->_encodeHeaders($input); - return $retval["To"] ; - } - - /** - * Encodes headers as per RFC2047 - * - * @param array $input The header data to encode - * @param array $params Extra build parameters - * - * @return array Encoded data - * @access private - */ - function _encodeHeaders($input, $params = array()) - { - $build_params = $this->_build_params; - while (list($key, $value) = each($params)) { - $build_params[$key] = $value; - } - - foreach ($input as $hdr_name => $hdr_value) { - if (is_array($hdr_value)) { - foreach ($hdr_value as $idx => $value) { - $input[$hdr_name][$idx] = $this->encodeHeader( - $hdr_name, $value, - $build_params['head_charset'], $build_params['head_encoding'] - ); - } - } else { - $input[$hdr_name] = $this->encodeHeader( - $hdr_name, $hdr_value, - $build_params['head_charset'], $build_params['head_encoding'] - ); - } - } - - return $input; - } - - /** - * Encodes a header as per RFC2047 - * - * @param string $name The header name - * @param string $value The header data to encode - * @param string $charset Character set name - * @param string $encoding Encoding name (base64 or quoted-printable) - * - * @return string Encoded header data (without a name) - * @access public - * @since 1.5.3 - */ - function encodeHeader($name, $value, $charset, $encoding) - { - return Mail_mimePart::encodeHeader( - $name, $value, $charset, $encoding, $this->_build_params['eol'] - ); - } - - /** - * Get file's basename (locale independent) - * - * @param string $filename Filename - * - * @return string Basename - * @access private - */ - function _basename($filename) - { - // basename() is not unicode safe and locale dependent - if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { - return preg_replace('/^.*[\\\\\\/]/', '', $filename); - } else { - return preg_replace('/^.*[\/]/', '', $filename); - } - } - - /** - * Get Content-Type and Content-Transfer-Encoding headers of the message - * - * @return array Headers array - * @access private - */ - function _contentHeaders() - { - $attachments = count($this->_parts) ? true : false; - $html_images = count($this->_html_images) ? true : false; - $html = strlen($this->_htmlbody) ? true : false; - $text = (!$html && strlen($this->_txtbody)) ? true : false; - $headers = array(); - - // See get() - switch (true) { - case $text && !$attachments: - $headers['Content-Type'] = 'text/plain'; - break; - - case !$text && !$html && $attachments: - case $text && $attachments: - case $html && $attachments && !$html_images: - case $html && $attachments && $html_images: - $headers['Content-Type'] = 'multipart/mixed'; - break; - - case $html && !$attachments && !$html_images && isset($this->_txtbody): - case $html && !$attachments && $html_images && isset($this->_txtbody): - $headers['Content-Type'] = 'multipart/alternative'; - break; - - case $html && !$attachments && !$html_images && !isset($this->_txtbody): - $headers['Content-Type'] = 'text/html'; - break; - - case $html && !$attachments && $html_images && !isset($this->_txtbody): - $headers['Content-Type'] = 'multipart/related'; - break; - - default: - return $headers; - } - - $this->_checkParams(); - - $eol = !empty($this->_build_params['eol']) - ? $this->_build_params['eol'] : "\r\n"; - - if ($headers['Content-Type'] == 'text/plain') { - // single-part message: add charset and encoding - $charset = 'charset=' . $this->_build_params['text_charset']; - // place charset parameter in the same line, if possible - // 26 = strlen("Content-Type: text/plain; ") - $headers['Content-Type'] - .= (strlen($charset) + 26 <= 76) ? "; $charset" : ";$eol $charset"; - $headers['Content-Transfer-Encoding'] - = $this->_build_params['text_encoding']; - } else if ($headers['Content-Type'] == 'text/html') { - // single-part message: add charset and encoding - $charset = 'charset=' . $this->_build_params['html_charset']; - // place charset parameter in the same line, if possible - $headers['Content-Type'] - .= (strlen($charset) + 25 <= 76) ? "; $charset" : ";$eol $charset"; - $headers['Content-Transfer-Encoding'] - = $this->_build_params['html_encoding']; - } else { - // multipart message: and boundary - if (!empty($this->_build_params['boundary'])) { - $boundary = $this->_build_params['boundary']; - } else if (!empty($this->_headers['Content-Type']) - && preg_match('/boundary="([^"]+)"/', $this->_headers['Content-Type'], $m) - ) { - $boundary = $m[1]; - } else { - $boundary = '=_' . md5(rand() . microtime()); - } - - $this->_build_params['boundary'] = $boundary; - $headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; - } - - return $headers; - } - - /** - * Validate and set build parameters - * - * @return void - * @access private - */ - function _checkParams() - { - $encodings = array('7bit', '8bit', 'base64', 'quoted-printable'); - - $this->_build_params['text_encoding'] - = strtolower($this->_build_params['text_encoding']); - $this->_build_params['html_encoding'] - = strtolower($this->_build_params['html_encoding']); - - if (!in_array($this->_build_params['text_encoding'], $encodings)) { - $this->_build_params['text_encoding'] = '7bit'; - } - if (!in_array($this->_build_params['html_encoding'], $encodings)) { - $this->_build_params['html_encoding'] = '7bit'; - } - - // text body - if ($this->_build_params['text_encoding'] == '7bit' - && !preg_match('/ascii/i', $this->_build_params['text_charset']) - && preg_match('/[^\x00-\x7F]/', $this->_txtbody) - ) { - $this->_build_params['text_encoding'] = 'quoted-printable'; - } - // html body - if ($this->_build_params['html_encoding'] == '7bit' - && !preg_match('/ascii/i', $this->_build_params['html_charset']) - && preg_match('/[^\x00-\x7F]/', $this->_htmlbody) - ) { - $this->_build_params['html_encoding'] = 'quoted-printable'; - } - } - -} // End of class diff --git a/data/module/Mail/mimeDecode.php b/data/module/Mail/mimeDecode.php deleted file mode 100644 index 677d245e34..0000000000 --- a/data/module/Mail/mimeDecode.php +++ /dev/null @@ -1,1003 +0,0 @@ - - * Copyright (c) 2003-2006, PEAR - * 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 the authors, 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 Mail - * @package Mail_Mime - * @author Richard Heyes - * @author George Schlossnagle - * @author Cipriano Groenendal - * @author Sean Coates - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Mail_mime - */ - - -/** - * require PEAR - * - * This package depends on PEAR to raise errors. - */ -require_once 'PEAR.php'; - - -/** - * The Mail_mimeDecode class is used to decode mail/mime messages - * - * This class will parse a raw mime email and return the structure. - * Returned structure is similar to that returned by imap_fetchstructure(). - * - * +----------------------------- IMPORTANT ------------------------------+ - * | Usage of this class compared to native php extensions such as | - * | mailparse or imap, is slow and may be feature deficient. If available| - * | you are STRONGLY recommended to use the php extensions. | - * +----------------------------------------------------------------------+ - * - * @category Mail - * @package Mail_Mime - * @author Richard Heyes - * @author George Schlossnagle - * @author Cipriano Groenendal - * @author Sean Coates - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/Mail_mime - */ -class Mail_mimeDecode extends PEAR -{ - /** - * The raw email to decode - * - * @var string - * @access private - */ - var $_input; - - /** - * The header part of the input - * - * @var string - * @access private - */ - var $_header; - - /** - * The body part of the input - * - * @var string - * @access private - */ - var $_body; - - /** - * If an error occurs, this is used to store the message - * - * @var string - * @access private - */ - var $_error; - - /** - * Flag to determine whether to include bodies in the - * returned object. - * - * @var boolean - * @access private - */ - var $_include_bodies; - - /** - * Flag to determine whether to decode bodies - * - * @var boolean - * @access private - */ - var $_decode_bodies; - - /** - * Flag to determine whether to decode headers - * - * @var boolean - * @access private - */ - var $_decode_headers; - - /** - * Flag to determine whether to include attached messages - * as body in the returned object. Depends on $_include_bodies - * - * @var boolean - * @access private - */ - var $_rfc822_bodies; - - /** - * Constructor. - * - * Sets up the object, initialise the variables, and splits and - * stores the header and body of the input. - * - * @param string The input to decode - * @access public - */ - function Mail_mimeDecode($input) - { - list($header, $body) = $this->_splitBodyHeader($input); - - $this->_input = $input; - $this->_header = $header; - $this->_body = $body; - $this->_decode_bodies = false; - $this->_include_bodies = true; - $this->_rfc822_bodies = false; - } - - /** - * Begins the decoding process. If called statically - * it will create an object and call the decode() method - * of it. - * - * @param array An array of various parameters that determine - * various things: - * include_bodies - Whether to include the body in the returned - * object. - * decode_bodies - Whether to decode the bodies - * of the parts. (Transfer encoding) - * decode_headers - Whether to decode headers - * input - If called statically, this will be treated - * as the input - * @return object Decoded results - * @access public - */ - function decode($params = null) - { - // determine if this method has been called statically - $isStatic = empty($this) || !is_a($this, __CLASS__); - - // Have we been called statically? - // If so, create an object and pass details to that. - if ($isStatic AND isset($params['input'])) { - - $obj = new Mail_mimeDecode($params['input']); - $structure = $obj->decode($params); - - // Called statically but no input - } elseif ($isStatic) { - return PEAR::raiseError('Called statically and no input given'); - - // Called via an object - } else { - $this->_include_bodies = isset($params['include_bodies']) ? - $params['include_bodies'] : false; - $this->_decode_bodies = isset($params['decode_bodies']) ? - $params['decode_bodies'] : false; - $this->_decode_headers = isset($params['decode_headers']) ? - $params['decode_headers'] : false; - $this->_rfc822_bodies = isset($params['rfc_822bodies']) ? - $params['rfc_822bodies'] : false; - - $structure = $this->_decode($this->_header, $this->_body); - if ($structure === false) { - $structure = $this->raiseError($this->_error); - } - } - - return $structure; - } - - /** - * Performs the decoding. Decodes the body string passed to it - * If it finds certain content-types it will call itself in a - * recursive fashion - * - * @param string Header section - * @param string Body section - * @return object Results of decoding process - * @access private - */ - function _decode($headers, $body, $default_ctype = 'text/plain') - { - $return = new stdClass; - $return->headers = array(); - $headers = $this->_parseHeaders($headers); - - foreach ($headers as $value) { - $value['value'] = $this->_decode_headers ? $this->_decodeHeader($value['value']) : $value['value']; - if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { - $return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); - $return->headers[strtolower($value['name'])][] = $value['value']; - - } elseif (isset($return->headers[strtolower($value['name'])])) { - $return->headers[strtolower($value['name'])][] = $value['value']; - - } else { - $return->headers[strtolower($value['name'])] = $value['value']; - } - } - - - foreach ($headers as $key => $value) { - $headers[$key]['name'] = strtolower($headers[$key]['name']); - switch ($headers[$key]['name']) { - - case 'content-type': - $content_type = $this->_parseHeaderValue($headers[$key]['value']); - - if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { - $return->ctype_primary = $regs[1]; - $return->ctype_secondary = $regs[2]; - } - - if (isset($content_type['other'])) { - foreach($content_type['other'] as $p_name => $p_value) { - $return->ctype_parameters[$p_name] = $p_value; - } - } - break; - - case 'content-disposition': - $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); - $return->disposition = $content_disposition['value']; - if (isset($content_disposition['other'])) { - foreach($content_disposition['other'] as $p_name => $p_value) { - $return->d_parameters[$p_name] = $p_value; - } - } - break; - - case 'content-transfer-encoding': - $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); - break; - } - } - - if (isset($content_type)) { - switch (strtolower($content_type['value'])) { - case 'text/plain': - $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; - $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; - break; - - case 'text/html': - $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; - $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; - break; - - case 'multipart/parallel': - case 'multipart/appledouble': // Appledouble mail - case 'multipart/report': // RFC1892 - case 'multipart/signed': // PGP - case 'multipart/digest': - case 'multipart/alternative': - case 'multipart/related': - case 'multipart/mixed': - case 'application/vnd.wap.multipart.related': - if(!isset($content_type['other']['boundary'])){ - $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; - return false; - } - - $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; - - $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); - for ($i = 0; $i < count($parts); $i++) { - list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); - $part = $this->_decode($part_header, $part_body, $default_ctype); - if($part === false) - $part = $this->raiseError($this->_error); - $return->parts[] = $part; - } - break; - - case 'message/rfc822': - if ($this->_rfc822_bodies) { - $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; - $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body); - } - $obj = new Mail_mimeDecode($body); - $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, - 'decode_bodies' => $this->_decode_bodies, - 'decode_headers' => $this->_decode_headers)); - unset($obj); - break; - - default: - if(!isset($content_transfer_encoding['value'])) - $content_transfer_encoding['value'] = '7bit'; - $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; - break; - } - - } else { - $ctype = explode('/', $default_ctype); - $return->ctype_primary = $ctype[0]; - $return->ctype_secondary = $ctype[1]; - $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; - } - - return $return; - } - - /** - * Given the output of the above function, this will return an - * array of references to the parts, indexed by mime number. - * - * @param object $structure The structure to go through - * @param string $mime_number Internal use only. - * @return array Mime numbers - */ - function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') - { - $return = array(); - if (!empty($structure->parts)) { - if ($mime_number != '') { - $structure->mime_id = $prepend . $mime_number; - $return[$prepend . $mime_number] = &$structure; - } - for ($i = 0; $i < count($structure->parts); $i++) { - - - if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { - $prepend = $prepend . $mime_number . '.'; - $_mime_number = ''; - } else { - $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); - } - - $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); - foreach ($arr as $key => $val) { - $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; - } - } - } else { - if ($mime_number == '') { - $mime_number = '1'; - } - $structure->mime_id = $prepend . $mime_number; - $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; - } - - return $return; - } - - /** - * Given a string containing a header and body - * section, this function will split them (at the first - * blank line) and return them. - * - * @param string Input to split apart - * @return array Contains header and body section - * @access private - */ - function _splitBodyHeader($input) - { - if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { - return array($match[1], $match[2]); - } - // bug #17325 - empty bodies are allowed. - we just check that at least one line - // of headers exist.. - if (count(explode("\n",$input))) { - return array($input, ''); - } - $this->_error = 'Could not split header and body'; - return false; - } - - /** - * Parse headers given in $input and return - * as assoc array. - * - * @param string Headers to parse - * @return array Contains parsed headers - * @access private - */ - function _parseHeaders($input) - { - - if ($input !== '') { - // Unfold the input - $input = preg_replace("/\r?\n/", "\r\n", $input); - //#7065 - wrapping.. with encoded stuff.. - probably not needed, - // wrapping space should only get removed if the trailing item on previous line is a - // encoded character - $input = preg_replace("/=\r\n(\t| )+/", '=', $input); - $input = preg_replace("/\r\n(\t| )+/", ' ', $input); - - $headers = explode("\r\n", trim($input)); - - foreach ($headers as $value) { - $hdr_name = substr($value, 0, $pos = strpos($value, ':')); - $hdr_value = substr($value, $pos+1); - if($hdr_value[0] == ' ') - $hdr_value = substr($hdr_value, 1); - - $return[] = array( - 'name' => $hdr_name, - 'value' => $hdr_value - ); - } - } else { - $return = array(); - } - - return $return; - } - - /** - * Function to parse a header value, - * extract first part, and any secondary - * parts (after ;) This function is not as - * robust as it could be. Eg. header comments - * in the wrong place will probably break it. - * - * @param string Header value to parse - * @return array Contains parsed result - * @access private - */ - function _parseHeaderValue($input) - { - - if (($pos = strpos($input, ';')) === false) { - $input = $this->_decode_headers ? $this->_decodeHeader($input) : $input; - $return['value'] = trim($input); - return $return; - } - - - - $value = substr($input, 0, $pos); - $value = $this->_decode_headers ? $this->_decodeHeader($value) : $value; - $return['value'] = trim($value); - $input = trim(substr($input, $pos+1)); - - if (!strlen($input) > 0) { - return $return; - } - // at this point input contains xxxx=".....";zzzz="...." - // since we are dealing with quoted strings, we need to handle this properly.. - $i = 0; - $l = strlen($input); - $key = ''; - $val = false; // our string - including quotes.. - $q = false; // in quote.. - $lq = ''; // last quote.. - - while ($i < $l) { - - $c = $input[$i]; - //var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val)); - - $escaped = false; - if ($c == '\\') { - $i++; - if ($i == $l-1) { // end of string. - break; - } - $escaped = true; - $c = $input[$i]; - } - - - // state - in key.. - if ($val === false) { - if (!$escaped && $c == '=') { - $val = ''; - $key = trim($key); - $i++; - continue; - } - if (!$escaped && $c == ';') { - if ($key) { // a key without a value.. - $key= trim($key); - $return['other'][$key] = ''; - $return['other'][strtolower($key)] = ''; - } - $key = ''; - } - $key .= $c; - $i++; - continue; - } - - // state - in value.. (as $val is set..) - - if ($q === false) { - // not in quote yet. - if ((!strlen($val) || $lq !== false) && $c == ' ' || $c == "\t") { - $i++; - continue; // skip leading spaces after '=' or after '"' - } - if (!$escaped && ($c == '"' || $c == "'")) { - // start quoted area.. - $q = $c; - // in theory should not happen raw text in value part.. - // but we will handle it as a merged part of the string.. - $val = !strlen(trim($val)) ? '' : trim($val); - $i++; - continue; - } - // got end.... - if (!$escaped && $c == ';') { - - $val = trim($val); - $added = false; - if (preg_match('/\*[0-9]+$/', $key)) { - // this is the extended aaa*0=...;aaa*1=.... code - // it assumes the pieces arrive in order, and are valid... - $key = preg_replace('/\*[0-9]+$/', '', $key); - if (isset($return['other'][$key])) { - $return['other'][$key] .= $val; - if (strtolower($key) != $key) { - $return['other'][strtolower($key)] .= $val; - } - $added = true; - } - // continue and use standard setters.. - } - if (!$added) { - $return['other'][$key] = $val; - $return['other'][strtolower($key)] = $val; - } - $val = false; - $key = ''; - $lq = false; - $i++; - continue; - } - - $val .= $c; - $i++; - continue; - } - - // state - in quote.. - if (!$escaped && $c == $q) { // potential exit state.. - - // end of quoted string.. - $lq = $q; - $q = false; - $i++; - continue; - } - - // normal char inside of quoted string.. - $val.= $c; - $i++; - } - - // do we have anything left.. - if (strlen(trim($key)) || $val !== false) { - - $val = trim($val); - $added = false; - if ($val !== false && preg_match('/\*[0-9]+$/', $key)) { - // no dupes due to our crazy regexp. - $key = preg_replace('/\*[0-9]+$/', '', $key); - if (isset($return['other'][$key])) { - $return['other'][$key] .= $val; - if (strtolower($key) != $key) { - $return['other'][strtolower($key)] .= $val; - } - $added = true; - } - // continue and use standard setters.. - } - if (!$added) { - $return['other'][$key] = $val; - $return['other'][strtolower($key)] = $val; - } - } - // decode values. - foreach($return['other'] as $key =>$val) { - $return['other'][$key] = $this->_decode_headers ? $this->_decodeHeader($val) : $val; - } - //print_r($return); - return $return; - } - - /** - * This function splits the input based - * on the given boundary - * - * @param string Input to parse - * @return array Contains array of resulting mime parts - * @access private - */ - function _boundarySplit($input, $boundary) - { - $parts = array(); - - $bs_possible = substr($boundary, 2, -2); - $bs_check = '\"' . $bs_possible . '\"'; - - if ($boundary == $bs_check) { - $boundary = $bs_possible; - } - $tmp = preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input); - - $len = count($tmp) -1; - for ($i = 1; $i < $len; $i++) { - if (strlen(trim($tmp[$i]))) { - $parts[] = $tmp[$i]; - } - } - - // add the last part on if it does not end with the 'closing indicator' - if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') { - $parts[] = $tmp[$len]; - } - return $parts; - } - - /** - * Given a header, this function will decode it - * according to RFC2047. Probably not *exactly* - * conformant, but it does pass all the given - * examples (in RFC2047). - * - * @param string Input header value to decode - * @return string Decoded header value - * @access private - */ - function _decodeHeader($input) - { - // Remove white space between encoded-words - $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); - - // For each encoded-word... - while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { - - $encoded = $matches[1]; - $charset = $matches[2]; - $encoding = $matches[3]; - $text = $matches[4]; - - switch (strtolower($encoding)) { - case 'b': - $text = base64_decode($text); - break; - - case 'q': - $text = str_replace('_', ' ', $text); - preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); - foreach($matches[1] as $value) - $text = str_replace('='.$value, chr(hexdec($value)), $text); - break; - } - - $input = str_replace($encoded, $text, $input); - } - - return $input; - } - - /** - * Given a body string and an encoding type, - * this function will decode and return it. - * - * @param string Input body to decode - * @param string Encoding type to use. - * @return string Decoded body - * @access private - */ - function _decodeBody($input, $encoding = '7bit') - { - switch (strtolower($encoding)) { - case '7bit': - return $input; - break; - - case 'quoted-printable': - return $this->_quotedPrintableDecode($input); - break; - - case 'base64': - return base64_decode($input); - break; - - default: - return $input; - } - } - - /** - * Given a quoted-printable string, this - * function will decode and return it. - * - * @param string Input body to decode - * @return string Decoded body - * @access private - */ - function _quotedPrintableDecode($input) - { - // Remove soft line breaks - $input = preg_replace("/=\r?\n/", '', $input); - - // Replace encoded characters - $input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); - - return $input; - } - - /** - * Checks the input for uuencoded files and returns - * an array of them. Can be called statically, eg: - * - * $files =& Mail_mimeDecode::uudecode($some_text); - * - * It will check for the begin 666 ... end syntax - * however and won't just blindly decode whatever you - * pass it. - * - * @param string Input body to look for attahcments in - * @return array Decoded bodies, filenames and permissions - * @access public - * @author Unknown - */ - function &uudecode($input) - { - // Find all uuencoded sections - preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); - - for ($j = 0; $j < count($matches[3]); $j++) { - - $str = $matches[3][$j]; - $filename = $matches[2][$j]; - $fileperm = $matches[1][$j]; - - $file = ''; - $str = preg_split("/\r?\n/", trim($str)); - $strlen = count($str); - - for ($i = 0; $i < $strlen; $i++) { - $pos = 1; - $d = 0; - $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); - - while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { - $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); - $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); - $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); - $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); - $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); - - $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); - - $file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077)); - - $pos += 4; - $d += 3; - } - - if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { - $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); - $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); - $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); - $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); - - $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); - - $pos += 3; - $d += 2; - } - - if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { - $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); - $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); - $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); - - } - } - $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); - } - - return $files; - } - - /** - * getSendArray() returns the arguments required for Mail::send() - * used to build the arguments for a mail::send() call - * - * Usage: - * $mailtext = Full email (for example generated by a template) - * $decoder = new Mail_mimeDecode($mailtext); - * $parts = $decoder->getSendArray(); - * if (!PEAR::isError($parts) { - * list($recipents,$headers,$body) = $parts; - * $mail = Mail::factory('smtp'); - * $mail->send($recipents,$headers,$body); - * } else { - * echo $parts->message; - * } - * @return mixed array of recipeint, headers,body or Pear_Error - * @access public - * @author Alan Knowles - */ - function getSendArray() - { - // prevent warning if this is not set - $this->_decode_headers = FALSE; - $headerlist =$this->_parseHeaders($this->_header); - $to = ""; - if (!$headerlist) { - return $this->raiseError("Message did not contain headers"); - } - foreach($headerlist as $item) { - $header[$item['name']] = $item['value']; - switch (strtolower($item['name'])) { - case "to": - case "cc": - case "bcc": - $to .= ",".$item['value']; - default: - break; - } - } - if ($to == "") { - return $this->raiseError("Message did not contain any recipents"); - } - $to = substr($to,1); - return array($to,$header,$this->_body); - } - - /** - * Returns a xml copy of the output of - * Mail_mimeDecode::decode. Pass the output in as the - * argument. This function can be called statically. Eg: - * - * $output = $obj->decode(); - * $xml = Mail_mimeDecode::getXML($output); - * - * The DTD used for this should have been in the package. Or - * alternatively you can get it from cvs, or here: - * http://www.phpguru.org/xmail/xmail.dtd. - * - * @param object Input to convert to xml. This should be the - * output of the Mail_mimeDecode::decode function - * @return string XML version of input - * @access public - */ - function getXML($input) - { - $crlf = "\r\n"; - $output = '' . $crlf . - '' . $crlf . - '' . $crlf . - Mail_mimeDecode::_getXML($input) . - ''; - - return $output; - } - - /** - * Function that does the actual conversion to xml. Does a single - * mimepart at a time. - * - * @param object Input to convert to xml. This is a mimepart object. - * It may or may not contain subparts. - * @param integer Number of tabs to indent - * @return string XML version of input - * @access private - */ - function _getXML($input, $indent = 1) - { - $htab = "\t"; - $crlf = "\r\n"; - $output = ''; - $headers = @(array)$input->headers; - - foreach ($headers as $hdr_name => $hdr_value) { - - // Multiple headers with this name - if (is_array($headers[$hdr_name])) { - for ($i = 0; $i < count($hdr_value); $i++) { - $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); - } - - // Only one header of this sort - } else { - $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); - } - } - - if (!empty($input->parts)) { - for ($i = 0; $i < count($input->parts); $i++) { - $output .= $crlf . str_repeat($htab, $indent) . '' . $crlf . - Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . - str_repeat($htab, $indent) . '' . $crlf; - } - } elseif (isset($input->body)) { - $output .= $crlf . str_repeat($htab, $indent) . 'body . ']]>' . $crlf; - } - - return $output; - } - - /** - * Helper function to _getXML(). Returns xml of a header. - * - * @param string Name of header - * @param string Value of header - * @param integer Number of tabs to indent - * @return string XML version of input - * @access private - */ - function _getXML_helper($hdr_name, $hdr_value, $indent) - { - $htab = "\t"; - $crlf = "\r\n"; - $return = ''; - - $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); - $new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); - - // Sort out any parameters - if (!empty($new_hdr_value['other'])) { - foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { - $params[] = str_repeat($htab, $indent) . $htab . '' . $crlf . - str_repeat($htab, $indent) . $htab . $htab . '' . htmlspecialchars($paramname) . '' . $crlf . - str_repeat($htab, $indent) . $htab . $htab . '' . htmlspecialchars($paramvalue) . '' . $crlf . - str_repeat($htab, $indent) . $htab . '' . $crlf; - } - - $params = implode('', $params); - } else { - $params = ''; - } - - $return = str_repeat($htab, $indent) . '
' . $crlf . - str_repeat($htab, $indent) . $htab . '' . htmlspecialchars($new_hdr_name) . '' . $crlf . - str_repeat($htab, $indent) . $htab . '' . htmlspecialchars($new_hdr_value['value']) . '' . $crlf . - $params . - str_repeat($htab, $indent) . '
' . $crlf; - - return $return; - } - -} // End of class diff --git a/data/module/Mail/mimePart.php b/data/module/Mail/mimePart.php deleted file mode 100644 index 60b3601e06..0000000000 --- a/data/module/Mail/mimePart.php +++ /dev/null @@ -1,1190 +0,0 @@ - - * Copyright (c) 2003-2006, PEAR - * 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 the authors, 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 Mail - * @package Mail_Mime - * @author Richard Heyes - * @author Cipriano Groenendal - * @author Sean Coates - * @author Aleksander Machniak - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Mail_mime - */ - - -/** - * The Mail_mimePart class is used to create MIME E-mail messages - * - * This class enables you to manipulate and build a mime email - * from the ground up. The Mail_Mime class is a userfriendly api - * to this class for people who aren't interested in the internals - * of mime mail. - * This class however allows full control over the email. - * - * @category Mail - * @package Mail_Mime - * @author Richard Heyes - * @author Cipriano Groenendal - * @author Sean Coates - * @author Aleksander Machniak - * @copyright 2003-2006 PEAR - * @license http://www.opensource.org/licenses/bsd-license.php BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/Mail_mime - */ -class Mail_mimePart -{ - /** - * The encoding type of this part - * - * @var string - * @access private - */ - var $_encoding; - - /** - * An array of subparts - * - * @var array - * @access private - */ - var $_subparts; - - /** - * The output of this part after being built - * - * @var string - * @access private - */ - var $_encoded; - - /** - * Headers for this part - * - * @var array - * @access private - */ - var $_headers; - - /** - * The body of this part (not encoded) - * - * @var string - * @access private - */ - var $_body; - - /** - * The location of file with body of this part (not encoded) - * - * @var string - * @access private - */ - var $_body_file; - - /** - * The end-of-line sequence - * - * @var string - * @access private - */ - var $_eol = "\r\n"; - - /** - * Constructor. - * - * Sets up the object. - * - * @param string $body The body of the mime part if any. - * @param array $params An associative array of optional parameters: - * content_type - The content type for this part eg multipart/mixed - * encoding - The encoding to use, 7bit, 8bit, - * base64, or quoted-printable - * charset - Content character set - * cid - Content ID to apply - * disposition - Content disposition, inline or attachment - * dfilename - Filename parameter for content disposition - * description - Content description - * name_encoding - Encoding of the attachment name (Content-Type) - * By default filenames are encoded using RFC2231 - * Here you can set RFC2047 encoding (quoted-printable - * or base64) instead - * filename_encoding - Encoding of the attachment filename (Content-Disposition) - * See 'name_encoding' - * headers_charset - Charset of the headers e.g. filename, description. - * If not set, 'charset' will be used - * eol - End of line sequence. Default: "\r\n" - * body_file - Location of file with part's body (instead of $body) - * - * @access public - */ - function Mail_mimePart($body = '', $params = array()) - { - if (!empty($params['eol'])) { - $this->_eol = $params['eol']; - } else if (defined('MAIL_MIMEPART_CRLF')) { // backward-copat. - $this->_eol = MAIL_MIMEPART_CRLF; - } - - foreach ($params as $key => $value) { - switch ($key) { - case 'encoding': - $this->_encoding = $value; - $headers['Content-Transfer-Encoding'] = $value; - break; - - case 'cid': - $headers['Content-ID'] = '<' . $value . '>'; - break; - - case 'location': - $headers['Content-Location'] = $value; - break; - - case 'body_file': - $this->_body_file = $value; - break; - } - } - - // Default content-type - if (empty($params['content_type'])) { - $params['content_type'] = 'text/plain'; - } - - // Content-Type - $headers['Content-Type'] = $params['content_type']; - if (!empty($params['charset'])) { - $charset = "charset={$params['charset']}"; - // place charset parameter in the same line, if possible - if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) { - $headers['Content-Type'] .= '; '; - } else { - $headers['Content-Type'] .= ';' . $this->_eol . ' '; - } - $headers['Content-Type'] .= $charset; - - // Default headers charset - if (!isset($params['headers_charset'])) { - $params['headers_charset'] = $params['charset']; - } - } - if (!empty($params['filename'])) { - $headers['Content-Type'] .= ';' . $this->_eol; - $headers['Content-Type'] .= $this->_buildHeaderParam( - 'name', $params['filename'], - !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII', - !empty($params['language']) ? $params['language'] : null, - !empty($params['name_encoding']) ? $params['name_encoding'] : null - ); - } - - // Content-Disposition - if (!empty($params['disposition'])) { - $headers['Content-Disposition'] = $params['disposition']; - if (!empty($params['filename'])) { - $headers['Content-Disposition'] .= ';' . $this->_eol; - $headers['Content-Disposition'] .= $this->_buildHeaderParam( - 'filename', $params['filename'], - !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII', - !empty($params['language']) ? $params['language'] : null, - !empty($params['filename_encoding']) ? $params['filename_encoding'] : null - ); - } - } - - if (!empty($params['description'])) { - $headers['Content-Description'] = $this->encodeHeader( - 'Content-Description', $params['description'], - !empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII', - !empty($params['name_encoding']) ? $params['name_encoding'] : 'quoted-printable', - $this->_eol - ); - } - - // Default encoding - if (!isset($this->_encoding)) { - $this->_encoding = '7bit'; - } - - // Assign stuff to member variables - $this->_encoded = array(); - $this->_headers = $headers; - $this->_body = $body; - } - - /** - * Encodes and returns the email. Also stores - * it in the encoded member variable - * - * @param string $boundary Pre-defined boundary string - * - * @return An associative array containing two elements, - * body and headers. The headers element is itself - * an indexed array. On error returns PEAR error object. - * @access public - */ - function encode($boundary=null) - { - $encoded =& $this->_encoded; - - if (count($this->_subparts)) { - $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); - $eol = $this->_eol; - - $this->_headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; - - $encoded['body'] = ''; - - for ($i = 0; $i < count($this->_subparts); $i++) { - $encoded['body'] .= '--' . $boundary . $eol; - $tmp = $this->_subparts[$i]->encode(); - if (PEAR::isError($tmp)) { - return $tmp; - } - foreach ($tmp['headers'] as $key => $value) { - $encoded['body'] .= $key . ': ' . $value . $eol; - } - $encoded['body'] .= $eol . $tmp['body'] . $eol; - } - - $encoded['body'] .= '--' . $boundary . '--' . $eol; - - } else if ($this->_body) { - $encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding); - } else if ($this->_body_file) { - // Temporarily reset magic_quotes_runtime for file reads and writes - if ($magic_quote_setting = get_magic_quotes_runtime()) { - @ini_set('magic_quotes_runtime', 0); - } - $body = $this->_getEncodedDataFromFile($this->_body_file, $this->_encoding); - if ($magic_quote_setting) { - @ini_set('magic_quotes_runtime', $magic_quote_setting); - } - - if (PEAR::isError($body)) { - return $body; - } - $encoded['body'] = $body; - } else { - $encoded['body'] = ''; - } - - // Add headers to $encoded - $encoded['headers'] =& $this->_headers; - - return $encoded; - } - - /** - * Encodes and saves the email into file. File must exist. - * Data will be appended to the file. - * - * @param string $filename Output file location - * @param string $boundary Pre-defined boundary string - * @param boolean $skip_head True if you don't want to save headers - * - * @return array An associative array containing message headers - * or PEAR error object - * @access public - * @since 1.6.0 - */ - function encodeToFile($filename, $boundary=null, $skip_head=false) - { - if (file_exists($filename) && !is_writable($filename)) { - $err = PEAR::raiseError('File is not writeable: ' . $filename); - return $err; - } - - if (!($fh = fopen($filename, 'ab'))) { - $err = PEAR::raiseError('Unable to open file: ' . $filename); - return $err; - } - - // Temporarily reset magic_quotes_runtime for file reads and writes - if ($magic_quote_setting = get_magic_quotes_runtime()) { - @ini_set('magic_quotes_runtime', 0); - } - - $res = $this->_encodePartToFile($fh, $boundary, $skip_head); - - fclose($fh); - - if ($magic_quote_setting) { - @ini_set('magic_quotes_runtime', $magic_quote_setting); - } - - return PEAR::isError($res) ? $res : $this->_headers; - } - - /** - * Encodes given email part into file - * - * @param string $fh Output file handle - * @param string $boundary Pre-defined boundary string - * @param boolean $skip_head True if you don't want to save headers - * - * @return array True on sucess or PEAR error object - * @access private - */ - function _encodePartToFile($fh, $boundary=null, $skip_head=false) - { - $eol = $this->_eol; - - if (count($this->_subparts)) { - $boundary = $boundary ? $boundary : '=_' . md5(rand() . microtime()); - $this->_headers['Content-Type'] .= ";$eol boundary=\"$boundary\""; - } - - if (!$skip_head) { - foreach ($this->_headers as $key => $value) { - fwrite($fh, $key . ': ' . $value . $eol); - } - $f_eol = $eol; - } else { - $f_eol = ''; - } - - if (count($this->_subparts)) { - for ($i = 0; $i < count($this->_subparts); $i++) { - fwrite($fh, $f_eol . '--' . $boundary . $eol); - $res = $this->_subparts[$i]->_encodePartToFile($fh); - if (PEAR::isError($res)) { - return $res; - } - $f_eol = $eol; - } - - fwrite($fh, $eol . '--' . $boundary . '--' . $eol); - - } else if ($this->_body) { - fwrite($fh, $f_eol . $this->_getEncodedData($this->_body, $this->_encoding)); - } else if ($this->_body_file) { - fwrite($fh, $f_eol); - $res = $this->_getEncodedDataFromFile( - $this->_body_file, $this->_encoding, $fh - ); - if (PEAR::isError($res)) { - return $res; - } - } - - return true; - } - - /** - * Adds a subpart to current mime part and returns - * a reference to it - * - * @param string $body The body of the subpart, if any. - * @param array $params The parameters for the subpart, same - * as the $params argument for constructor. - * - * @return Mail_mimePart A reference to the part you just added. It is - * crucial if using multipart/* in your subparts that - * you use =& in your script when calling this function, - * otherwise you will not be able to add further subparts. - * @access public - */ - function &addSubpart($body, $params) - { - $this->_subparts[] = new Mail_mimePart($body, $params); - return $this->_subparts[count($this->_subparts) - 1]; - } - - /** - * Returns encoded data based upon encoding passed to it - * - * @param string $data The data to encode. - * @param string $encoding The encoding type to use, 7bit, base64, - * or quoted-printable. - * - * @return string - * @access private - */ - function _getEncodedData($data, $encoding) - { - switch ($encoding) { - case 'quoted-printable': - return $this->_quotedPrintableEncode($data); - break; - - case 'base64': - return rtrim(chunk_split(base64_encode($data), 76, $this->_eol)); - break; - - case '8bit': - case '7bit': - default: - return $data; - } - } - - /** - * Returns encoded data based upon encoding passed to it - * - * @param string $filename Data file location - * @param string $encoding The encoding type to use, 7bit, base64, - * or quoted-printable. - * @param resource $fh Output file handle. If set, data will be - * stored into it instead of returning it - * - * @return string Encoded data or PEAR error object - * @access private - */ - function _getEncodedDataFromFile($filename, $encoding, $fh=null) - { - if (!is_readable($filename)) { - $err = PEAR::raiseError('Unable to read file: ' . $filename); - return $err; - } - - if (!($fd = fopen($filename, 'rb'))) { - $err = PEAR::raiseError('Could not open file: ' . $filename); - return $err; - } - - $data = ''; - - switch ($encoding) { - case 'quoted-printable': - while (!feof($fd)) { - $buffer = $this->_quotedPrintableEncode(fgets($fd)); - if ($fh) { - fwrite($fh, $buffer); - } else { - $data .= $buffer; - } - } - break; - - case 'base64': - while (!feof($fd)) { - // Should read in a multiple of 57 bytes so that - // the output is 76 bytes per line. Don't use big chunks - // because base64 encoding is memory expensive - $buffer = fread($fd, 57 * 9198); // ca. 0.5 MB - $buffer = base64_encode($buffer); - $buffer = chunk_split($buffer, 76, $this->_eol); - if (feof($fd)) { - $buffer = rtrim($buffer); - } - - if ($fh) { - fwrite($fh, $buffer); - } else { - $data .= $buffer; - } - } - break; - - case '8bit': - case '7bit': - default: - while (!feof($fd)) { - $buffer = fread($fd, 1048576); // 1 MB - if ($fh) { - fwrite($fh, $buffer); - } else { - $data .= $buffer; - } - } - } - - fclose($fd); - - if (!$fh) { - return $data; - } - } - - /** - * Encodes data to quoted-printable standard. - * - * @param string $input The data to encode - * @param int $line_max Optional max line length. Should - * not be more than 76 chars - * - * @return string Encoded data - * - * @access private - */ - function _quotedPrintableEncode($input , $line_max = 76) - { - $eol = $this->_eol; - /* - // imap_8bit() is extremely fast, but doesn't handle properly some characters - if (function_exists('imap_8bit') && $line_max == 76) { - $input = preg_replace('/\r?\n/', "\r\n", $input); - $input = imap_8bit($input); - if ($eol != "\r\n") { - $input = str_replace("\r\n", $eol, $input); - } - return $input; - } - */ - $lines = preg_split("/\r?\n/", $input); - $escape = '='; - $output = ''; - - while (list($idx, $line) = each($lines)) { - $newline = ''; - $i = 0; - - while (isset($line[$i])) { - $char = $line[$i]; - $dec = ord($char); - $i++; - - if (($dec == 32) && (!isset($line[$i]))) { - // convert space at eol only - $char = '=20'; - } elseif ($dec == 9 && isset($line[$i])) { - ; // Do nothing if a TAB is not on eol - } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { - $char = $escape . sprintf('%02X', $dec); - } elseif (($dec == 46) && (($newline == '') - || ((strlen($newline) + strlen("=2E")) >= $line_max)) - ) { - // Bug #9722: convert full-stop at bol, - // some Windows servers need this, won't break anything (cipri) - // Bug #11731: full-stop at bol also needs to be encoded - // if this line would push us over the line_max limit. - $char = '=2E'; - } - - // Note, when changing this line, also change the ($dec == 46) - // check line, as it mimics this line due to Bug #11731 - // EOL is not counted - if ((strlen($newline) + strlen($char)) >= $line_max) { - // soft line break; " =\r\n" is okay - $output .= $newline . $escape . $eol; - $newline = ''; - } - $newline .= $char; - } // end of for - $output .= $newline . $eol; - unset($lines[$idx]); - } - // Don't want last crlf - $output = substr($output, 0, -1 * strlen($eol)); - return $output; - } - - /** - * Encodes the paramater of a header. - * - * @param string $name The name of the header-parameter - * @param string $value The value of the paramter - * @param string $charset The characterset of $value - * @param string $language The language used in $value - * @param string $encoding Parameter encoding. If not set, parameter value - * is encoded according to RFC2231 - * @param int $maxLength The maximum length of a line. Defauls to 75 - * - * @return string - * - * @access private - */ - function _buildHeaderParam($name, $value, $charset=null, $language=null, - $encoding=null, $maxLength=75 - ) { - // RFC 2045: - // value needs encoding if contains non-ASCII chars or is longer than 78 chars - if (!preg_match('#[^\x20-\x7E]#', $value)) { - $token_regexp = '#([^\x21,\x23-\x27,\x2A,\x2B,\x2D' - . ',\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])#'; - if (!preg_match($token_regexp, $value)) { - // token - if (strlen($name) + strlen($value) + 3 <= $maxLength) { - return " {$name}={$value}"; - } - } else { - // quoted-string - $quoted = addcslashes($value, '\\"'); - if (strlen($name) + strlen($quoted) + 5 <= $maxLength) { - return " {$name}=\"{$quoted}\""; - } - } - } - - // RFC2047: use quoted-printable/base64 encoding - if ($encoding == 'quoted-printable' || $encoding == 'base64') { - return $this->_buildRFC2047Param($name, $value, $charset, $encoding); - } - - // RFC2231: - $encValue = preg_replace_callback( - '/([^\x21,\x23,\x24,\x26,\x2B,\x2D,\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])/', - array($this, '_encodeReplaceCallback'), $value - ); - $value = "$charset'$language'$encValue"; - - $header = " {$name}*={$value}"; - if (strlen($header) <= $maxLength) { - return $header; - } - - $preLength = strlen(" {$name}*0*="); - $maxLength = max(16, $maxLength - $preLength - 3); - $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; - - $headers = array(); - $headCount = 0; - while ($value) { - $matches = array(); - $found = preg_match($maxLengthReg, $value, $matches); - if ($found) { - $headers[] = " {$name}*{$headCount}*={$matches[0]}"; - $value = substr($value, strlen($matches[0])); - } else { - $headers[] = " {$name}*{$headCount}*={$value}"; - $value = ''; - } - $headCount++; - } - - $headers = implode(';' . $this->_eol, $headers); - return $headers; - } - - /** - * Encodes header parameter as per RFC2047 if needed - * - * @param string $name The parameter name - * @param string $value The parameter value - * @param string $charset The parameter charset - * @param string $encoding Encoding type (quoted-printable or base64) - * @param int $maxLength Encoded parameter max length. Default: 76 - * - * @return string Parameter line - * @access private - */ - function _buildRFC2047Param($name, $value, $charset, - $encoding='quoted-printable', $maxLength=76 - ) { - // WARNING: RFC 2047 says: "An 'encoded-word' MUST NOT be used in - // parameter of a MIME Content-Type or Content-Disposition field", - // but... it's supported by many clients/servers - $quoted = ''; - - if ($encoding == 'base64') { - $value = base64_encode($value); - $prefix = '=?' . $charset . '?B?'; - $suffix = '?='; - - // 2 x SPACE, 2 x '"', '=', ';' - $add_len = strlen($prefix . $suffix) + strlen($name) + 6; - $len = $add_len + strlen($value); - - while ($len > $maxLength) { - // We can cut base64-encoded string every 4 characters - $real_len = floor(($maxLength - $add_len) / 4) * 4; - $_quote = substr($value, 0, $real_len); - $value = substr($value, $real_len); - - $quoted .= $prefix . $_quote . $suffix . $this->_eol . ' '; - $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' - $len = strlen($value) + $add_len; - } - $quoted .= $prefix . $value . $suffix; - - } else { - // quoted-printable - $value = $this->encodeQP($value); - $prefix = '=?' . $charset . '?Q?'; - $suffix = '?='; - - // 2 x SPACE, 2 x '"', '=', ';' - $add_len = strlen($prefix . $suffix) + strlen($name) + 6; - $len = $add_len + strlen($value); - - while ($len > $maxLength) { - $length = $maxLength - $add_len; - // don't break any encoded letters - if (preg_match("/^(.{0,$length}[^\=][^\=])/", $value, $matches)) { - $_quote = $matches[1]; - } - - $quoted .= $prefix . $_quote . $suffix . $this->_eol . ' '; - $value = substr($value, strlen($_quote)); - $add_len = strlen($prefix . $suffix) + 4; // 2 x SPACE, '"', ';' - $len = strlen($value) + $add_len; - } - - $quoted .= $prefix . $value . $suffix; - } - - return " {$name}=\"{$quoted}\""; - } - - /** - * Encodes a header as per RFC2047 - * - * @param string $name The header name - * @param string $value The header data to encode - * @param string $charset Character set name - * @param string $encoding Encoding name (base64 or quoted-printable) - * @param string $eol End-of-line sequence. Default: "\r\n" - * - * @return string Encoded header data (without a name) - * @access public - * @since 1.6.1 - */ - function encodeHeader($name, $value, $charset='ISO-8859-1', - $encoding='quoted-printable', $eol="\r\n" - ) { - // Structured headers - $comma_headers = array( - 'from', 'to', 'cc', 'bcc', 'sender', 'reply-to', - 'resent-from', 'resent-to', 'resent-cc', 'resent-bcc', - 'resent-sender', 'resent-reply-to', - 'return-receipt-to', 'disposition-notification-to', - ); - $other_headers = array( - 'references', 'in-reply-to', 'message-id', 'resent-message-id', - ); - - $name = strtolower($name); - - if (in_array($name, $comma_headers)) { - $separator = ','; - } else if (in_array($name, $other_headers)) { - $separator = ' '; - } - - if (!$charset) { - $charset = 'ISO-8859-1'; - } - - // Structured header (make sure addr-spec inside is not encoded) - if (!empty($separator)) { - $parts = Mail_mimePart::_explodeQuotedString($separator, $value); - $value = ''; - - foreach ($parts as $part) { - $part = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $part); - $part = trim($part); - - if (!$part) { - continue; - } - if ($value) { - $value .= $separator==',' ? $separator.' ' : ' '; - } else { - $value = $name . ': '; - } - - // let's find phrase (name) and/or addr-spec - if (preg_match('/^<\S+@\S+>$/', $part)) { - $value .= $part; - } else if (preg_match('/^\S+@\S+$/', $part)) { - // address without brackets and without name - $value .= $part; - } else if (preg_match('/<*\S+@\S+>*$/', $part, $matches)) { - // address with name (handle name) - $address = $matches[0]; - $word = str_replace($address, '', $part); - $word = trim($word); - // check if phrase requires quoting - if ($word) { - // non-ASCII: require encoding - if (preg_match('#([\x80-\xFF]){1}#', $word)) { - if ($word[0] == '"' && $word[strlen($word)-1] == '"') { - // de-quote quoted-string, encoding changes - // string to atom - $search = array("\\\"", "\\\\"); - $replace = array("\"", "\\"); - $word = str_replace($search, $replace, $word); - $word = substr($word, 1, -1); - } - // find length of last line - if (($pos = strrpos($value, $eol)) !== false) { - $last_len = strlen($value) - $pos; - } else { - $last_len = strlen($value); - } - $word = Mail_mimePart::encodeHeaderValue( - $word, $charset, $encoding, $last_len, $eol - ); - } else if (($word[0] != '"' || $word[strlen($word)-1] != '"') - && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $word) - ) { - // ASCII: quote string if needed - $word = '"'.addcslashes($word, '\\"').'"'; - } - } - $value .= $word.' '.$address; - } else { - // addr-spec not found, don't encode (?) - $value .= $part; - } - - // RFC2822 recommends 78 characters limit, use 76 from RFC2047 - $value = wordwrap($value, 76, $eol . ' '); - } - - // remove header name prefix (there could be EOL too) - $value = preg_replace( - '/^'.$name.':('.preg_quote($eol, '/').')* /', '', $value - ); - - } else { - // Unstructured header - // non-ASCII: require encoding - if (preg_match('#([\x80-\xFF]){1}#', $value)) { - if ($value[0] == '"' && $value[strlen($value)-1] == '"') { - // de-quote quoted-string, encoding changes - // string to atom - $search = array("\\\"", "\\\\"); - $replace = array("\"", "\\"); - $value = str_replace($search, $replace, $value); - $value = substr($value, 1, -1); - } - $value = Mail_mimePart::encodeHeaderValue( - $value, $charset, $encoding, strlen($name) + 2, $eol - ); - } else if (strlen($name.': '.$value) > 78) { - // ASCII: check if header line isn't too long and use folding - $value = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $value); - $tmp = wordwrap($name.': '.$value, 78, $eol . ' '); - $value = preg_replace('/^'.$name.':\s*/', '', $tmp); - // hard limit 998 (RFC2822) - $value = wordwrap($value, 998, $eol . ' ', true); - } - } - - return $value; - } - - /** - * Explode quoted string - * - * @param string $delimiter Delimiter expression string for preg_match() - * @param string $string Input string - * - * @return array String tokens array - * @access private - */ - function _explodeQuotedString($delimiter, $string) - { - $result = array(); - $strlen = strlen($string); - - for ($q=$p=$i=0; $i < $strlen; $i++) { - if ($string[$i] == "\"" - && (empty($string[$i-1]) || $string[$i-1] != "\\") - ) { - $q = $q ? false : true; - } else if (!$q && preg_match("/$delimiter/", $string[$i])) { - $result[] = substr($string, $p, $i - $p); - $p = $i + 1; - } - } - - $result[] = substr($string, $p); - return $result; - } - - /** - * Encodes a header value as per RFC2047 - * - * @param string $value The header data to encode - * @param string $charset Character set name - * @param string $encoding Encoding name (base64 or quoted-printable) - * @param int $prefix_len Prefix length. Default: 0 - * @param string $eol End-of-line sequence. Default: "\r\n" - * - * @return string Encoded header data - * @access public - * @since 1.6.1 - */ - function encodeHeaderValue($value, $charset, $encoding, $prefix_len=0, $eol="\r\n") - { - // #17311: Use multibyte aware method (requires mbstring extension) - if ($result = Mail_mimePart::encodeMB($value, $charset, $encoding, $prefix_len, $eol)) { - return $result; - } - - // Generate the header using the specified params and dynamicly - // determine the maximum length of such strings. - // 75 is the value specified in the RFC. - $encoding = $encoding == 'base64' ? 'B' : 'Q'; - $prefix = '=?' . $charset . '?' . $encoding .'?'; - $suffix = '?='; - $maxLength = 75 - strlen($prefix . $suffix); - $maxLength1stLine = $maxLength - $prefix_len; - - if ($encoding == 'B') { - // Base64 encode the entire string - $value = base64_encode($value); - - // We can cut base64 every 4 characters, so the real max - // we can get must be rounded down. - $maxLength = $maxLength - ($maxLength % 4); - $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4); - - $cutpoint = $maxLength1stLine; - $output = ''; - - while ($value) { - // Split translated string at every $maxLength - $part = substr($value, 0, $cutpoint); - $value = substr($value, $cutpoint); - $cutpoint = $maxLength; - // RFC 2047 specifies that any split header should - // be seperated by a CRLF SPACE. - if ($output) { - $output .= $eol . ' '; - } - $output .= $prefix . $part . $suffix; - } - $value = $output; - } else { - // quoted-printable encoding has been selected - $value = Mail_mimePart::encodeQP($value); - - // This regexp will break QP-encoded text at every $maxLength - // but will not break any encoded letters. - $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|"; - $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; - - if (strlen($value) > $maxLength1stLine) { - // Begin with the regexp for the first line. - $reg = $reg1st; - $output = ''; - while ($value) { - // Split translated string at every $maxLength - // But make sure not to break any translated chars. - $found = preg_match($reg, $value, $matches); - - // After this first line, we need to use a different - // regexp for the first line. - $reg = $reg2nd; - - // Save the found part and encapsulate it in the - // prefix & suffix. Then remove the part from the - // $value_out variable. - if ($found) { - $part = $matches[0]; - $len = strlen($matches[0]); - $value = substr($value, $len); - } else { - $part = $value; - $value = ''; - } - - // RFC 2047 specifies that any split header should - // be seperated by a CRLF SPACE - if ($output) { - $output .= $eol . ' '; - } - $output .= $prefix . $part . $suffix; - } - $value = $output; - } else { - $value = $prefix . $value . $suffix; - } - } - - return $value; - } - - /** - * Encodes the given string using quoted-printable - * - * @param string $str String to encode - * - * @return string Encoded string - * @access public - * @since 1.6.0 - */ - function encodeQP($str) - { - // Bug #17226 RFC 2047 restricts some characters - // if the word is inside a phrase, permitted chars are only: - // ASCII letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" - - // "=", "_", "?" must be encoded - $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; - $str = preg_replace_callback( - $regexp, array('Mail_mimePart', '_qpReplaceCallback'), $str - ); - - return str_replace(' ', '_', $str); - } - - /** - * Encodes the given string using base64 or quoted-printable. - * This method makes sure that encoded-word represents an integral - * number of characters as per RFC2047. - * - * @param string $str String to encode - * @param string $charset Character set name - * @param string $encoding Encoding name (base64 or quoted-printable) - * @param int $prefix_len Prefix length. Default: 0 - * @param string $eol End-of-line sequence. Default: "\r\n" - * - * @return string Encoded string - * @access public - * @since 1.8.0 - */ - function encodeMB($str, $charset, $encoding, $prefix_len=0, $eol="\r\n") - { - if (!function_exists('mb_substr') || !function_exists('mb_strlen')) { - return; - } - - $encoding = $encoding == 'base64' ? 'B' : 'Q'; - // 75 is the value specified in the RFC - $prefix = '=?' . $charset . '?'.$encoding.'?'; - $suffix = '?='; - $maxLength = 75 - strlen($prefix . $suffix); - - // A multi-octet character may not be split across adjacent encoded-words - // So, we'll loop over each character - // mb_stlen() with wrong charset will generate a warning here and return null - $length = mb_strlen($str, $charset); - $result = ''; - $line_length = $prefix_len; - - if ($encoding == 'B') { - // base64 - $start = 0; - $prev = ''; - - for ($i=1; $i<=$length; $i++) { - // See #17311 - $chunk = mb_substr($str, $start, $i-$start, $charset); - $chunk = base64_encode($chunk); - $chunk_len = strlen($chunk); - - if ($line_length + $chunk_len == $maxLength || $i == $length) { - if ($result) { - $result .= "\n"; - } - $result .= $chunk; - $line_length = 0; - $start = $i; - } else if ($line_length + $chunk_len > $maxLength) { - if ($result) { - $result .= "\n"; - } - if ($prev) { - $result .= $prev; - } - $line_length = 0; - $start = $i - 1; - } else { - $prev = $chunk; - } - } - } else { - // quoted-printable - // see encodeQP() - $regexp = '/([\x22-\x29\x2C\x2E\x3A-\x40\x5B-\x60\x7B-\x7E\x80-\xFF])/'; - - for ($i=0; $i<=$length; $i++) { - $char = mb_substr($str, $i, 1, $charset); - // RFC recommends underline (instead of =20) in place of the space - // that's one of the reasons why we're not using iconv_mime_encode() - if ($char == ' ') { - $char = '_'; - $char_len = 1; - } else { - $char = preg_replace_callback( - $regexp, array('Mail_mimePart', '_qpReplaceCallback'), $char - ); - $char_len = strlen($char); - } - - if ($line_length + $char_len > $maxLength) { - if ($result) { - $result .= "\n"; - } - $line_length = 0; - } - - $result .= $char; - $line_length += $char_len; - } - } - - if ($result) { - $result = $prefix - .str_replace("\n", $suffix.$eol.' '.$prefix, $result).$suffix; - } - - return $result; - } - - /** - * Callback function to replace extended characters (\x80-xFF) with their - * ASCII values (RFC2047: quoted-printable) - * - * @param array $matches Preg_replace's matches array - * - * @return string Encoded character string - * @access private - */ - function _qpReplaceCallback($matches) - { - return sprintf('=%02X', ord($matches[1])); - } - - /** - * Callback function to replace extended characters (\x80-xFF) with their - * ASCII values (RFC2231) - * - * @param array $matches Preg_replace's matches array - * - * @return string Encoded character string - * @access private - */ - function _encodeReplaceCallback($matches) - { - return sprintf('%%%02X', ord($matches[1])); - } - -} // End of class diff --git a/data/module/Mail/mock.php b/data/module/Mail/mock.php deleted file mode 100644 index 61570ba408..0000000000 --- a/data/module/Mail/mock.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: mock.php 294747 2010-02-08 08:18:33Z clockwerx $ - * @link http://pear.php.net/package/Mail/ - */ - -/** - * Mock implementation of the PEAR Mail:: interface for testing. - * @access public - * @package Mail - * @version $Revision: 294747 $ - */ -class Mail_mock extends Mail { - - /** - * Array of messages that have been sent with the mock. - * - * @var array - * @access public - */ - var $sentMessages = array(); - - /** - * Callback before sending mail. - * - * @var callback - */ - var $_preSendCallback; - - /** - * Callback after sending mai. - * - * @var callback - */ - var $_postSendCallback; - - /** - * Constructor. - * - * Instantiates a new Mail_mock:: object based on the parameters - * passed in. It looks for the following parameters, both optional: - * preSendCallback Called before an email would be sent. - * postSendCallback Called after an email would have been sent. - * - * @param array Hash containing any parameters. - * @access public - */ - function Mail_mock($params) - { - if (isset($params['preSendCallback']) && - is_callable($params['preSendCallback'])) { - $this->_preSendCallback = $params['preSendCallback']; - } - - if (isset($params['postSendCallback']) && - is_callable($params['postSendCallback'])) { - $this->_postSendCallback = $params['postSendCallback']; - } - } - - /** - * Implements Mail_mock::send() function. Silently discards all - * mail. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (ie, 'Subject'), and the array value - * is the header value (ie, 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * Mime parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * @access public - */ - function send($recipients, $headers, $body) - { - if ($this->_preSendCallback) { - call_user_func_array($this->_preSendCallback, - array(&$this, $recipients, $headers, $body)); - } - - $entry = array('recipients' => $recipients, 'headers' => $headers, 'body' => $body); - $this->sentMessages[] = $entry; - - if ($this->_postSendCallback) { - call_user_func_array($this->_postSendCallback, - array(&$this, $recipients, $headers, $body)); - } - - return true; - } - -} diff --git a/data/module/Mail/null.php b/data/module/Mail/null.php deleted file mode 100644 index c8d9fbc16c..0000000000 --- a/data/module/Mail/null.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright 2010 Phil Kernick - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Mail/ - */ - -/** - * Null implementation of the PEAR Mail:: interface. - * @access public - * @package Mail - * @version $Revision$ - */ -class Mail_null extends Mail { - - /** - * Implements Mail_null::send() function. Silently discards all - * mail. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (ie, 'Subject'), and the array value - * is the header value (ie, 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * Mime parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * @access public - */ - function send($recipients, $headers, $body) - { - return true; - } - -} diff --git a/data/module/Mail/sendmail.php b/data/module/Mail/sendmail.php deleted file mode 100644 index 627b0e8f6a..0000000000 --- a/data/module/Mail/sendmail.php +++ /dev/null @@ -1,171 +0,0 @@ - | -// +----------------------------------------------------------------------+ - -/** - * Sendmail implementation of the PEAR Mail:: interface. - * @access public - * @package Mail - * @version $Revision$ - */ -class Mail_sendmail extends Mail { - - /** - * The location of the sendmail or sendmail wrapper binary on the - * filesystem. - * @var string - */ - var $sendmail_path = '/usr/sbin/sendmail'; - - /** - * Any extra command-line parameters to pass to the sendmail or - * sendmail wrapper binary. - * @var string - */ - var $sendmail_args = '-i'; - - /** - * Constructor. - * - * Instantiates a new Mail_sendmail:: object based on the parameters - * passed in. It looks for the following parameters: - * sendmail_path The location of the sendmail binary on the - * filesystem. Defaults to '/usr/sbin/sendmail'. - * - * sendmail_args Any extra parameters to pass to the sendmail - * or sendmail wrapper binary. - * - * If a parameter is present in the $params array, it replaces the - * default. - * - * @param array $params Hash containing any parameters different from the - * defaults. - * @access public - */ - function Mail_sendmail($params) - { - if (isset($params['sendmail_path'])) { - $this->sendmail_path = $params['sendmail_path']; - } - if (isset($params['sendmail_args'])) { - $this->sendmail_args = $params['sendmail_args']; - } - - /* - * Because we need to pass message headers to the sendmail program on - * the commandline, we can't guarantee the use of the standard "\r\n" - * separator. Instead, we use the system's native line separator. - */ - if (defined('PHP_EOL')) { - $this->sep = PHP_EOL; - } else { - $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n"; - } - } - - /** - * Implements Mail::send() function using the sendmail - * command-line binary. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (ie, 'Subject'), and the array value - * is the header value (ie, 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * Mime parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * @access public - */ - function send($recipients, $headers, $body) - { - if (!is_array($headers)) { - return PEAR::raiseError('$headers must be an array'); - } - - $result = $this->_sanitizeHeaders($headers); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $recipients = $this->parseRecipients($recipients); - if (is_a($recipients, 'PEAR_Error')) { - return $recipients; - } - $recipients = implode(' ', array_map('escapeshellarg', $recipients)); - - $headerElements = $this->prepareHeaders($headers); - if (is_a($headerElements, 'PEAR_Error')) { - return $headerElements; - } - list($from, $text_headers) = $headerElements; - - /* Since few MTAs are going to allow this header to be forged - * unless it's in the MAIL FROM: exchange, we'll use - * Return-Path instead of From: if it's set. */ - if (!empty($headers['Return-Path'])) { - $from = $headers['Return-Path']; - } - - if (!isset($from)) { - return PEAR::raiseError('No from address given.'); - } elseif (strpos($from, ' ') !== false || - strpos($from, ';') !== false || - strpos($from, '&') !== false || - strpos($from, '`') !== false) { - return PEAR::raiseError('From address specified with dangerous characters.'); - } - - $from = escapeshellarg($from); // Security bug #16200 - - $mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w'); - if (!$mail) { - return PEAR::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.'); - } - - // Write the headers following by two newlines: one to end the headers - // section and a second to separate the headers block from the body. - fputs($mail, $text_headers . $this->sep . $this->sep); - - fputs($mail, $body); - $result = pclose($mail); - if (version_compare(phpversion(), '4.2.3') == -1) { - // With older php versions, we need to shift the pclose - // result to get the exit code. - $result = $result >> 8 & 0xFF; - } - - if ($result != 0) { - return PEAR::raiseError('sendmail returned error code ' . $result, - $result); - } - - return true; - } - -} diff --git a/data/module/Mail/smtp.php b/data/module/Mail/smtp.php deleted file mode 100644 index 52ea602086..0000000000 --- a/data/module/Mail/smtp.php +++ /dev/null @@ -1,444 +0,0 @@ - - * @author Chuck Hagenbuch - * @copyright 2010 Chuck Hagenbuch - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: smtp.php 294747 2010-02-08 08:18:33Z clockwerx $ - * @link http://pear.php.net/package/Mail/ - */ - -/** Error: Failed to create a Net_SMTP object */ -define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000); - -/** Error: Failed to connect to SMTP server */ -define('PEAR_MAIL_SMTP_ERROR_CONNECT', 10001); - -/** Error: SMTP authentication failure */ -define('PEAR_MAIL_SMTP_ERROR_AUTH', 10002); - -/** Error: No From: address has been provided */ -define('PEAR_MAIL_SMTP_ERROR_FROM', 10003); - -/** Error: Failed to set sender */ -define('PEAR_MAIL_SMTP_ERROR_SENDER', 10004); - -/** Error: Failed to add recipient */ -define('PEAR_MAIL_SMTP_ERROR_RECIPIENT', 10005); - -/** Error: Failed to send data */ -define('PEAR_MAIL_SMTP_ERROR_DATA', 10006); - -/** - * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. - * @access public - * @package Mail - * @version $Revision: 294747 $ - */ -class Mail_smtp extends Mail { - - /** - * SMTP connection object. - * - * @var object - * @access private - */ - var $_smtp = null; - - /** - * The list of service extension parameters to pass to the Net_SMTP - * mailFrom() command. - * @var array - */ - var $_extparams = array(); - - /** - * The SMTP host to connect to. - * @var string - */ - var $host = 'localhost'; - - /** - * The port the SMTP server is on. - * @var integer - */ - var $port = 25; - - /** - * Should SMTP authentication be used? - * - * This value may be set to true, false or the name of a specific - * authentication method. - * - * If the value is set to true, the Net_SMTP package will attempt to use - * the best authentication method advertised by the remote SMTP server. - * - * @var mixed - */ - var $auth = false; - - /** - * The username to use if the SMTP server requires authentication. - * @var string - */ - var $username = ''; - - /** - * The password to use if the SMTP server requires authentication. - * @var string - */ - var $password = ''; - - /** - * Hostname or domain that will be sent to the remote SMTP server in the - * HELO / EHLO message. - * - * @var string - */ - var $localhost = 'localhost'; - - /** - * SMTP connection timeout value. NULL indicates no timeout. - * - * @var integer - */ - var $timeout = null; - - /** - * Turn on Net_SMTP debugging? - * - * @var boolean $debug - */ - var $debug = false; - - /** - * Indicates whether or not the SMTP connection should persist over - * multiple calls to the send() method. - * - * @var boolean - */ - var $persist = false; - - /** - * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server - * supports it. This speeds up delivery over high-latency connections. By - * default, use the default value supplied by Net_SMTP. - * @var bool - */ - var $pipelining; - - /** - * Constructor. - * - * Instantiates a new Mail_smtp:: object based on the parameters - * passed in. It looks for the following parameters: - * host The server to connect to. Defaults to localhost. - * port The port to connect to. Defaults to 25. - * auth SMTP authentication. Defaults to none. - * username The username to use for SMTP auth. No default. - * password The password to use for SMTP auth. No default. - * localhost The local hostname / domain. Defaults to localhost. - * timeout The SMTP connection timeout. Defaults to none. - * verp Whether to use VERP or not. Defaults to false. - * DEPRECATED as of 1.2.0 (use setMailParams()). - * debug Activate SMTP debug mode? Defaults to false. - * persist Should the SMTP connection persist? - * pipelining Use SMTP command pipelining - * - * If a parameter is present in the $params array, it replaces the - * default. - * - * @param array Hash containing any parameters different from the - * defaults. - * @access public - */ - function Mail_smtp($params) - { - if (isset($params['host'])) $this->host = $params['host']; - if (isset($params['port'])) $this->port = $params['port']; - if (isset($params['auth'])) $this->auth = $params['auth']; - if (isset($params['username'])) $this->username = $params['username']; - if (isset($params['password'])) $this->password = $params['password']; - if (isset($params['localhost'])) $this->localhost = $params['localhost']; - if (isset($params['timeout'])) $this->timeout = $params['timeout']; - if (isset($params['debug'])) $this->debug = (bool)$params['debug']; - if (isset($params['persist'])) $this->persist = (bool)$params['persist']; - if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining']; - - // Deprecated options - if (isset($params['verp'])) { - $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']); - } - - register_shutdown_function(array(&$this, '_Mail_smtp')); - } - - /** - * Destructor implementation to ensure that we disconnect from any - * potentially-alive persistent SMTP connections. - */ - function _Mail_smtp() - { - $this->disconnect(); - } - - /** - * Implements Mail::send() function using SMTP. - * - * @param mixed $recipients Either a comma-seperated list of recipients - * (RFC822 compliant), or an array of recipients, - * each RFC822 valid. This may contain recipients not - * specified in the headers, for Bcc:, resending - * messages, etc. - * - * @param array $headers The array of headers to send with the mail, in an - * associative array, where the array key is the - * header name (e.g., 'Subject'), and the array value - * is the header value (e.g., 'test'). The header - * produced from those values would be 'Subject: - * test'. - * - * @param string $body The full text of the message body, including any - * MIME parts, etc. - * - * @return mixed Returns true on success, or a PEAR_Error - * containing a descriptive error message on - * failure. - * @access public - */ - function send($recipients, $headers, $body) - { - /* If we don't already have an SMTP object, create one. */ - $result = &$this->getSMTPObject(); - if (PEAR::isError($result)) { - return $result; - } - - if (!is_array($headers)) { - return PEAR::raiseError('$headers must be an array'); - } - - $this->_sanitizeHeaders($headers); - - $headerElements = $this->prepareHeaders($headers); - if (is_a($headerElements, 'PEAR_Error')) { - $this->_smtp->rset(); - return $headerElements; - } - list($from, $textHeaders) = $headerElements; - - /* Since few MTAs are going to allow this header to be forged - * unless it's in the MAIL FROM: exchange, we'll use - * Return-Path instead of From: if it's set. */ - if (!empty($headers['Return-Path'])) { - $from = $headers['Return-Path']; - } - - if (!isset($from)) { - $this->_smtp->rset(); - return PEAR::raiseError('No From: address has been provided', - PEAR_MAIL_SMTP_ERROR_FROM); - } - - $params = null; - if (!empty($this->_extparams)) { - foreach ($this->_extparams as $key => $val) { - $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val); - } - } - if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) { - $error = $this->_error("Failed to set sender: $from", $res); - $this->_smtp->rset(); - return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_SENDER); - } - - $recipients = $this->parseRecipients($recipients); - if (is_a($recipients, 'PEAR_Error')) { - $this->_smtp->rset(); - return $recipients; - } - - foreach ($recipients as $recipient) { - $res = $this->_smtp->rcptTo($recipient); - if (is_a($res, 'PEAR_Error')) { - $error = $this->_error("Failed to add recipient: $recipient", $res); - $this->_smtp->rset(); - return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_RECIPIENT); - } - } - - /* Send the message's headers and the body as SMTP data. */ - $res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body); - list(,$args) = $this->_smtp->getResponse(); - - if (preg_match("/Ok: queued as (.*)/", $args, $queued)) { - $this->queued_as = $queued[1]; - } - - /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to. - * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */ - $this->greeting = $this->_smtp->getGreeting(); - - if (is_a($res, 'PEAR_Error')) { - $error = $this->_error('Failed to send data', $res); - $this->_smtp->rset(); - return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_DATA); - } - - /* If persistent connections are disabled, destroy our SMTP object. */ - if ($this->persist === false) { - $this->disconnect(); - } - - return true; - } - - /** - * Connect to the SMTP server by instantiating a Net_SMTP object. - * - * @return mixed Returns a reference to the Net_SMTP object on success, or - * a PEAR_Error containing a descriptive error message on - * failure. - * - * @since 1.2.0 - * @access public - */ - function &getSMTPObject() - { - if (is_object($this->_smtp) !== false) { - return $this->_smtp; - } - - include_once 'Net/SMTP.php'; - $this->_smtp = &new Net_SMTP($this->host, - $this->port, - $this->localhost); - - /* If we still don't have an SMTP object at this point, fail. */ - if (is_object($this->_smtp) === false) { - return PEAR::raiseError('Failed to create a Net_SMTP object', - PEAR_MAIL_SMTP_ERROR_CREATE); - } - - /* Configure the SMTP connection. */ - if ($this->debug) { - $this->_smtp->setDebug(true); - } - - /* Attempt to connect to the configured SMTP server. */ - if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) { - $error = $this->_error('Failed to connect to ' . - $this->host . ':' . $this->port, - $res); - return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT); - } - - /* Attempt to authenticate if authentication has been enabled. */ - if ($this->auth) { - $method = is_string($this->auth) ? $this->auth : ''; - - if (PEAR::isError($res = $this->_smtp->auth($this->username, - $this->password, - $method))) { - $error = $this->_error("$method authentication failure", - $res); - $this->_smtp->rset(); - return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH); - } - } - - return $this->_smtp; - } - - /** - * Add parameter associated with a SMTP service extension. - * - * @param string Extension keyword. - * @param string Any value the keyword needs. - * - * @since 1.2.0 - * @access public - */ - function addServiceExtensionParameter($keyword, $value = null) - { - $this->_extparams[$keyword] = $value; - } - - /** - * Disconnect and destroy the current SMTP connection. - * - * @return boolean True if the SMTP connection no longer exists. - * - * @since 1.1.9 - * @access public - */ - function disconnect() - { - /* If we have an SMTP object, disconnect and destroy it. */ - if (is_object($this->_smtp) && $this->_smtp->disconnect()) { - $this->_smtp = null; - } - - /* We are disconnected if we no longer have an SMTP object. */ - return ($this->_smtp === null); - } - - /** - * Build a standardized string describing the current SMTP error. - * - * @param string $text Custom string describing the error context. - * @param object $error Reference to the current PEAR_Error object. - * - * @return string A string describing the current SMTP error. - * - * @since 1.1.7 - * @access private - */ - function _error($text, &$error) - { - /* Split the SMTP response into a code and a response string. */ - list($code, $response) = $this->_smtp->getResponse(); - - /* Build our standardized error string. */ - return $text - . ' [SMTP: ' . $error->getMessage() - . " (code: $code, response: $response)]"; - } - -} diff --git a/data/module/Mail/smtpmx.php b/data/module/Mail/smtpmx.php deleted file mode 100644 index f0b6940868..0000000000 --- a/data/module/Mail/smtpmx.php +++ /dev/null @@ -1,502 +0,0 @@ - - * @copyright 2010 gERD Schaufelberger - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: smtpmx.php 294747 2010-02-08 08:18:33Z clockwerx $ - * @link http://pear.php.net/package/Mail/ - */ - -require_once 'Net/SMTP.php'; - -/** - * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class. - * - * - * @access public - * @author gERD Schaufelberger - * @package Mail - * @version $Revision: 294747 $ - */ -class Mail_smtpmx extends Mail { - - /** - * SMTP connection object. - * - * @var object - * @access private - */ - var $_smtp = null; - - /** - * The port the SMTP server is on. - * @var integer - * @see getservicebyname() - */ - var $port = 25; - - /** - * Hostname or domain that will be sent to the remote SMTP server in the - * HELO / EHLO message. - * - * @var string - * @see posix_uname() - */ - var $mailname = 'localhost'; - - /** - * SMTP connection timeout value. NULL indicates no timeout. - * - * @var integer - */ - var $timeout = 10; - - /** - * use either PEAR:Net_DNS or getmxrr - * - * @var boolean - */ - var $withNetDns = true; - - /** - * PEAR:Net_DNS_Resolver - * - * @var object - */ - var $resolver; - - /** - * Whether to use VERP or not. If not a boolean, the string value - * will be used as the VERP separators. - * - * @var mixed boolean or string - */ - var $verp = false; - - /** - * Whether to use VRFY or not. - * - * @var boolean $vrfy - */ - var $vrfy = false; - - /** - * Switch to test mode - don't send emails for real - * - * @var boolean $debug - */ - var $test = false; - - /** - * Turn on Net_SMTP debugging? - * - * @var boolean $peardebug - */ - var $debug = false; - - /** - * internal error codes - * - * translate internal error identifier to PEAR-Error codes and human - * readable messages. - * - * @var boolean $debug - * @todo as I need unique error-codes to identify what exactly went wrond - * I did not use intergers as it should be. Instead I added a "namespace" - * for each code. This avoids conflicts with error codes from different - * classes. How can I use unique error codes and stay conform with PEAR? - */ - var $errorCode = array( - 'not_connected' => array( - 'code' => 1, - 'msg' => 'Could not connect to any mail server ({HOST}) at port {PORT} to send mail to {RCPT}.' - ), - 'failed_vrfy_rcpt' => array( - 'code' => 2, - 'msg' => 'Recipient "{RCPT}" could not be veryfied.' - ), - 'failed_set_from' => array( - 'code' => 3, - 'msg' => 'Failed to set sender: {FROM}.' - ), - 'failed_set_rcpt' => array( - 'code' => 4, - 'msg' => 'Failed to set recipient: {RCPT}.' - ), - 'failed_send_data' => array( - 'code' => 5, - 'msg' => 'Failed to send mail to: {RCPT}.' - ), - 'no_from' => array( - 'code' => 5, - 'msg' => 'No from address has be provided.' - ), - 'send_data' => array( - 'code' => 7, - 'msg' => 'Failed to create Net_SMTP object.' - ), - 'no_mx' => array( - 'code' => 8, - 'msg' => 'No MX-record for {RCPT} found.' - ), - 'no_resolver' => array( - 'code' => 9, - 'msg' => 'Could not start resolver! Install PEAR:Net_DNS or switch off "netdns"' - ), - 'failed_rset' => array( - 'code' => 10, - 'msg' => 'RSET command failed, SMTP-connection corrupt.' - ), - ); - - /** - * Constructor. - * - * Instantiates a new Mail_smtp:: object based on the parameters - * passed in. It looks for the following parameters: - * mailname The name of the local mail system (a valid hostname which matches the reverse lookup) - * port smtp-port - the default comes from getservicebyname() and should work fine - * timeout The SMTP connection timeout. Defaults to 30 seconds. - * vrfy Whether to use VRFY or not. Defaults to false. - * verp Whether to use VERP or not. Defaults to false. - * test Activate test mode? Defaults to false. - * debug Activate SMTP and Net_DNS debug mode? Defaults to false. - * netdns whether to use PEAR:Net_DNS or the PHP build in function getmxrr, default is true - * - * If a parameter is present in the $params array, it replaces the - * default. - * - * @access public - * @param array Hash containing any parameters different from the - * defaults. - * @see _Mail_smtpmx() - */ - function __construct($params) - { - if (isset($params['mailname'])) { - $this->mailname = $params['mailname']; - } else { - // try to find a valid mailname - if (function_exists('posix_uname')) { - $uname = posix_uname(); - $this->mailname = $uname['nodename']; - } - } - - // port number - if (isset($params['port'])) { - $this->_port = $params['port']; - } else { - $this->_port = getservbyname('smtp', 'tcp'); - } - - if (isset($params['timeout'])) $this->timeout = $params['timeout']; - if (isset($params['verp'])) $this->verp = $params['verp']; - if (isset($params['test'])) $this->test = $params['test']; - if (isset($params['peardebug'])) $this->test = $params['peardebug']; - if (isset($params['netdns'])) $this->withNetDns = $params['netdns']; - } - - /** - * Constructor wrapper for PHP4 - * - * @access public - * @param array Hash containing any parameters different from the defaults - * @see __construct() - */ - function Mail_smtpmx($params) - { - $this->__construct($params); - register_shutdown_function(array(&$this, '__destruct')); - } - - /** - * Destructor implementation to ensure that we disconnect from any - * potentially-alive persistent SMTP connections. - */ - function __destruct() - { - if (is_object($this->_smtp)) { - $this->_smtp->disconnect(); - $this->_smtp = null; - } - } - - /** - * Implements Mail::send() function using SMTP direct delivery - * - * @access public - * @param mixed $recipients in RFC822 style or array - * @param array $headers The array of headers to send with the mail. - * @param string $body The full text of the message body, - * @return mixed Returns true on success, or a PEAR_Error - */ - function send($recipients, $headers, $body) - { - if (!is_array($headers)) { - return PEAR::raiseError('$headers must be an array'); - } - - $result = $this->_sanitizeHeaders($headers); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - // Prepare headers - $headerElements = $this->prepareHeaders($headers); - if (is_a($headerElements, 'PEAR_Error')) { - return $headerElements; - } - list($from, $textHeaders) = $headerElements; - - // use 'Return-Path' if possible - if (!empty($headers['Return-Path'])) { - $from = $headers['Return-Path']; - } - if (!isset($from)) { - return $this->_raiseError('no_from'); - } - - // Prepare recipients - $recipients = $this->parseRecipients($recipients); - if (is_a($recipients, 'PEAR_Error')) { - return $recipients; - } - - foreach ($recipients as $rcpt) { - list($user, $host) = explode('@', $rcpt); - - $mx = $this->_getMx($host); - if (is_a($mx, 'PEAR_Error')) { - return $mx; - } - - if (empty($mx)) { - $info = array('rcpt' => $rcpt); - return $this->_raiseError('no_mx', $info); - } - - $connected = false; - foreach ($mx as $mserver => $mpriority) { - $this->_smtp = new Net_SMTP($mserver, $this->port, $this->mailname); - - // configure the SMTP connection. - if ($this->debug) { - $this->_smtp->setDebug(true); - } - - // attempt to connect to the configured SMTP server. - $res = $this->_smtp->connect($this->timeout); - if (is_a($res, 'PEAR_Error')) { - $this->_smtp = null; - continue; - } - - // connection established - if ($res) { - $connected = true; - break; - } - } - - if (!$connected) { - $info = array( - 'host' => implode(', ', array_keys($mx)), - 'port' => $this->port, - 'rcpt' => $rcpt, - ); - return $this->_raiseError('not_connected', $info); - } - - // Verify recipient - if ($this->vrfy) { - $res = $this->_smtp->vrfy($rcpt); - if (is_a($res, 'PEAR_Error')) { - $info = array('rcpt' => $rcpt); - return $this->_raiseError('failed_vrfy_rcpt', $info); - } - } - - // mail from: - $args['verp'] = $this->verp; - $res = $this->_smtp->mailFrom($from, $args); - if (is_a($res, 'PEAR_Error')) { - $info = array('from' => $from); - return $this->_raiseError('failed_set_from', $info); - } - - // rcpt to: - $res = $this->_smtp->rcptTo($rcpt); - if (is_a($res, 'PEAR_Error')) { - $info = array('rcpt' => $rcpt); - return $this->_raiseError('failed_set_rcpt', $info); - } - - // Don't send anything in test mode - if ($this->test) { - $result = $this->_smtp->rset(); - $res = $this->_smtp->rset(); - if (is_a($res, 'PEAR_Error')) { - return $this->_raiseError('failed_rset'); - } - - $this->_smtp->disconnect(); - $this->_smtp = null; - return true; - } - - // Send data - $res = $this->_smtp->data("$textHeaders\r\n$body"); - if (is_a($res, 'PEAR_Error')) { - $info = array('rcpt' => $rcpt); - return $this->_raiseError('failed_send_data', $info); - } - - $this->_smtp->disconnect(); - $this->_smtp = null; - } - - return true; - } - - /** - * Recieve mx rexords for a spciefied host - * - * The MX records - * - * @access private - * @param string $host mail host - * @return mixed sorted - */ - function _getMx($host) - { - $mx = array(); - - if ($this->withNetDns) { - $res = $this->_loadNetDns(); - if (is_a($res, 'PEAR_Error')) { - return $res; - } - - $response = $this->resolver->query($host, 'MX'); - if (!$response) { - return false; - } - - foreach ($response->answer as $rr) { - if ($rr->type == 'MX') { - $mx[$rr->exchange] = $rr->preference; - } - } - } else { - $mxHost = array(); - $mxWeight = array(); - - if (!getmxrr($host, $mxHost, $mxWeight)) { - return false; - } - for ($i = 0; $i < count($mxHost); ++$i) { - $mx[$mxHost[$i]] = $mxWeight[$i]; - } - } - - asort($mx); - return $mx; - } - - /** - * initialize PEAR:Net_DNS_Resolver - * - * @access private - * @return boolean true on success - */ - function _loadNetDns() - { - if (is_object($this->resolver)) { - return true; - } - - if (!include_once 'Net/DNS.php') { - return $this->_raiseError('no_resolver'); - } - - $this->resolver = new Net_DNS_Resolver(); - if ($this->debug) { - $this->resolver->test = 1; - } - - return true; - } - - /** - * raise standardized error - * - * include additional information in error message - * - * @access private - * @param string $id maps error ids to codes and message - * @param array $info optional information in associative array - * @see _errorCode - */ - function _raiseError($id, $info = array()) - { - $code = $this->errorCode[$id]['code']; - $msg = $this->errorCode[$id]['msg']; - - // include info to messages - if (!empty($info)) { - $search = array(); - $replace = array(); - - foreach ($info as $key => $value) { - array_push($search, '{' . strtoupper($key) . '}'); - array_push($replace, $value); - } - - $msg = str_replace($search, $replace, $msg); - } - - return PEAR::raiseError($msg, $code); - } - -} diff --git a/data/module/Mobile/Detect.php b/data/module/Mobile/Detect.php deleted file mode 100755 index b6eb0da21b..0000000000 --- a/data/module/Mobile/Detect.php +++ /dev/null @@ -1,1248 +0,0 @@ -, Nick Ilyin - * Original author: Victor Stanciu - * - * @license Code and contributions have 'MIT License' - * More details: https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt - * - * @link Homepage: http://mobiledetect.net - * GitHub Repo: https://github.com/serbanghita/Mobile-Detect - * Google Code: http://code.google.com/p/php-mobile-detect/ - * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md - * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples - * - * @version 2.8.3 - */ - -class Mobile_Detect -{ - /** - * Mobile detection type. - * - * @deprecated since version 2.6.9 - */ - const DETECTION_TYPE_MOBILE = 'mobile'; - - /** - * Extended detection type. - * - * @deprecated since version 2.6.9 - */ - const DETECTION_TYPE_EXTENDED = 'extended'; - - /** - * A frequently used regular expression to extract version #s. - * - * @deprecated since version 2.6.9 - */ - const VER = '([\w._\+]+)'; - - /** - * Top-level device. - */ - const MOBILE_GRADE_A = 'A'; - - /** - * Mid-level device. - */ - const MOBILE_GRADE_B = 'B'; - - /** - * Low-level device. - */ - const MOBILE_GRADE_C = 'C'; - - /** - * Stores the version number of the current release. - */ - const VERSION = '2.8.3'; - - /** - * A type for the version() method indicating a string return value. - */ - const VERSION_TYPE_STRING = 'text'; - - /** - * A type for the version() method indicating a float return value. - */ - const VERSION_TYPE_FLOAT = 'float'; - - /** - * The User-Agent HTTP header is stored in here. - * @var string - */ - protected $userAgent = null; - - /** - * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. - * @var array - */ - protected $httpHeaders = array(); - - /** - * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED. - * - * @deprecated since version 2.6.9 - * - * @var string - */ - protected $detectionType = self::DETECTION_TYPE_MOBILE; - - /** - * HTTP headers that trigger the 'isMobile' detection - * to be true. - * - * @var array - */ - protected static $mobileHeaders = array( - - 'HTTP_ACCEPT' => array('matches' => array( - // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/ - 'application/x-obml2d', - // BlackBerry devices. - 'application/vnd.rim.html', - 'text/vnd.wap.wml', - 'application/vnd.wap.xhtml+xml' - )), - 'HTTP_X_WAP_PROFILE' => null, - 'HTTP_X_WAP_CLIENTID' => null, - 'HTTP_WAP_CONNECTION' => null, - 'HTTP_PROFILE' => null, - // Reported by Opera on Nokia devices (eg. C3). - 'HTTP_X_OPERAMINI_PHONE_UA' => null, - 'HTTP_X_NOKIA_GATEWAY_ID' => null, - 'HTTP_X_ORANGE_ID' => null, - 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null, - 'HTTP_X_HUAWEI_USERID' => null, - // Reported by Windows Smartphones. - 'HTTP_UA_OS' => null, - // Reported by Verizon, Vodafone proxy system. - 'HTTP_X_MOBILE_GATEWAY' => null, - // Seend this on HTC Sensation. @ref: SensationXE_Beats_Z715e. - 'HTTP_X_ATT_DEVICEID' => null, - // Seen this on a HTC. - 'HTTP_UA_CPU' => array('matches' => array('ARM')), - ); - - /** - * List of mobile devices (phones). - * - * @var array - */ - protected static $phoneDevices = array( - 'iPhone' => '\biPhone.*(Mobile|PhoneGap)|\biPod', // |\biTunes - 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+', - 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m', - 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile', - // @todo: Is 'Dell Streak' a tablet or a phone? ;) - 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b', - 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925', - 'Samsung' => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E', - 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802)', - 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i', - 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile', - // @ref: http://www.micromaxinfo.com/mobiles/smartphones - // Added because the codes might conflict with Acer Tablets. - 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b', - 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex. - 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;) - // @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH) - // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android. - 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790', - // @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones. - 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250', - 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)', - // Added simvalley mobile just for fun. They have some interesting devices. - // @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html - 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b', - // @Tapatalk is a mobile app; @ref: http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039 - 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser' - ); - - /** - * List of tablet devices. - * - * @var array - */ - protected static $tabletDevices = array( - 'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic. - 'NexusTablet' => 'Android.*Nexus[\s]+(7|10)|^.*Android.*Nexus(?:(?!Mobile).)*$', - 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-I9205|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705C|SM-T535|SM-T331', // SCH-P709|SCH-P729|SM-T2558 - Samsung Mega - treat them like a regular phone. - // @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/ - 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE)\b', - // Only the Surface tablets with Windows RT are considered mobile. - // @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx - 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;', - // @ref: http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT - 'HPTablet' => 'HP Slate 7|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8', - // @note: watch out for PadFone, see #132 - 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|TX201LA', - 'BlackBerryTablet' => 'PlayBook|RIM Tablet', - 'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200', - 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617', - 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2', - // @ref: http://www.acer.ro/ac/ro/RO/content/drivers - // @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer) - // @ref: http://us.acer.com/ac/en/US/content/group/tablets - // @note: Can conflict with Micromax and Motorola phones codes. - 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-830)\b|W3-810|\bA3-A10\b', - // @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/ - // @ref: http://us.toshiba.com/tablets/tablet-finder - // @ref: http://www.toshiba.co.jp/regza/tablet/ - 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO', - // @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html - // @ref: http://www.lg.com/us/tablets - 'LGTablet' => '\bL-06C|LG-V900|LG-V500|LG-V909|LG-V500|LG-V510|LG-VK810\b', - 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b', - // Prestigio Tablets http://www.prestigio.com/support - 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD', - // @ref: http://support.lenovo.com/en_GB/downloads/default.page?# - 'LenovoTablet' => 'IdeaTab|ThinkPad([ ]+)?Tablet|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A1000|A2107|A2109|A1107|B6000|B8000|B8080-F)', - // @ref: http://www.yarvik.com/en/matrix/tablets/ - 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b', - 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB', - 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT', - // http://www.intenso.de/kategorie_en.php?kategorie=33 - // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate - 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab', - // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/ - 'IRUTablet' => 'M702pro', - 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b', - // @ref: http://www.e-boda.ro/tablete-pc.html - 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)', - // @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/ - 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)', - // @reference: http://wiki.archosfans.com/index.php?title=Main_Page - 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|ARCHOS 101G10|Archos 101 Neon', - // @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product - 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark', - // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER - // @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser - // @ref: http://www.sony.jp/support/tablet/ - 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551', - // @ref: db + http://www.cube-tablet.com/buy-products.html - 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT', - // @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001 - 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010', - // @ref: http://www.match.net.cn/products.asp - 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733', - // @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets) - // @ref: http://www.imp3.net/14/show.php?itemid=20454 - 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)', - // @ref: http://www.rock-chips.com/index.php?do=prod&pid=2 - 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A', - // @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/ - 'FlyTablet' => 'IQ310|Fly Vision', - // @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html - 'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)|Maxwell.*Lite|Maxwell.*Plus', - // @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290 - // @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets) - 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim', - // Nec or Medias Tab - 'NecTablet' => '\bN-06D|\bN-08D', - // Pantech Tablets: http://www.pantechusa.com/phones/ - 'PantechTablet' => 'Pantech.*P4100', - // Broncho Tablets: http://www.broncho.cn/ (hard to find) - 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)', - // @ref: http://versusuk.com/support.html - 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b', - // @ref: http://www.zync.in/index.php/our-products/tablet-phablets - 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900', - // @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/ - 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA', - // @ref: https://www.nabitablet.com/ - 'NabiTablet' => 'Android.*\bNabi', - 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build', - // French Danew Tablets http://www.danew.com/produits-tablette.php - 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b', - // Texet Tablets and Readers http://www.texet.ru/tablet/ - 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE', - // @note: Avoid detecting 'PLAYSTATION 3' as mobile. - 'PlaystationTablet' => 'Playstation.*(Portable|Vita)', - // @ref: http://www.trekstor.de/surftabs.html - 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A', - // @ref: http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets - 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b', - // @ref: http://www.advandigital.com/index.php?link=content-product&jns=JP001 - // @Note: because of the short codenames we have to include whitespaces to reduce the possible conflicts. - 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ', - // @ref: http://www.danytech.com/category/tablet-pc - 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1', - // @ref: http://www.galapad.net/product.html - 'GalapadTablet' => 'Android.*\bG1\b', - // @ref: http://www.micromaxinfo.com/tablet/funbook - 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b', - // http://www.karbonnmobiles.com/products_tablet.php - 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b', - // @ref: http://www.myallfine.com/Products.asp - 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide', - // @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr= - 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b', - // @ref: http://www.yonesnav.com/products/products.php - 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026', - // @ref: http://www.cjshowroom.com/eproducts.aspx?classcode=004001001 - // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html) - 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503', - // @ref: http://www.gloryunion.cn/products.asp - // @ref: http://www.allwinnertech.com/en/apply/mobile.html - // @ref: http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB) - // @todo: Softwiner tablets? - // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions. - 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G - // @ref: http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118 - 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10', - // @ref: http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/ - // @todo: add more tests. - 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)', - // @ref: http://hclmetablet.com/India/index.php - 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync', - // @ref: http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html - 'DPSTablet' => 'DPS Dream 9|DPS Dual 7', - // @ref: http://www.visture.com/index.asp - 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10', - // @ref: http://www.mijncresta.nl/tablet - 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989', - // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309 - 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b', - // Concorde tab - 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan', - // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/ - 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042', - // Modecom Tablets - http://www.modecom.eu/tablets/portal/ - 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003', - // Vonino Tablets - http://www.vonino.eu/tablets - 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b', - // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0 - 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1', - // Storex Tablets - http://storex.fr/espace_client/support.html - // @note: no need to add all the tablet codes since they are guided by the first regex. - 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab', - // Generic Vodafone tablets. - 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10', - // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb - // Aka: http://www.essentielb.fr/ - 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2', - // Ross & Moor - http://ross-moor.ru/ - 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711', - // i-mobile http://product.i-mobilephone.com/Mobile_Device - 'iMobileTablet' => 'i-mobile i-note', - // @ref: http://www.tolino.de/de/vergleichen/ - 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine', - // AudioSonic - a Kmart brand - // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72¤tPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1 - 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b', - // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/ - // @todo: add them gradually to avoid conflicts. - 'AMPETablet' => 'Android.* A78 ', - // Skk Mobile - http://skkmobile.com.ph/product_tablets.php - 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)', - // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1 - 'TecnoTablet' => 'TECNO P9', - // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3 - 'JXDTablet' => 'Android.*\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b', - // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/ - 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)', - // http://www.intracon.eu/tablet - 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10', - // http://www.xoro.de/produkte/ - // @note: Might be the same brand with 'Simply tablets' - 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151', - // http://www1.viewsonic.com/products/computing/tablets/ - 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a', - // http://www.odys.de/web/internet-tablet_en.html - 'OdysTablet' => 'LOOX|XENO10|ODYS Space', - // http://www.captiva-power.de/products.html#tablets-en - 'CaptivaTablet' => 'CAPTIVA PAD', - // IconBIT - http://www.iconbit.com/products/tablets/ - 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S', - // @ref: http://www.tesco.com/direct/hudl/ - 'Hudl' => 'Hudl HT7S3', - // @ref: http://www.telstra.com.au/home-phone/thub-2/ - 'TelstraTablet' => 'T-Hub2', - 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4', - ); - - /** - * List of mobile Operating Systems. - * - * @var array - */ - protected static $operatingSystems = array( - 'AndroidOS' => 'Android', - 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os', - 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino', - 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b', - // @reference: http://en.wikipedia.org/wiki/Windows_Mobile - 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;', - // @reference: http://en.wikipedia.org/wiki/Windows_Phone - // http://wifeng.cn/?r=blog&a=view&id=106 - // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx - 'WindowsPhoneOS' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7', - 'iOS' => '\biPhone.*Mobile|\biPod|\biPad', - // http://en.wikipedia.org/wiki/MeeGo - // @todo: research MeeGo in UAs - 'MeeGoOS' => 'MeeGo', - // http://en.wikipedia.org/wiki/Maemo - // @todo: research Maemo in UAs - 'MaemoOS' => 'Maemo', - 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135 - 'webOS' => 'webOS|hpwOS', - 'badaOS' => '\bBada\b', - 'BREWOS' => 'BREW', - ); - - /** - * List of mobile User Agents. - * - * @var array - */ - protected static $browsers = array( - // @reference: https://developers.google.com/chrome/mobile/docs/user-agent - 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?', - 'Dolfin' => '\bDolfin\b', - 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+', - 'Skyfire' => 'Skyfire', - 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+ - 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile', - 'Bolt' => 'bolt', - 'TeaShark' => 'teashark', - 'Blazer' => 'Blazer', - // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3 - 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile', - // @ref: http://en.wikipedia.org/wiki/Midori_(web_browser) - //'Midori' => 'midori', - 'Tizen' => 'Tizen', - 'UCBrowser' => 'UC.*Browser|UCWEB', - // @ref: https://github.com/serbanghita/Mobile-Detect/issues/7 - 'DiigoBrowser' => 'DiigoBrowser', - // http://www.puffinbrowser.com/index.php - 'Puffin' => 'Puffin', - // @ref: http://mercury-browser.com/index.html - 'Mercury' => '\bMercury\b', - // @reference: http://en.wikipedia.org/wiki/Minimo - // http://en.wikipedia.org/wiki/Vision_Mobile_Browser - 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger' - ); - - /** - * Utilities. - * - * @var array - */ - protected static $utilities = array( - // Experimental. When a mobile device wants to switch to 'Desktop Mode'. - // @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/ - // @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011 - 'DesktopMode' => 'WPDesktop', - 'TV' => 'SonyDTV|HbbTV', // experimental - 'WebKit' => '(webkit)[ /]([\w.]+)', - 'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit', - 'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2', - // @todo: Include JXD consoles. - 'Console' => '\b(Nintendo|Nintendo WiiU|PLAYSTATION|Xbox)\b', - 'Watch' => 'SM-V700', - ); - - /** - * All possible HTTP headers that represent the - * User-Agent string. - * - * @var array - */ - protected static $uaHttpHeaders = array( - // The default User-Agent string. - 'HTTP_USER_AGENT', - // Header can occur on devices using Opera Mini. - 'HTTP_X_OPERAMINI_PHONE_UA', - // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ - 'HTTP_X_DEVICE_USER_AGENT', - 'HTTP_X_ORIGINAL_USER_AGENT', - 'HTTP_X_SKYFIRE_PHONE', - 'HTTP_X_BOLT_PHONE_UA', - 'HTTP_DEVICE_STOCK_UA', - 'HTTP_X_UCBROWSER_DEVICE_UA' - ); - - /** - * The individual segments that could exist in a User-Agent string. VER refers to the regular - * expression defined in the constant self::VER. - * - * @var array - */ - protected static $properties = array( - - // Build - 'Mobile' => 'Mobile/[VER]', - 'Build' => 'Build/[VER]', - 'Version' => 'Version/[VER]', - 'VendorID' => 'VendorID/[VER]', - - // Devices - 'iPad' => 'iPad.*CPU[a-z ]+[VER]', - 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]', - 'iPod' => 'iPod.*CPU[a-z ]+[VER]', - //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'), - 'Kindle' => 'Kindle/[VER]', - - // Browser - 'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'), - 'Coast' => array('Coast/[VER]'), - 'Dolfin' => 'Dolfin/[VER]', - // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference - 'Firefox' => 'Firefox/[VER]', - 'Fennec' => 'Fennec/[VER]', - // @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx - 'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'), - // http://en.wikipedia.org/wiki/NetFront - 'NetFront' => 'NetFront/[VER]', - 'NokiaBrowser' => 'NokiaBrowser/[VER]', - 'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ), - 'Opera Mini' => 'Opera Mini/[VER]', - 'Opera Mobi' => 'Version/[VER]', - 'UC Browser' => 'UC Browser[VER]', - 'MQQBrowser' => 'MQQBrowser/[VER]', - 'MicroMessenger' => 'MicroMessenger/[VER]', - // @note: Safari 7534.48.3 is actually Version 5.1. - // @note: On BlackBerry the Version is overwriten by the OS. - 'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ), - 'Skyfire' => 'Skyfire/[VER]', - 'Tizen' => 'Tizen/[VER]', - 'Webkit' => 'webkit[ /][VER]', - - // Engine - 'Gecko' => 'Gecko/[VER]', - 'Trident' => 'Trident/[VER]', - 'Presto' => 'Presto/[VER]', - - // OS - 'iOS' => ' \bOS\b [VER] ', - 'Android' => 'Android [VER]', - 'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'), - 'BREW' => 'BREW [VER]', - 'Java' => 'Java/[VER]', - // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx - // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases - 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'), - 'Windows Phone' => 'Windows Phone [VER]', - 'Windows CE' => 'Windows CE/[VER]', - // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd - 'Windows NT' => 'Windows NT [VER]', - 'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'), - 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'), - ); - - /** - * Construct an instance of this class. - * - * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored. - * If left empty, will use the global _SERVER['HTTP_*'] vars instead. - * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT - * from the $headers array instead. - */ - public function __construct( - array $headers = null, - $userAgent = null - ){ - $this->setHttpHeaders($headers); - $this->setUserAgent($userAgent); - } - - /** - * Get the current script version. - * This is useful for the demo.php file, - * so people can check on what version they are testing - * for mobile devices. - * - * @return string The version number in semantic version format. - */ - public static function getScriptVersion() - { - return self::VERSION; - } - - /** - * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. - * - * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract - * the headers. The default null is left for backwards compatibilty. - */ - public function setHttpHeaders($httpHeaders = null) - { - //use global _SERVER if $httpHeaders aren't defined - if (!is_array($httpHeaders) || !count($httpHeaders)) { - $httpHeaders = $_SERVER; - } - - //clear existing headers - $this->httpHeaders = array(); - - //Only save HTTP headers. In PHP land, that means only _SERVER vars that - //start with HTTP_. - foreach ($httpHeaders as $key => $value) { - if (substr($key,0,5) == 'HTTP_') { - $this->httpHeaders[$key] = $value; - } - } - } - - /** - * Retrieves the HTTP headers. - * - * @return array - */ - public function getHttpHeaders() - { - return $this->httpHeaders; - } - - /** - * Retrieves a particular header. If it doesn't exist, no exception/error is caused. - * Simply null is returned. - * - * @param string $header The name of the header to retrieve. Can be HTTP compliant such as - * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the - * all-caps, HTTP_ prefixed, underscore seperated awesomeness. - * - * @return string|null The value of the header. - */ - public function getHttpHeader($header) - { - //are we using PHP-flavored headers? - if (strpos($header, '_') === false) { - $header = str_replace('-', '_', $header); - $header = strtoupper($header); - } - - //test the alternate, too - $altHeader = 'HTTP_' . $header; - - //Test both the regular and the HTTP_ prefix - if (isset($this->httpHeaders[$header])) { - return $this->httpHeaders[$header]; - } elseif (isset($this->httpHeaders[$altHeader])) { - return $this->httpHeaders[$altHeader]; - } - - return null; - } - - public function getMobileHeaders() - { - return self::$mobileHeaders; - } - - /** - * Get all possible HTTP headers that - * can contain the User-Agent string. - * - * @return array List of HTTP headers. - */ - public function getUaHttpHeaders() - { - return self::$uaHttpHeaders; - } - - /** - * Set the User-Agent to be used. - * - * @param string $userAgent The user agent string to set. - * - * @return string|null - */ - public function setUserAgent($userAgent = null) - { - if (!empty($userAgent)) { - return $this->userAgent = $userAgent; - } else { - - $this->userAgent = null; - - foreach($this->getUaHttpHeaders() as $altHeader){ - if(!empty($this->httpHeaders[$altHeader])){ // @todo: should use getHttpHeader(), but it would be slow. (Serban) - $this->userAgent .= $this->httpHeaders[$altHeader] . " "; - } - } - - return $this->userAgent = (!empty($this->userAgent) ? trim($this->userAgent) : null); - - } - } - - /** - * Retrieve the User-Agent. - * - * @return string|null The user agent if it's set. - */ - public function getUserAgent() - { - return $this->userAgent; - } - - /** - * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or - * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set. - * - * @deprecated since version 2.6.9 - * - * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default - * parameter is null which will default to self::DETECTION_TYPE_MOBILE. - */ - public function setDetectionType($type = null) - { - if ($type === null) { - $type = self::DETECTION_TYPE_MOBILE; - } - - if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) { - return; - } - - $this->detectionType = $type; - } - - /** - * Retrieve the list of known phone devices. - * - * @return array List of phone devices. - */ - public static function getPhoneDevices() - { - return self::$phoneDevices; - } - - /** - * Retrieve the list of known tablet devices. - * - * @return array List of tablet devices. - */ - public static function getTabletDevices() - { - return self::$tabletDevices; - } - - /** - * Alias for getBrowsers() method. - * - * @return array List of user agents. - */ - public static function getUserAgents() - { - return self::getBrowsers(); - } - - /** - * Retrieve the list of known browsers. Specifically, the user agents. - * - * @return array List of browsers / user agents. - */ - public static function getBrowsers() - { - return self::$browsers; - } - - /** - * Retrieve the list of known utilities. - * - * @return array List of utilities. - */ - public static function getUtilities() - { - return self::$utilities; - } - - /** - * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*(). - * - * @deprecated since version 2.6.9 - * - * @return array All the rules (but not extended). - */ - public static function getMobileDetectionRules() - { - static $rules; - - if (!$rules) { - $rules = array_merge( - self::$phoneDevices, - self::$tabletDevices, - self::$operatingSystems, - self::$browsers - ); - } - - return $rules; - - } - - /** - * Method gets the mobile detection rules + utilities. - * The reason this is separate is because utilities rules - * don't necessary imply mobile. This method is used inside - * the new $detect->is('stuff') method. - * - * @deprecated since version 2.6.9 - * - * @return array All the rules + extended. - */ - public function getMobileDetectionRulesExtended() - { - static $rules; - - if (!$rules) { - // Merge all rules together. - $rules = array_merge( - self::$phoneDevices, - self::$tabletDevices, - self::$operatingSystems, - self::$browsers, - self::$utilities - ); - } - - return $rules; - } - - /** - * Retrieve the current set of rules. - * - * @deprecated since version 2.6.9 - * - * @return array - */ - public function getRules() - { - if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) { - return self::getMobileDetectionRulesExtended(); - } else { - return self::getMobileDetectionRules(); - } - } - - /** - * Retrieve the list of mobile operating systems. - * - * @return array The list of mobile operating systems. - */ - public static function getOperatingSystems() - { - return self::$operatingSystems; - } - - /** - * Check the HTTP headers for signs of mobile. - * This is the fastest mobile check possible; it's used - * inside isMobile() method. - * - * @return bool - */ - public function checkHttpHeadersForMobile() - { - - foreach($this->getMobileHeaders() as $mobileHeader => $matchType){ - if( isset($this->httpHeaders[$mobileHeader]) ){ - if( is_array($matchType['matches']) ){ - foreach($matchType['matches'] as $_match){ - if( strpos($this->httpHeaders[$mobileHeader], $_match) !== false ){ - return true; - } - } - return false; - } else { - return true; - } - } - } - - return false; - - } - - /** - * Magic overloading method. - * - * @method boolean is[...]() - * @param string $name - * @param array $arguments - * @return mixed - * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' - */ - public function __call($name, $arguments) - { - //make sure the name starts with 'is', otherwise - if (substr($name, 0, 2) != 'is') { - throw new BadMethodCallException("No such method exists: $name"); - } - - $this->setDetectionType(self::DETECTION_TYPE_MOBILE); - - $key = substr($name, 2); - - return $this->matchUAAgainstKey($key); - } - - /** - * Find a detection rule that matches the current User-agent. - * - * @param null $userAgent deprecated - * @return boolean - */ - protected function matchDetectionRulesAgainstUA($userAgent = null) - { - // Begin general search. - foreach ($this->getRules() as $_regex) { - if (empty($_regex)) { - continue; - } - if ($this->match($_regex, $userAgent)) { - return true; - } - } - - return false; - } - - /** - * Search for a certain key in the rules array. - * If the key is found the try to match the corresponding - * regex agains the User-Agent. - * - * @param string $key - * @param null $userAgent deprecated - * @return mixed - */ - protected function matchUAAgainstKey($key, $userAgent = null) - { - // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc. - $key = strtolower($key); - - //change the keys to lower case - $_rules = array_change_key_case($this->getRules()); - - if (array_key_exists($key, $_rules)) { - if (empty($_rules[$key])) { - return null; - } - - return $this->match($_rules[$key], $userAgent); - } - - return false; - } - - /** - * Check if the device is mobile. - * Returns true if any type of mobile device detected, including special ones - * @param null $userAgent deprecated - * @param null $httpHeaders deprecated - * @return bool - */ - public function isMobile($userAgent = null, $httpHeaders = null) - { - - if ($httpHeaders) { - $this->setHttpHeaders($httpHeaders); - } - - if ($userAgent) { - $this->setUserAgent($userAgent); - } - - $this->setDetectionType(self::DETECTION_TYPE_MOBILE); - - if ($this->checkHttpHeadersForMobile()) { - return true; - } else { - return $this->matchDetectionRulesAgainstUA(); - } - - } - - /** - * Check if the device is a tablet. - * Return true if any type of tablet device is detected. - * - * @param string $userAgent deprecated - * @param array $httpHeaders deprecated - * @return bool - */ - public function isTablet($userAgent = null, $httpHeaders = null) - { - $this->setDetectionType(self::DETECTION_TYPE_MOBILE); - - foreach (self::$tabletDevices as $_regex) { - if ($this->match($_regex, $userAgent)) { - return true; - } - } - - return false; - } - - /** - * This method checks for a certain property in the - * userAgent. - * @todo: The httpHeaders part is not yet used. - * - * @param string $key - * @param string $userAgent deprecated - * @param string $httpHeaders deprecated - * @return bool|int|null - */ - public function is($key, $userAgent = null, $httpHeaders = null) - { - // Set the UA and HTTP headers only if needed (eg. batch mode). - if ($httpHeaders) { - $this->setHttpHeaders($httpHeaders); - } - - if ($userAgent) { - $this->setUserAgent($userAgent); - } - - $this->setDetectionType(self::DETECTION_TYPE_EXTENDED); - - return $this->matchUAAgainstKey($key); - } - - /** - * Some detection rules are relative (not standard), - * because of the diversity of devices, vendors and - * their conventions in representing the User-Agent or - * the HTTP headers. - * - * This method will be used to check custom regexes against - * the User-Agent string. - * - * @param $regex - * @param string $userAgent - * @return bool - * - * @todo: search in the HTTP headers too. - */ - public function match($regex, $userAgent = null) - { - // Escape the special character which is the delimiter. - $regex = str_replace('/', '\/', $regex); - - return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent)); - } - - /** - * Get the properties array. - * - * @return array - */ - public static function getProperties() - { - return self::$properties; - } - - /** - * Prepare the version number. - * - * @todo Remove the error supression from str_replace() call. - * - * @param string $ver The string version, like "2.6.21.2152"; - * - * @return float - */ - public function prepareVersionNo($ver) - { - $ver = str_replace(array('_', ' ', '/'), '.', $ver); - $arrVer = explode('.', $ver, 2); - - if (isset($arrVer[1])) { - $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions. - } - - return (float) implode('.', $arrVer); - } - - /** - * Check the version of the given property in the User-Agent. - * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) - * - * @param string $propertyName The name of the property. See self::getProperties() array - * keys for all possible properties. - * @param string $type Either self::VERSION_TYPE_STRING to get a string value or - * self::VERSION_TYPE_FLOAT indicating a float value. This parameter - * is optional and defaults to self::VERSION_TYPE_STRING. Passing an - * invalid parameter will default to the this type as well. - * - * @return string|float The version of the property we are trying to extract. - */ - public function version($propertyName, $type = self::VERSION_TYPE_STRING) - { - if (empty($propertyName)) { - return false; - } - - //set the $type to the default if we don't recognize the type - if ($type != self::VERSION_TYPE_STRING && $type != self::VERSION_TYPE_FLOAT) { - $type = self::VERSION_TYPE_STRING; - } - - $properties = self::getProperties(); - - // Check if the property exists in the properties array. - if (array_key_exists($propertyName, $properties)) { - - // Prepare the pattern to be matched. - // Make sure we always deal with an array (string is converted). - $properties[$propertyName] = (array) $properties[$propertyName]; - - foreach ($properties[$propertyName] as $propertyMatchString) { - - $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); - - // Escape the special character which is the delimiter. - $propertyPattern = str_replace('/', '\/', $propertyPattern); - - // Identify and extract the version. - preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match); - - if (!empty($match[1])) { - $version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1] ); - - return $version; - } - - } - - } - - return false; - } - - /** - * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants. - * - * @return string One of the self::MOBILE_GRADE_* constants. - */ - public function mobileGrade() - { - $isMobile = $this->isMobile(); - - if ( - // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1) - $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)>=4.3 || - $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)>=3.1 || - $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)>=3.1 || - - // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5) - // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM - // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices - // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7 - ( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) || - - // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800 - $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT)>=7.0 || - - // Blackberry 7 - Tested on BlackBerry Torch 9810 - // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670 - $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=6.0 || - // Blackberry Playbook (1.0-2.0) - Tested on PlayBook - $this->match('Playbook.*Tablet') || - - // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0) - ( $this->version('webOS', self::VERSION_TYPE_FLOAT)>=1.4 && $this->match('Palm|Pre|Pixi') ) || - // Palm WebOS 3.0 - Tested on HP TouchPad - $this->match('hp.*TouchPad') || - - // Firefox Mobile (12 Beta) - Tested on Android 2.3 device - ( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=12 ) || - - // Chrome for Android - Tested on Android 4.0, 4.1 device - ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=4.0 ) || - - // Skyfire 4.1 - Tested on Android 2.3 device - ( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT)>=4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) || - - // Opera Mobile 11.5-12: Tested on Android 2.3 - ( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>11 && $this->is('AndroidOS') ) || - - // Meego 1.2 - Tested on Nokia 950 and N9 - $this->is('MeeGoOS') || - - // Tizen (pre-release) - Tested on early hardware - $this->is('Tizen') || - - // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser - // @todo: more tests here! - $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT)>=2.0 || - - // UC Browser - Tested on Android 2.3 device - ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) || - - // Kindle 3 and Fire - Tested on the built-in WebKit browser for each - ( $this->match('Kindle Fire') || - $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT)>=3.0 ) || - - // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet - $this->is('AndroidOS') && $this->is('NookTablet') || - - // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7 - $this->version('Chrome', self::VERSION_TYPE_FLOAT)>=11 && !$isMobile || - - // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7 - $this->version('Safari', self::VERSION_TYPE_FLOAT)>=5.0 && !$isMobile || - - // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7 - $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=4.0 && !$isMobile || - - // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7 - $this->version('MSIE', self::VERSION_TYPE_FLOAT)>=7.0 && !$isMobile || - - // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7 - // @reference: http://my.opera.com/community/openweb/idopera/ - $this->version('Opera', self::VERSION_TYPE_FLOAT)>=10 && !$isMobile - - ){ - return self::MOBILE_GRADE_A; - } - - if ( - $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 || - $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)<3.1 || - $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)<3.1 || - - // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770 - $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 || - - //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3 - ( $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)>=5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)<=6.5 && - ($this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 || $this->is('iOS')) ) || - - // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1) - $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') || - - // @todo: report this (tested on Nokia N71) - $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>=11 && $this->is('SymbianOS') - ){ - return self::MOBILE_GRADE_B; - } - - if ( - // Blackberry 4.x - Tested on the Curve 8330 - $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<5.0 || - // Windows Mobile - Tested on the HTC Leo (WinMo 5.2) - $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT)<=5.2 - - ){ - return self::MOBILE_GRADE_C; - } - - //All older smartphone platforms and featurephones - Any device that doesn't support media queries - //will receive the basic, C grade experience. - return self::MOBILE_GRADE_C; - } -} diff --git a/data/module/Net/UserAgent/Mobile.php b/data/module/Net/UserAgent/Mobile.php deleted file mode 100644 index 2f5b227412..0000000000 --- a/data/module/Net/UserAgent/Mobile.php +++ /dev/null @@ -1,457 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @since File available since Release 0.1 - */ - -require_once dirname(__FILE__) . '/../../PEAR.php'; -require_once dirname(__FILE__) . '/Mobile/Error.php'; - -// {{{ GLOBALS - -/** - * globals for fallback on no match - * - * @global boolean $GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch'] - */ -$GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch'] = false; - -// }}} -// {{{ Net_UserAgent_Mobile - -/** - * HTTP mobile user agent string parser - * - * Net_UserAgent_Mobile parses HTTP_USER_AGENT strings of (mainly Japanese) mobile - * HTTP user agents. It'll be useful in page dispatching by user agents. - * This package was ported from Perl's HTTP::MobileAgent. - * See {@link http://search.cpan.org/search?mode=module&query=HTTP-MobileAgent} - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $agent = &Net_UserAgent_Mobile::factory($agent_string); - * // or $agent = &Net_UserAgent_Mobile::factory(); // to get from $_SERVER - * - * if ($agent->isDoCoMo()) { - * // or if ($agent->getName() == 'DoCoMo') - * // or if (strtolower(get_class($agent)) == 'http_mobileagent_docomo') - * // it's NTT DoCoMo i-mode - * // see what's available in Net_UserAgent_Mobile_DoCoMo - * } elseif ($agent->isSoftBank()) { - * // it's SoftBank - * // see what's available in Net_UserAgent_Mobile_SoftBank - * } elseif ($agent->isEZweb()) { - * // it's KDDI/EZWeb - * // see what's available in Net_UserAgent_Mobile_EZweb - * } else { - * // may be PC - * // $agent is Net_UserAgent_Mobile_NonMobile - * } - * - * $display = $agent->getDisplay(); // Net_UserAgent_Mobile_Display - * if ($display->isColor()) { - * ... - * } - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @since Class available since Release 0.1 - */ -class Net_UserAgent_Mobile -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - /**#@+ - * @access public - * @static - */ - - // }}} - // {{{ factory() - - /** - * create a new {@link Net_UserAgent_Mobile_Common} subclass instance - * - * parses HTTP headers and constructs {@link Net_UserAgent_Mobile_Common} - * subclass instance. - * If no argument is supplied, $_SERVER{'HTTP_*'} is used. - * - * @param string $userAgent User-Agent string - * @return Net_UserAgent_Mobile_Common a newly created or an existing - * Net_UserAgent_Mobile_Common object - * @throws Net_UserAgent_Mobile_Error - */ - function &factory($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - // parse User-Agent string - if (Net_UserAgent_Mobile::isDoCoMo($userAgent)) { - $driver = 'DoCoMo'; - } elseif (Net_UserAgent_Mobile::isEZweb($userAgent)) { - $driver = 'EZweb'; - } elseif (Net_UserAgent_Mobile::isSoftBank($userAgent)) { - $driver = 'SoftBank'; - } elseif (Net_UserAgent_Mobile::isWillcom($userAgent)) { - $driver = 'Willcom'; - } else { - $driver = 'NonMobile'; - } - - $class = "Net_UserAgent_Mobile_$driver"; - - if (!class_exists($class)) { - $file = dirname(__FILE__) . "/Mobile/{$driver}.php"; - if (!include_once $file) { - return PEAR::raiseError(null, - NET_USERAGENT_MOBILE_ERROR_NOT_FOUND, - null, null, - "Unable to include the $file file", - 'Net_UserAgent_Mobile_Error', true - ); - } - } - - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $instance = new $class($userAgent); - PEAR::staticPopErrorHandling(); - $error = &$instance->getError(); - if (Net_UserAgent_Mobile::isError($error)) { - if ($GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch'] - && $error->getCode() == NET_USERAGENT_MOBILE_ERROR_NOMATCH - ) { - $instance = &Net_UserAgent_Mobile::factory('Net_UserAgent_Mobile_Fallback_On_NoMatch'); - return $instance; - } - - return PEAR::raiseError($error); - } - - return $instance; - } - - // }}} - // {{{ singleton() - - /** - * creates a new {@link Net_UserAgent_Mobile_Common} subclass instance or returns - * a instance from existent ones - * - * @param string $userAgent User-Agent string - * @return Net_UserAgent_Mobile_Common a newly created or an existing - * Net_UserAgent_Mobile_Common object - * @throws Net_UserAgent_Mobile_Error - */ - function &singleton($userAgent = null) - { - static $instances; - - if (!isset($instances)) { - $instances = array(); - } - - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - if (!array_key_exists($userAgent, $instances)) { - $instances[$userAgent] = Net_UserAgent_Mobile::factory($userAgent); - } - - return $instances[$userAgent]; - } - - // }}} - // {{{ isError() - - /** - * tell whether a result code from a Net_UserAgent_Mobile method is an error - * - * @param integer $value result code - * @return boolean whether $value is an {@link Net_UserAgent_Mobile_Error} - */ - function isError($value) - { - return is_object($value) - && (strtolower(get_class($value)) == strtolower('Net_UserAgent_Mobile_Error') - || is_subclass_of($value, 'Net_UserAgent_Mobile_Error')); - } - - // }}} - // {{{ errorMessage() - - /** - * return a textual error message for a Net_UserAgent_Mobile error code - * - * @param integer $value error code - * @return string error message, or null if the error code was not recognized - */ - function errorMessage($value) - { - static $errorMessages; - if (!isset($errorMessages)) { - $errorMessages = array( - NET_USERAGENT_MOBILE_ERROR => 'unknown error', - NET_USERAGENT_MOBILE_ERROR_NOMATCH => 'no match', - NET_USERAGENT_MOBILE_ERROR_NOT_FOUND => 'not found', - NET_USERAGENT_MOBILE_OK => 'no error' - ); - } - - if (Net_UserAgent_Mobile::isError($value)) { - $value = $value->getCode(); - } - - return isset($errorMessages[$value]) ? - $errorMessages[$value] : - $errorMessages[NET_USERAGENT_MOBILE_ERROR]; - } - - // }}} - // {{{ isMobile() - - /** - * Checks whether or not the user agent is mobile by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isMobile($userAgent = null) - { - if (Net_UserAgent_Mobile::isDoCoMo($userAgent)) { - return true; - } elseif (Net_UserAgent_Mobile::isEZweb($userAgent)) { - return true; - } elseif (Net_UserAgent_Mobile::isSoftBank($userAgent)) { - return true; - } elseif (Net_UserAgent_Mobile::isWillcom($userAgent)) { - return true; - } - - return false; - } - - // }}} - // {{{ isDoCoMo() - - /** - * Checks whether or not the user agent is DoCoMo by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isDoCoMo($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - if (preg_match('!^DoCoMo!', $userAgent)) { - return true; - } - - return false; - } - - // }}} - // {{{ isEZweb() - - /** - * Checks whether or not the user agent is EZweb by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isEZweb($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - if (preg_match('!^KDDI-!', $userAgent)) { - return true; - } elseif (preg_match('!^UP\.Browser!', $userAgent)) { - return true; - } - - return false; - } - - // }}} - // {{{ isSoftBank() - - /** - * Checks whether or not the user agent is SoftBank by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isSoftBank($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - if (preg_match('!^SoftBank!', $userAgent)) { - return true; - } elseif (preg_match('!^Semulator!', $userAgent)) { - return true; - } elseif (preg_match('!^Vodafone!', $userAgent)) { - return true; - } elseif (preg_match('!^Vemulator!', $userAgent)) { - return true; - } elseif (preg_match('!^MOT-!', $userAgent)) { - return true; - } elseif (preg_match('!^MOTEMULATOR!', $userAgent)) { - return true; - } elseif (preg_match('!^J-PHONE!', $userAgent)) { - return true; - } elseif (preg_match('!^J-EMULATOR!', $userAgent)) { - return true; - } - - return false; - } - - // }}} - // {{{ isWillcom() - - /** - * Checks whether or not the user agent is Willcom by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isWillcom($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - if (preg_match('!^Mozilla/3\.0\((?:DDIPOCKET|WILLCOM);!', $userAgent)) { - return true; - } - - return false; - } - - // }}} - // {{{ isSmartphone() - - /** - * Checks whether or not the user agent is Smartphone by a given user agent string. - * - * @param string $userAgent - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isSmartphone($userAgent = null) - { - if (is_null($userAgent)) { - $userAgent = @$_SERVER['HTTP_USER_AGENT']; - } - - $useragents = array( - 'iPhone', // Apple iPhone - 'iPod', // Apple iPod touch - 'Android', // 1.5+ Android - 'dream', // Pre 1.5 Android - 'CUPCAKE', // 1.5+ Android - 'blackberry9500', // Storm - 'blackberry9530', // Storm - 'blackberry9520', // Storm v2 - 'blackberry9550', // Storm v2 - 'blackberry9800', // Torch - 'webOS', // Palm Pre Experimental - 'incognito', // Other iPhone browser - 'webmate', // Other iPhone browser - 'Windows Phone OS' // Windows Phone - ); - - $pattern = implode("|", $useragents); - return preg_match('/'.$pattern.'/', $userAgent); - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/Common.php b/data/module/Net/UserAgent/Mobile/Common.php deleted file mode 100644 index dc8c8ee261..0000000000 --- a/data/module/Net/UserAgent/Mobile/Common.php +++ /dev/null @@ -1,528 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @since File available since Release 0.1 - */ - -require_once dirname(__FILE__) . '/Error.php'; -require_once dirname(__FILE__) . '/../../../PEAR.php'; - -// {{{ Net_UserAgent_Mobile_Common - -/** - * Base class that is extended by each user agents implementor - * - * Net_UserAgent_Mobile_Common is a class for mobile user agent - * abstraction layer on Net_UserAgent_Mobile. - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @since Class available since Release 0.1 - */ -class Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /** - * User-Agent name like 'DoCoMo' - * @var string - */ - var $name; - - /** - * User-Agent version number like '1.0' - * @var string - */ - var $version; - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * {@link Net_UserAgent_Mobile_Display} object - * @var object {@link Net_UserAgent_Mobile_Display} - */ - var $_display; - - /** - * {@link Net_UserAgent_Mobile_Error} object for error handling in the constructor - * @var object - **/ - var $_error; - - /** - * The User-Agent string. - * @var string - * @since Property available since Release 0.31.0 - **/ - var $_userAgent; - - /** - * The model name of the user agent. - * - * @var string - * @since Property available since Release 0.31.0 - */ - var $_model; - - /** - * The raw model name of the user agent. - * - * @var string - * @since Property available since Release 0.31.0 - */ - var $_rawModel; - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ constructor - - /** - * constructor - * - * @param string $userAgent User-Agent string - */ - function Net_UserAgent_Mobile_Common($userAgent) - { - $this->_userAgent = $userAgent; - - $result = $this->parse($userAgent); - if (PEAR::isError($result)) { - $this->_error = &$result; - } - } - - // }}} - // {{{ getError - - /** - * Gets a Net_UserAgent_Mobile_Error object. - * - * @param object {@link Net_UserAgent_Mobile_Error} object when setting an error - * @return Net_UserAgent_Mobile_Error - * @since Method available since Release 1.0.0RC2 - */ - function &getError() - { - if (is_null($this->_error)) { - $return = null; - return $return; - } - - return $this->_error; - } - - // }}} - // {{{ getUserAgent() - - /** - * returns User-Agent string - * - * @return string - */ - function getUserAgent() - { - return $this->_userAgent; - } - - // }}} - // {{{ getHeader() - - /** - * returns a specified HTTP header - * - * @param string $header - * @return string - */ - function getHeader($header) - { - return @$_SERVER[ 'HTTP_' . str_replace('-', '_', $header) ]; - } - - // }}} - // {{{ getName() - - /** - * returns User-Agent name like 'DoCoMo' - * - * @return string - */ - function getName() - { - return $this->name; - } - - // }}} - // {{{ getDisplay() - - /** - * returns {@link Net_UserAgent_Mobile_Disply} object - * - * @return Net_UserAgent_Mobile_Display - */ - function getDisplay() - { - if (is_null($this->_display)) { - $this->_display = $this->makeDisplay(); - } - - return $this->_display; - } - - // }}} - // {{{ getVersion() - - /** - * returns User-Agent version number like '1.0' - * - * @return string - */ - function getVersion() - { - return $this->version; - } - - // }}} - // {{{ noMatch() - - /** - * generates a warning message for new variants - * - * @throws Net_UserAgent_Mobile_Error - */ - function noMatch() - { - return PEAR::raiseError($this->getUserAgent() . ': might be new variants. Please contact the author of Net_UserAgent_Mobile!', - NET_USERAGENT_MOBILE_ERROR_NOMATCH, - null, - null, - null, - 'Net_UserAgent_Mobile_Error' - ); - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - * @abstract - */ - function parse($userAgent) {} - - // }}} - // {{{ makeDisplay() - - /** - * create a new Net_UserAgent_Mobile_Display class instance (should be - * implemented in subclasses) - * - * @return Net_UserAgent_Mobile_Display - * @abstract - */ - function makeDisplay() {} - - // }}} - // {{{ isDoCoMo() - - /** - * returns true if the agent is DoCoMo - * - * @return boolean - */ - function isDoCoMo() - { - return false; - } - - // }}} - // {{{ isJPhone() - - /** - * returns true if the agent is J-PHONE - * - * @return boolean - */ - function isJPhone() - { - return false; - } - - // }}} - // {{{ isVodafone() - - /** - * returns true if the agent is Vodafone - * - * @return boolean - */ - function isVodafone() - { - return false; - } - - // }}} - // {{{ isEZweb() - - /** - * returns true if the agent is EZweb - * - * @return boolean - */ - function isEZweb() - { - return false; - } - - // }}} - // {{{ isAirHPhone() - - /** - * returns true if the agent is AirH"PHONE - * - * @return boolean - */ - function isAirHPhone() - { - return false; - } - - // }}} - // {{{ isNonMobile() - - /** - * returns true if the agent is NonMobile - * - * @return boolean - */ - function isNonMobile() - { - return false; - } - - // }}} - // {{{ isTUKa() - - /** - * returns true if the agent is TU-Ka - * - * @return boolean - */ - function isTUKa() - { - return false; - } - - // }}} - // {{{ isWAP1() - - /** - * returns true if the agent can speak WAP1 protocol - * - * @return boolean - */ - function isWAP1() - { - return $this->isEZweb() && !$this->isWAP2(); - } - - // }}} - // {{{ isWAP2() - - /** - * returns true if the agent can speak WAP2 protocol - * - * @return boolean - */ - function isWAP2() - { - return $this->isEZweb() && $this->isXHTMLCompliant(); - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @abstract - */ - function getCarrierShortName() - { - die(); - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @abstract - */ - function getCarrierLongName() - { - die(); - } - - // }}} - // {{{ isSoftBank() - - /** - * Returns whether the agent is SoftBank or not. - * - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isSoftBank() - { - return false; - } - - // }}} - // {{{ isWillcom() - - /** - * Returns whether the agent is Willcom or not. - * - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isWillcom() - { - return false; - } - - // }}} - // {{{ isSmartphone() - - /** - * Returns whether the agent is Smartphone or not. - * - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isSmartphone() - { - return false; - } - - - // }}} - // {{{ getModel() - - /** - * Returns the model name of the user agent. - * - * @return string - * @since Method available since Release 0.31.0 - */ - function getModel() - { - if (is_null($this->_model)) { - return $this->_rawModel; - } else { - return $this->_model; - } - } - - // }}} - // {{{ getRawModel() - - /** - * Returns the raw model name of the user agent. - * - * @return string - * @since Method available since Release 0.31.0 - */ - function getRawModel() - { - return $this->_rawModel; - } - - // }}} - // {{{ getUID() - - /** - * Gets the UID of a subscriber. - * - * @return string - * @since Method available since Release 1.0.0RC1 - */ - function getUID() {} - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/Display.php b/data/module/Net/UserAgent/Mobile/Display.php deleted file mode 100644 index 41c03b0a7b..0000000000 --- a/data/module/Net/UserAgent/Mobile/Display.php +++ /dev/null @@ -1,285 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @since File available since Release 0.1 - */ - -// {{{ Net_UserAgent_Mobile_Display - -/** - * Display information for Net_UserAgent_Mobile - * - * Net_UserAgent_Mobile_Display is a class for display information on - * {@link Net_UserAgent_Mobile}. Handy for image resizing or dispatching. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $agent = &Net_UserAgent_Mobile::factory(); - * $display = $agent->getDisplay(); - * - * $width = $display->getWidth(); - * $height = $display->getHeight(); - * list($width, $height) = $display->getSize(); - * - * if ($display->isColor()) { - * $depth = $display->getDepth(); - * } - * - * // only available in DoCoMo 505i - * $width_bytes = $display->getWidthBytes(); - * $height_bytes = $display->getHeightBytes(); - * - * - * USING EXTERNAL MAP FILE: - * If the environment variable DOCOMO_MAP exists, the specified XML data will be used - * for DoCoMo display information. - * - * ex) Please add the following code. - * $_SERVER['DOCOMO_MAP'] = '/path/to/DoCoMoMap.xml'; - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @since Class available since Release 0.1 - */ -class Net_UserAgent_Mobile_Display -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * width of the display - * @var integer - */ - var $_width; - - /** - * height of the display - * @var integer - */ - var $_height; - - /** - * depth of the display - * @var integer - */ - var $_depth; - - /** - * color capability of the display - * @var boolean - */ - var $_color; - - /** - * width (bytes) of the display - * @var integer - */ - var $_widthBytes; - - /** - * height (bytes) of the display - * @var integer - */ - var $_heightBytes; - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ constructor - - /** - * constructor - * - * @param array $data display infomation - */ - function Net_UserAgent_Mobile_Display($data) - { - $this->_width = (integer)@$data['width']; - $this->_height = (integer)@$data['height']; - $this->_depth = (integer)@$data['depth']; - $this->_color = (boolean)@$data['color']; - - $this->_widthBytes = (integer)@$data['width_bytes']; - $this->_heightBytes = (integer)@$data['height_bytes']; - } - - // }}} - // {{{ calcSize() - - /** - * returns width * height of the display - * - * @return integer - */ - function calcSize() - { - return $this->_width * $this->_height; - } - - // }}} - // {{{ getSize() - - /** - * returns width with height of the display - * - * @return array - */ - function getSize() - { - return array($this->_width, $this->_height); - } - - // }}} - // {{{ getWidth() - - /** - * returns width of the display - * - * @return integer - */ - function getWidth() - { - return $this->_width; - } - - // }}} - // {{{ getHeight() - - /** - * returns height of the display - * - * @return integer - */ - function getHeight() - { - return $this->_height; - } - - // }}} - // {{{ getDepth() - - /** - * returns depth of the display - * - * @return integer - */ - function getDepth() - { - return $this->_depth; - } - - // }}} - // {{{ isColor() - - /** - * returns true if the display has color capability - * - * @return boolean - */ - function isColor() - { - return $this->_color; - } - - // }}} - // {{{ getWidthBytes() - - /** - * returns width (bytes) of the display - * - * @return integer - */ - function getWidthBytes() - { - return $this->_widthBytes; - } - - // }}} - // {{{ getHeightBytes() - - /** - * returns height (bytes) of the display - * - * @return integer - */ - function getHeightBytes() - { - return $this->_heightBytes; - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/DoCoMo.php b/data/module/Net/UserAgent/Mobile/DoCoMo.php deleted file mode 100644 index ada57a5f36..0000000000 --- a/data/module/Net/UserAgent/Mobile/DoCoMo.php +++ /dev/null @@ -1,988 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://www.nttdocomo.co.jp/service/imode/make/content/spec/useragent/index.html - * @link http://www.nttdocomo.co.jp/service/imode/make/content/browser/browser2/useragent/index.html - * @since File available since Release 0.1 - */ - -require_once dirname(__FILE__) . '/Common.php'; -require_once dirname(__FILE__) . '/Display.php'; -require_once dirname(__FILE__) . '/../Mobile.php'; - -// {{{ Net_UserAgent_Mobile_DoCoMo - -/** - * NTT DoCoMo implementation - * - * Net_UserAgent_Mobile_DoCoMo is a subclass of {@link Net_UserAgent_Mobile_Common}, - * which implements NTT docomo i-mode user agents. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $_SERVER['HTTP_USER_AGENT'] = 'DoCoMo/1.0/P502i/c10'; - * $agent = &Net_UserAgent_Mobile::factory(); - * - * printf("Name: %s\n", $agent->getName()); // 'DoCoMo' - * printf("Version: %s\n", $agent->getVersion()); // 1.0 - * printf("HTML version: %s\n", $agent->getHTMLVersion()); // 2.0 - * printf("Model: %s\n", $agent->getModel()); // 'P502i' - * printf("Cache: %dk\n", $agent->getCacheSize()); // 10 - * if ($agent->isFOMA()) { - * print "FOMA\n"; // false - * } - * printf("Vendor: %s\n", $agent->getVendor()); // 'P' - * printf("Series: %s\n", $agent->getSeries()); // '502i' - * - * // only available with
- * // e.g.) 'DoCoMo/1.0/P503i/c10/serNMABH200331'; - * printf("Serial: %s\n", $agent->getSerialNumber()); // 'NMABH200331' - * - * // e.g.) 'DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789)'; - * printf("Serial: %s\n", $agent->getSerialNumber()); // '0123456789abcde' - * printf("Card ID: %s\n", $agent->getCardID()); // '01234567890123456789' - * - * // e.g.) 'DoCoMo/1.0/P502i (Google CHTML Proxy/1.0)' - * printf("Comment: %s\n", $agent->getComment()); // 'Google CHTML Proxy/1.0' - * - * // e.g.) 'DoCoMo/1.0/D505i/c20/TB/W20H10' - * printf("Status: %s\n", $agent->getStatus()); // 'TB' - * - * // only available in eggy/M-stage - * // e.g.) 'DoCoMo/1.0/eggy/c300/s32/kPHS-K' - * printf("Bandwidth: %dkbps\n", $agent->getBandwidth()); // 32 - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @link http://www.nttdocomo.co.jp/service/imode/make/content/spec/useragent/index.html - * @link http://www.nttdocomo.co.jp/service/imode/make/content/browser/browser2/useragent/index.html - * @since Class available since Release 0.1 - */ -class Net_UserAgent_Mobile_DoCoMo extends Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * status of the cache (TC, TB, TD, TJ) - * @var string - */ - var $_status; - - /** - * bandwidth like 32 as kilobytes unit - * @var integer - */ - var $_bandwidth; - - /** - * hardware unique serial number - * @var string - */ - var $_serialNumber; - - /** - * whether it's FOMA or not - * @var boolean - */ - var $_isFOMA = false; - - /** - * FOMA Card ID (20 digit alphanumeric) - * @var string - */ - var $_cardID; - - /** - * comment on user agent string like 'Google Proxy' - * @var string - */ - var $_comment; - - /** - * cache size as killobytes unit - * @var integer - */ - var $_cacheSize; - - /** - * width and height of the display - * @var string - */ - var $_displayBytes; - - /** - * The model names which have GPS capability. - * - * @var array - * @since Property available since Release 1.0.0RC1 - */ - var $_gpsModels = array('F884i', - 'F801i', - 'F905iBiz', - 'SO905iCS', - 'N905iBiz', - 'N905imyu', - 'SO905i', - 'F905i', - 'P905i', - 'N905i', - 'D905i', - 'SH905i', - 'P904i', - 'D904i', - 'F904i', - 'N904i', - 'SH904i', - 'F883iESS', - 'F883iES', - 'F903iBSC', - 'SO903i', - 'F903i', - 'D903i', - 'N903i', - 'P903i', - 'SH903i', - 'SA800i', - 'SA702i', - 'SA700iS', - 'F505iGPS', - 'F661i', - 'F884iES', - 'N906iL', - 'P906i', - 'SO906i', - 'SH906i', - 'N906imyu', - 'F906i', - 'N906i', - 'F01A', - 'F03A', - 'F06A', - 'F05A', - 'P01A', - 'P02A', - 'SH01A', - 'SH02A', - 'SH03A', - 'SH04A', - 'N01A', - 'N02A', - 'P07A3', - 'N06A3', - 'N08A3', - 'P08A3', - 'P09A3', - 'N09A3', - 'F09A3', - 'SH05A3', - 'SH06A3', - 'SH07A3' - ); - - /** - * The HTML versions which maps models to HTML versions. - * - * @var array - * @since Property available since Release 1.0.0RC1 - */ - var $_htmlVersions = array( - 'D501i' => '1.0', - 'F501i' => '1.0', - 'N501i' => '1.0', - 'P501i' => '1.0', - 'D502i' => '2.0', - 'F502i' => '2.0', - 'N502i' => '2.0', - 'P502i' => '2.0', - 'NM502i' => '2.0', - 'SO502i' => '2.0', - 'F502it' => '2.0', - 'N502it' => '2.0', - 'SO502iWM' => '2.0', - 'SH821i' => '2.0', - 'N821i' => '2.0', - 'P821i' => '2.0', - 'D209i' => '2.0', - 'ER209i' => '2.0', - 'F209i' => '2.0', - 'KO209i' => '2.0', - 'N209i' => '2.0', - 'P209i' => '2.0', - 'P209iS' => '2.0', - 'R209i' => '2.0', - 'P651ps' => '2.0', - 'R691i' => '2.0', - 'F210i' => '2.0', - 'N210i' => '2.0', - 'P210i' => '2.0', - 'KO210i' => '2.0', - 'F671i' => '2.0', - 'D210i' => '3.0', - 'SO210i' => '3.0', - 'F503i' => '3.0', - 'F503iS' => '3.0', - 'P503i' => '3.0', - 'P503iS' => '3.0', - 'N503i' => '3.0', - 'N503iS' => '3.0', - 'SO503i' => '3.0', - 'SO503iS' => '3.0', - 'D503i' => '3.0', - 'D503iS' => '3.0', - 'F211i' => '3.0', - 'D211i' => '3.0', - 'N211i' => '3.0', - 'N211iS' => '3.0', - 'P211i' => '3.0', - 'P211iS' => '3.0', - 'SO211i' => '3.0', - 'R211i' => '3.0', - 'SH251i' => '3.0', - 'SH251iS' => '3.0', - 'R692i' => '3.0', - 'N2001' => '3.0', - 'N2002' => '3.0', - 'P2002' => '3.0', - 'D2101V' => '3.0', - 'P2101V' => '3.0', - 'SH2101V' => '3.0', - 'T2101V' => '3.0', - 'D504i' => '4.0', - 'F504i' => '4.0', - 'F504iS' => '4.0', - 'N504i' => '4.0', - 'N504iS' => '4.0', - 'SO504i' => '4.0', - 'P504i' => '4.0', - 'P504iS' => '4.0', - 'D251i' => '4.0', - 'D251iS' => '4.0', - 'F251i' => '4.0', - 'N251i' => '4.0', - 'N251iS' => '4.0', - 'P251iS' => '4.0', - 'F671iS' => '4.0', - 'F212i' => '4.0', - 'SO212i' => '4.0', - 'F661i' => '4.0', - 'F672i' => '4.0', - 'SO213i' => '4.0', - 'SO213iS' => '4.0', - 'SO213iWR' => '4.0', - 'F2051' => '4.0', - 'N2051' => '4.0', - 'P2102V' => '4.0', - 'F2102V' => '4.0', - 'N2102V' => '4.0', - 'N2701' => '4.0', - 'NM850iG' => '4.0', - 'NM705i' => '4.0', - 'NM706i' => '4.0', - 'D505i' => '5.0', - 'SO505i' => '5.0', - 'SH505i' => '5.0', - 'N505i' => '5.0', - 'F505i' => '5.0', - 'P505i' => '5.0', - 'D505iS' => '5.0', - 'P505iS' => '5.0', - 'N505iS' => '5.0', - 'SO505iS' => '5.0', - 'SH505iS' => '5.0', - 'F505iGPS' => '5.0', - 'D252i' => '5.0', - 'SH252i' => '5.0', - 'P252i' => '5.0', - 'N252i' => '5.0', - 'P252iS' => '5.0', - 'D506i' => '5.0', - 'F506i' => '5.0', - 'N506i' => '5.0', - 'P506iC' => '5.0', - 'SH506iC' => '5.0', - 'SO506iC' => '5.0', - 'N506iS' => '5.0', - 'SO506i' => '5.0', - 'SO506iS' => '5.0', - 'N506iS2' => '5.0', - 'D253i' => '5.0', - 'N253i' => '5.0', - 'P253i' => '5.0', - 'D253iWM' => '5.0', - 'P253iS' => '5.0', - 'P213i' => '5.0', - 'F900i' => '5.0', - 'N900i' => '5.0', - 'P900i' => '5.0', - 'SH900i' => '5.0', - 'F900iT' => '5.0', - 'P900iV' => '5.0', - 'N900iS' => '5.0', - 'D900i' => '5.0', - 'F900iC' => '5.0', - 'N900iL' => '5.0', - 'N900iG' => '5.0', - 'F880iES' => '5.0', - 'SH901iC' => '5.0', - 'F901iC' => '5.0', - 'N901iC' => '5.0', - 'D901i' => '5.0', - 'P901i' => '5.0', - 'SH901iS' => '5.0', - 'F901iS' => '5.0', - 'D901iS' => '5.0', - 'P901iS' => '5.0', - 'N901iS' => '5.0', - 'P901iTV' => '5.0', - 'F700i' => '5.0', - 'SH700i' => '5.0', - 'N700i' => '5.0', - 'P700i' => '5.0', - 'F700iS' => '5.0', - 'SH700iS' => '5.0', - 'SA700iS' => '5.0', - 'SH851i' => '5.0', - 'P851i' => '5.0', - 'F881iES' => '5.0', - 'D701i' => '5.0', - 'N701i' => '5.0', - 'P701iD' => '5.0', - 'D701iWM' => '5.0', - 'N701iECO' => '5.0', - 'SA800i' => '5.0', - 'L600i' => '5.0', - 'N600i' => '5.0', - 'L601i' => '5.0', - 'M702iS' => '5.0', - 'M702iG' => '5.0', - 'L602i' => '5.0', - 'F902i' => '6.0', - 'D902i' => '6.0', - 'N902i' => '6.0', - 'P902i' => '6.0', - 'SH902i' => '6.0', - 'SO902i' => '6.0', - 'SH902iS' => '6.0', - 'P902iS' => '6.0', - 'N902iS' => '6.0', - 'D902iS' => '6.0', - 'F902iS' => '6.0', - 'SO902iWP+' => '6.0', - 'SH902iSL' => '6.0', - 'N902iX' => '6.0', - 'N902iL' => '6.0', - 'P702i' => '6.0', - 'N702iD' => '6.0', - 'F702iD' => '6.0', - 'SH702iD' => '6.0', - 'D702i' => '6.0', - 'SO702i' => '6.0', - 'D702iBCL' => '6.0', - 'SA702i' => '6.0', - 'SH702iS' => '6.0', - 'N702iS' => '6.0', - 'P702iD' => '6.0', - 'D702iF' => '6.0', - 'D851iWM' => '6.0', - 'F882iES' => '6.0', - 'N601i' => '6.0', - 'D800iDS' => '6.0', - 'P703imyu' => '6.0', - 'F883i' => '6.0', - 'F883iS' => '6.0', - 'P704imyu' => '6.0', - 'L704i' => '6.0', - 'L705i' => '6.0', - 'L705iX' => '6.0', - 'L852i' => '6.0', - 'L706ie' => '6.0', - 'L01A' => '6.0', - 'L03A' => '6.0', - 'SH903i' => '7.0', - 'P903i' => '7.0', - 'N903i' => '7.0', - 'D903i' => '7.0', - 'F903i' => '7.0', - 'SO903i' => '7.0', - 'D903iTV' => '7.0', - 'F903iX' => '7.0', - 'P903iTV' => '7.0', - 'SH903iTV' => '7.0', - 'F903iBSC' => '7.0', - 'P903iX' => '7.0', - 'SO903iTV' => '7.0', - 'N703iD' => '7.0', - 'F703i' => '7.0', - 'P703i' => '7.0', - 'D703i' => '7.0', - 'SH703i' => '7.0', - 'N703imyu' => '7.0', - 'SO703i' => '7.0', - 'SH904i' => '7.0', - 'N904i' => '7.0', - 'F904i' => '7.0', - 'D904i' => '7.0', - 'P904i' => '7.0', - 'SO704i' => '7.0', - 'F704i' => '7.0', - 'N704imyu' => '7.0', - 'SH704i' => '7.0', - 'D704i' => '7.0', - 'P704i' => '7.0', - 'F883iES' => '7.0', - 'F883iESS' => '7.0', - 'F801i' => '7.0', - 'F705i' => '7.0', - 'D705i' => '7.0', - 'D705imyu' => '7.0', - 'SH705i' => '7.0', - 'SH705i2' => '7.0', - 'SH706ie' => '7.0', - 'F05A' => '7.0', - 'SH905i' => '7.1', - 'D905i' => '7.1', - 'N905i' => '7.1', - 'P905i' => '7.1', - 'F905i' => '7.1', - 'SO905i' => '7.1', - 'N905imyu' => '7.1', - 'N905iBiz' => '7.1', - 'SH905iTV' => '7.1', - 'SO905iCS' => '7.1', - 'F905iBiz' => '7.1', - 'P905iTV' => '7.1', - 'P705i' => '7.1', - 'N705i' => '7.1', - 'N705imyu' => '7.1', - 'P705imyu' => '7.1', - 'SO705i' => '7.1', - 'P705iCL' => '7.1', - 'F884i' => '7.1', - 'F884iES' => '7.1', - 'N906iL' => '7.1', - 'N706i' => '7.1', - 'SO706i' => '7.1', - 'P706imyu' => '7.1', - 'N706ie' => '7.1', - 'N706i2' => '7.1', - 'N03A' => '7.1', - 'N05A' => '7.1', - 'F07A' => '7.1', - 'P906i' => '7.2', - 'SO906i' => '7.2', - 'SH906i' => '7.2', - 'N906imyu' => '7.2', - 'F906i' => '7.2', - 'N906i' => '7.2', - 'SH906iTV' => '7.2', - 'F706i' => '7.2', - 'SH706i' => '7.2', - 'P706ie' => '7.2', - 'SH706iw' => '7.2', - 'F01A' => '7.2', - 'F02A' => '7.2', - 'F03A' => '7.2', - 'F04A' => '7.2', - 'F06A' => '7.2', - 'P01A' => '7.2', - 'P02A' => '7.2', - 'P03A' => '7.2', - 'P04A' => '7.2', - 'P05A' => '7.2', - 'P06A' => '7.2', - 'SH01A' => '7.2', - 'SH02A' => '7.2', - 'SH03A' => '7.2', - 'SH04A' => '7.2', - 'N01A' => '7.2', - 'N02A' => '7.2', - 'N04A' => '7.2', - 'P10A' => '7.2', - ); - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ isDoCoMo() - - /** - * returns true - * - * @return boolean - */ - function isDoCoMo() - { - return true; - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - * @throws Net_UserAgent_Mobile_Error - */ - function parse($userAgent) - { - @list($main, $foma_or_comment) = explode(' ', $userAgent, 2); - - if ($foma_or_comment - && preg_match('/^\((.*)\)$/', $foma_or_comment, $matches) - ) { - - // DoCoMo/1.0/P209is (Google CHTML Proxy/1.0) - $this->_comment = $matches[1]; - $result = $this->_parseMain($main); - } elseif ($foma_or_comment) { - - // DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789) - $this->_isFOMA = true; - @list($this->name, $this->version) = explode('/', $main); - $result = $this->_parseFOMA($foma_or_comment); - } else { - - // DoCoMo/1.0/R692i/c10 - $result = $this->_parseMain($main); - } - - if (Net_UserAgent_Mobile::isError($result)) { - return $result; - } - } - - // }}} - // {{{ makeDisplay() - - /** - * create a new {@link Net_UserAgent_Mobile_Display} class instance - * - * @return Net_UserAgent_Mobile_Display - */ - function makeDisplay() - { - include_once dirname(__FILE__) . '/DoCoMo/ScreenInfo.php'; - - $screenInfo = &Net_UserAgent_Mobile_DoCoMo_ScreenInfo::singleton(); - $display = $screenInfo->get($this->getModel()); - if (!is_null($this->_displayBytes)) { - @list($widthBytes, $heightBytes) = explode('*', $this->_displayBytes); - $display['width_bytes'] = $widthBytes; - $display['height_bytes'] = $heightBytes; - } - - return new Net_UserAgent_Mobile_Display($display); - } - - // }}} - // {{{ getHTMLVersion() - - /** - * Gets the HTML version like '3.0'. Returns null if unknown. - * - * @return string - */ - function getHTMLVersion() - { - return @$this->_htmlVersions[ $this->getModel() ]; - } - - // }}} - // {{{ getCacheSize() - - /** - * returns cache size as kilobytes unit. returns 5 if unknown. - * - * @return integer - */ - function getCacheSize() - { - if ($this->_cacheSize) { - return $this->_cacheSize; - } - - return 5; - } - - // }}} - // {{{ getSeries() - - /** - * returns series name like '502i'. returns null if unknown. - * - * @return string - */ - function getSeries() - { - if (preg_match('/(\d{4})/', $this->_rawModel)) { - return 'FOMA'; - } - - if (preg_match('/(\d{3}i)/', $this->_rawModel, $matches)) { - return $matches[1]; - } - - if ($this->_rawModel == 'P651ps') { - return '651'; - } - } - - // }}} - // {{{ getVendor() - - /** - * returns vender code like 'SO' for Sony. returns null if unknown. - * - * @return string - */ - function getVendor() - { - if (preg_match('/([A-Z]+)\d/', $this->_rawModel, $matches)) { - return $matches[1]; - } - } - - // }}} - // {{{ getStatus() - - /** - * returns status like "TB", "TC", "TD" or "TJ", which means: - * - * TB | Browsers - * TC | Browsers with image off (only Available in HTML 5.0) - * TD | Fetching JAR - * TJ | i-Appli - * - * @return string - */ - function getStatus() - { - return $this->_status; - } - - // }}} - // {{{ getBandwidth() - - /** - * returns bandwidth like 32 as killobytes unit. Only vailable in eggy, - * returns null otherwise. - * - * @return integer - */ - function getBandwidth() - { - return $this->_bandwidth; - } - - // }}} - // {{{ getSerialNumber() - - /** - * returns hardware unique serial number (15 digit in FOMA, 11 digit - * otherwise alphanumeric). Only available with form utn attribute. - * returns null otherwise. - * - * @return string - */ - function getSerialNumber() - { - return $this->_serialNumber; - } - - // }}} - // {{{ isFOMA() - - /** - * retuns whether it's FOMA or not - * - * @return boolean - */ - function isFOMA() - { - return $this->_isFOMA; - } - - // }}} - // {{{ getComment() - - /** - * returns comment on user agent string like 'Google Proxy'. returns null - * otherwise. - * - * @return string - */ - function getComment() - { - return $this->_comment; - } - - // }}} - // {{{ getCardID() - - /** - * returns FOMA Card ID (20 digit alphanumeric). Only available in FOMA - * with attribute. returns null otherwise. - * - * @return string - */ - function getCardID() - { - return $this->_cardID; - } - - // }}} - // {{{ isGPS() - - /** - * Returns whether a user agent is a GPS model or not. - * - * @return boolean - */ - function isGPS() - { - return in_array($this->_rawModel, $this->_gpsModels); - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @return string - */ - function getCarrierShortName() - { - return 'I'; - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @return string - */ - function getCarrierLongName() - { - return 'DoCoMo'; - } - - // }}} - // {{{ getUID() - - /** - * Gets the UID of a subscriber. - * - * @return string - * @since Method available since Release 1.0.0RC1 - */ - function getUID() - { - if (array_key_exists('HTTP_X_DCMGUID', $_SERVER)) { - return $_SERVER['HTTP_X_DCMGUID']; - } - } - - // }}} - // {{{ getBrowserVersion() - - /** - * Gets the i-mode browser version. - * - * @return string - * @since Method available since Release 1.0.0RC3 - */ - function getBrowserVersion() - { - return $this->getCacheSize() == 500 ? '2.0' : '1.0'; - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - // }}} - // {{{ _parseMain() - - /** - * parse main part of HTTP_USER_AGENT string (not FOMA) - * - * @param string $main main part of HTTP_USER_AGENT string - * @throws Net_UserAgent_Mobile_Error - */ - function _parseMain($main) - { - @list($this->name, $this->version, $this->_rawModel, $cache, $rest) = - explode('/', $main, 5); - if ($this->_rawModel == 'SH505i2') { - $this->_model = 'SH505i'; - } - - if ($cache) { - if (!preg_match('/^c(\d+)$/', $cache, $matches)) { - return $this->noMatch(); - } - $this->_cacheSize = (integer)$matches[1]; - } - - if ($rest) { - $rest = explode('/', $rest); - foreach ($rest as $value) { - if (preg_match('/^ser(\w{11})$/', $value, $matches)) { - $this->_serialNumber = $matches[1]; - continue; - } - if (preg_match('/^(T[CDBJ])$/', $value, $matches)) { - $this->_status = $matches[1]; - continue; - } - if (preg_match('/^s(\d+)$/', $value, $matches)) { - $this->_bandwidth = (integer)$matches[1]; - continue; - } - if (preg_match('/^W(\d+)H(\d+)$/', $value, $matches)) { - $this->_displayBytes = "{$matches[1]}*{$matches[2]}"; - continue; - } - } - } - } - - // }}} - // {{{ _parseFOMA() - - /** - * parse main part of HTTP_USER_AGENT string (FOMA) - * - * @param string $foma main part of HTTP_USER_AGENT string - * @throws Net_UserAgent_Mobile_Error - */ - function _parseFOMA($foma) - { - if (!preg_match('/^([^(\s]+)/', $foma, $matches)) { - return $this->noMatch(); - } - - $this->_rawModel = $matches[1]; - if ($this->_rawModel == 'MST_v_SH2101V') { - $this->_model = 'SH2101V'; - } - - if (preg_match('/^[^(\s]+\s?\(([^)]+)\)(?:\(([^)]+)\))?$/', $foma, $matches)) { - if (preg_match('/^compatible/', $matches[1])) { // The user-agent is DoCoMo compatible. - $this->_comment = $matches[1]; - return; - } - - if (count($matches) == 3) { - if (preg_match('/^compatible/', $matches[2])) { // The user-agent is DoCoMo compatible. - $this->_comment = $matches[2]; - } - } - - $rest = explode(';', $matches[1]); - foreach ($rest as $value) { - if (preg_match('/^c(\d+)$/', $value, $matches)) { - $this->_cacheSize = (integer)$matches[1]; - continue; - } - if (preg_match('/^ser(\w{15})$/', $value, $matches)) { - $this->_serialNumber = $matches[1]; - continue; - } - if (preg_match('/^([A-Z]+)$/', $value, $matches)) { - $this->_status = $matches[1]; - continue; - } - if (preg_match('/^icc(\w{20})?$/', $value, $matches)) { - if (count($matches) == 2) { - $this->_cardID = $matches[1]; - } - continue; - } - if (preg_match('/^W(\d+)H(\d+)$/', $value, $matches)) { - $this->_displayBytes = "{$matches[1]}*{$matches[2]}"; - continue; - } - return $this->noMatch(); - } - } - } - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/DoCoMo/ScreenInfo.php b/data/module/Net/UserAgent/Mobile/DoCoMo/ScreenInfo.php deleted file mode 100644 index e7a1b98a37..0000000000 --- a/data/module/Net/UserAgent/Mobile/DoCoMo/ScreenInfo.php +++ /dev/null @@ -1,2184 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2008-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ScreenInfo.php,v 1.2 2009/06/23 08:06:58 kuboa Exp $ - * @link http://www.nttdocomo.co.jp/service/imode/make/content/spec/screen_area/index.html - * @since File available since Release 1.0.0RC1 - */ - -// {{{ GLOBALS - -$GLOBALS['NET_USERAGENT_MOBILE_DoCoMo_ScreenInfo_Instance'] = null; - -// }}} -// {{{ Net_UserAgent_Mobile_DoCoMo_ScreenInfo - -/** - * The screen information class for DoCoMo. - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2008-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @link http://www.nttdocomo.co.jp/service/imode/make/content/spec/screen_area/index.html - * @since Class available since Release 1.0.0RC1 - */ -class Net_UserAgent_Mobile_DoCoMo_ScreenInfo -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - var $_data = array( - - // i-mode compliant HTML 1.0 - 'D501I' => array( - 'width' => 96, - 'height' => 72, - 'depth' => 2, - 'color' => 0 - ), - 'F501I' => array( - 'width' => 112, - 'height' => 84, - 'depth' => 2, - 'color' => 0 - ), - 'N501I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 2, - 'color' => 0 - ), - 'P501I' => array( - 'width' => 96, - 'height' => 120, - 'depth' => 2, - 'color' => 0 - ), - - // i-mode compliant HTML 2.0 - 'D502I' => array( - 'width' => 96, - 'height' => 90, - 'depth' => 256, - 'color' => 1 - ), - 'F502I' => array( - 'width' => 96, - 'height' => 91, - 'depth' => 256, - 'color' => 1 - ), - 'N502I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4, - 'color' => 0 - ), - 'P502I' => array( - 'width' => 96, - 'height' => 117, - 'depth' => 4, - 'color' => 0 - ), - 'NM502I' => array( - 'width' => 111, - 'height' => 106, - 'depth' => 2, - 'color' => 0 - ), - 'SO502I' => array( - 'width' => 120, - 'height' => 120, - 'depth' => 4, - 'color' => 0 - ), - 'F502IT' => array( - 'width' => 96, - 'height' => 91, - 'depth' => 256, - 'color' => 1 - ), - 'N502IT' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 256, - 'color' => 1 - ), - 'SO502IWM' => array( - 'width' => 120, - 'height' => 113, - 'depth' => 256, - 'color' => 1 - ), - 'SH821I' => array( - 'width' => 96, - 'height' => 78, - 'depth' => 256, - 'color' => 1 - ), - 'N821I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4, - 'color' => 0 - ), - 'P821I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4, - 'color' => 0 - ), - 'D209I' => array( - 'width' => 96, - 'height' => 90, - 'depth' => 256, - 'color' => 1 - ), - 'ER209I' => array( - 'width' => 120, - 'height' => 72, - 'depth' => 2, - 'color' => 0 - ), - 'F209I' => array( - 'width' => 96, - 'height' => 91, - 'depth' => 256, - 'color' => 1 - ), - 'KO209I' => array( - 'width' => 96, - 'height' => 96, - 'depth' => 256, - 'color' => 1 - ), - 'N209I' => array( - 'width' => 108, - 'height' => 82, - 'depth' => 4, - 'color' => 0 - ), - 'P209I' => array( - 'width' => 96, - 'height' => 87, - 'depth' => 4, - 'color' => 0 - ), - 'P209IS' => array( - 'width' => 96, - 'height' => 87, - 'depth' => 256, - 'color' => 1 - ), - 'R209I' => array( - 'width' => 96, - 'height' => 72, - 'depth' => 4, - 'color' => 0 - ), - 'P651PS' => array( - 'width' => 96, - 'height' => 87, - 'depth' => 4, - 'color' => 0 - ), - 'R691I' => array( - 'width' => 96, - 'height' => 72, - 'depth' => 4, - 'color' => 0 - ), - 'F671I' => array( - 'width' => 120, - 'height' => 126, - 'depth' => 256, - 'color' => 1 - ), - 'F210I' => array( - 'width' => 96, - 'height' => 113, - 'depth' => 256, - 'color' => 1 - ), - 'N210I' => array( - 'width' => 118, - 'height' => 113, - 'depth' => 256, - 'color' => 1 - ), - 'P210I' => array( - 'width' => 96, - 'height' => 91, - 'depth' => 256, - 'color' => 1 - ), - 'KO210I' => array( - 'width' => 96, - 'height' => 96, - 'depth' => 256, - 'color' => 1 - ), - - // i-mode compliant HTML 3.0 - 'F503I' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 256, - 'color' => 1 - ), - 'F503IS' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 4096, - 'color' => 1 - ), - 'P503I' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 256, - 'color' => 1 - ), - 'P503IS' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 256, - 'color' => 1 - ), - 'N503I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4096, - 'color' => 1 - ), - 'N503IS' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4096, - 'color' => 1 - ), - 'SO503I' => array( - 'width' => 120, - 'height' => 113, - 'depth' => 65536, - 'color' => 1 - ), - 'SO503IS' => array( - 'width' => 120, - 'height' => 113, - 'depth' => 65536, - 'color' => 1 - ), - 'D503I' => array( - 'width' => 132, - 'height' => 126, - 'depth' => 4096, - 'color' => 1 - ), - 'D503IS' => array( - 'width' => 132, - 'height' => 126, - 'depth' => 4096, - 'color' => 1 - ), - 'D210I' => array( - 'width' => 96, - 'height' => 91, - 'depth' => 256, - 'color' => 1 - ), - 'SO210I' => array( - 'width' => 120, - 'height' => 113, - 'depth' => 256, - 'color' => 1 - ), - 'F211I' => array( - 'width' => 96, - 'height' => 113, - 'depth' => 4096, - 'color' => 1 - ), - 'D211I' => array( - 'width' => 100, - 'height' => 91, - 'depth' => 4096, - 'color' => 1 - ), - 'N211I' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4096, - 'color' => 1 - ), - 'N211IS' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4096, - 'color' => 1 - ), - 'P211I' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 65536, - 'color' => 1 - ), - 'P211IS' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 65536, - 'color' => 1 - ), - 'SO211I' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 4096, - 'color' => 1 - ), - 'R211I' => array( - 'width' => 96, - 'height' => 98, - 'depth' => 4096, - 'color' => 1 - ), - 'SH251I' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 65536, - 'color' => 1 - ), - 'SH251IS' => array( - 'width' => 176, - 'height' => 187, - 'depth' => 65536, - 'color' => 1 - ), - 'R692I' => array( - 'width' => 96, - 'height' => 98, - 'depth' => 4096, - 'color' => 1 - ), - - // i-mode compliant HTML 3.0 - // (FOMA 2001/2002/2101V) - 'N2001' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 4096, - 'color' => 1 - ), - 'N2002' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 65536, - 'color' => 1 - ), - 'P2002' => array( - 'width' => 118, - 'height' => 128, - 'depth' => 65536, - 'color' => 1 - ), - 'D2101V' => array( - 'width' => 120, - 'height' => 130, - 'depth' => 262144, - 'color' => 1 - ), - 'P2101V' => array( - 'width' => 163, - 'height' => 182, - 'depth' => 262144, - 'color' => 1 - ), - 'SH2101V' => array( - 'width' => 800, - 'height' => 600, - 'depth' => 65536, - 'color' => 1 - ), - 'T2101V' => array( - 'width' => 176, - 'height' => 144, - 'depth' => 262144, - 'color' => 1 - ), - - // i-mode compliant HTML 4.0 - 'D504I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 262144, - 'color' => 1 - ), - 'F504I' => array( - 'width' => 132, - 'height' => 136, - 'depth' => 65536, - 'color' => 1 - ), - 'F504IS' => array( - 'width' => 132, - 'height' => 136, - 'depth' => 65536, - 'color' => 1 - ), - 'N504I' => array( - 'width' => 160, - 'height' => 180, - 'depth' => 65536, - 'color' => 1 - ), - 'N504IS' => array( - 'width' => 160, - 'height' => 180, - 'depth' => 65536, - 'color' => 1 - ), - 'SO504I' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 65536, - 'color' => 1 - ), - 'P504I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'P504IS' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'D251I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 262144, - 'color' => 1 - ), - 'D251IS' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 262144, - 'color' => 1 - ), - 'F251I' => array( - 'width' => 132, - 'height' => 140, - 'depth' => 65536, - 'color' => 1 - ), - 'N251I' => array( - 'width' => 132, - 'height' => 140, - 'depth' => 65536, - 'color' => 1 - ), - 'N251IS' => array( - 'width' => 132, - 'height' => 140, - 'depth' => 65536, - 'color' => 1 - ), - 'P251IS' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'F671IS' => array( - 'width' => 160, - 'height' => 120, - 'depth' => 65536, - 'color' => 1 - ), - 'F212I' => array( - 'width' => 132, - 'height' => 136, - 'depth' => 65536, - 'color' => 1 - ), - 'SO212I' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 65536, - 'color' => 1 - ), - 'F661I' => array( - 'width' => 132, - 'height' => 136, - 'depth' => 65536, - 'color' => 1 - ), - 'F672I' => array( - 'width' => 160, - 'height' => 120, - 'depth' => 65536, - 'color' => 1 - ), - 'SO213I' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 65536, - 'color' => 1 - ), - 'SO213IS' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 65536, - 'color' => 1 - ), - 'SO213IWR' => array( - 'width' => 120, - 'height' => 112, - 'depth' => 65536, - 'color' => 1 - ), - - // i-mode compliant HTML 4.0 - // (FOMA 2051/2102V/2701 etc.) - 'F2051' => array( - 'width' => 176, - 'height' => 182, - 'depth' => 65536, - 'color' => 1 - ), - 'N2051' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 65536, - 'color' => 1 - ), - 'P2102V' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 262144, - 'color' => 1 - ), - 'P2102V' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 262144, - 'color' => 1 - ), - 'F2102V' => array( - 'width' => 176, - 'height' => 182, - 'depth' => 65536, - 'color' => 1 - ), - 'N2102V' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 65536, - 'color' => 1 - ), - 'N2701' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 65536, - 'color' => 1 - ), - 'NM850IG' => array( - 'width' => 176, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'NM705I' => array( - 'width' => 231, - 'height' => 235, - 'depth' => 16777216, - 'color' => 1 - ), - 'NM706I' => array( - 'width' => 231, - 'height' => 235, - 'depth' => 16777216, - 'color' => 1 - ), - - // i-mode compliant HTML 5.0 (505i etc.) - 'D505I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'SO505I' => array( - 'width' => 256, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH505I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'N505I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F505I' => array( - 'width' => 240, - 'height' => 268, - 'depth' => 262144, - 'color' => 1 - ), - 'P505I' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 65536, - 'color' => 1 - ), - 'D505IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'P505IS' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 65536, - 'color' => 1 - ), - 'N505IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'SO505IS' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'SH505IS' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'F505IGPS' => array( - 'width' => 240, - 'height' => 268, - 'depth' => 262144, - 'color' => 1 - ), - 'D252I' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 262144, - 'color' => 1 - ), - 'SH252I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'P252I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'N252I' => array( - 'width' => 132, - 'height' => 140, - 'depth' => 65536, - 'color' => 1 - ), - 'P252IS' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'D506I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F506I' => array( - 'width' => 240, - 'height' => 268, - 'depth' => 262144, - 'color' => 1 - ), - 'N506I' => array( - 'width' => 240, - 'height' => 295, - 'depth' => 262144, - 'color' => 1 - ), - 'P506IC' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 65536, - 'color' => 1 - ), - 'SH506IC' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'SO506IC' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'N506IS' => array( - 'width' => 240, - 'height' => 295, - 'depth' => 262144, - 'color' => 1 - ), - 'SO506I' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'SO506IS' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'N506IS2' => array( - 'width' => 240, - 'height' => 295, - 'depth' => 262144, - 'color' => 1 - ), - 'P506ICII' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 65536, - 'color' => 1 - ), - 'D253I' => array( - 'width' => 176, - 'height' => 198, - 'depth' => 262144, - 'color' => 1 - ), - 'N253I' => array( - 'width' => 160, - 'height' => 180, - 'depth' => 65536, - 'color' => 1 - ), - 'P253I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'D253IWM' => array( - 'width' => 220, - 'height' => 144, - 'depth' => 262144, - 'color' => 1 - ), - 'P253IS' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - 'P213I' => array( - 'width' => 132, - 'height' => 144, - 'depth' => 65536, - 'color' => 1 - ), - - // i-mode compliant HTML 5.0 - // (FOMA 900i etc.) - 'F900I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'N900I' => array( - 'width' => 240, - 'height' => 269, - 'depth' => 65536, - 'color' => 1 - ), - 'P900I' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 65536, - 'color' => 1 - ), - 'SH900I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'F900IT' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P900IV' => array( - 'width' => 240, - 'height' => 266, - 'depth' => 262144, - 'color' => 1 - ), - 'N900IS' => array( - 'width' => 240, - 'height' => 269, - 'depth' => 65536, - 'color' => 1 - ), - 'D900I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F900IC' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'F880IES' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'N900IL' => array( - 'width' => 240, - 'height' => 269, - 'depth' => 65536, - 'color' => 1 - ), - 'N900IG' => array( - 'width' => 240, - 'height' => 269, - 'depth' => 65536, - 'color' => 1 - ), - 'SH901IC' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'F901IC' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'N901IC' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'D901I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P901I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'F700I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH700I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'N700I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'P700I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'F700IS' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH700IS' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'SA700IS' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 65536, - 'color' => 1 - ), - - 'SH901IS' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'F901IS' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'D901IS' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P901IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'N901IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'P901ITV' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'SH851I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 262144, - 'color' => 1 - ), - 'P851I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'F881IES' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'D701I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 65536, - 'color' => 1 - ), - 'N701I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'P701ID' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'D701IWM' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 65536, - 'color' => 1 - ), - 'N701IECO' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'SA800I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 65536, - 'color' => 1 - ), - 'L600I' => array( - 'width' => 170, - 'height' => 189, - 'depth' => 65536, - 'color' => 1 - ), - 'N600I' => array( - 'width' => 176, - 'height' => 180, - 'depth' => 65536, - 'color' => 1 - ), - 'L601I' => array( - 'width' => 170, - 'height' => 189, - 'depth' => 65536, - 'color' => 1 - ), - 'M702IS' => array( - 'width' => 240, - 'height' => 267, - 'depth' => 262144, - 'color' => 1 - ), - 'M702IG' => array( - 'width' => 240, - 'height' => 267, - 'depth' => 262144, - 'color' => 1 - ), - 'L602I' => array( - 'width' => 170, - 'height' => 189, - 'depth' => 65536, - 'color' => 1 - ), - - // i-mode compliant HTML 6.0 - // (FOMA 902i etc.) - 'F902I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'D902I' => array( - 'width' => 230, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N902I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'P902I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'SH902I' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SO902I' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'SH902IS' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P902IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'N902IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'D902IS' => array( - 'width' => 230, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F902IS' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SO902IWP+' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'SH902ISL' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'N902IX' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'N902IL' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'P702I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'N702ID' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'F702ID' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH702ID' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'D702I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SO702I' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - 'D702IBCL' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SA702I' => array( - 'width' => 240, - 'height' => 252, - 'depth' => 65536, - 'color' => 1 - ), - 'SH702IS' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'N702IS' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'P702ID' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'D702IF' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'D851IWM' => array( - 'width' => 230, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F882IES' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'N601I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 65536, - 'color' => 1 - ), - 'D800IDS' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P703IMYU' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F883I' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'F883IS' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'P704IMYU' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'L704I' => array( - 'width' => 240, - 'height' => 280, - 'depth' => 262144, - 'color' => 1 - ), - 'L705I' => array( - 'width' => 240, - 'height' => 280, - 'depth' => 262144, - 'color' => 1 - ), - 'L705IX' => array( - 'width' => 240, - 'height' => 280, - 'depth' => 262144, - 'color' => 1 - ), - 'L852I' => array( - 'width' => 240, - 'height' => 298, - 'depth' => 65536, - 'color' => 1 - ), - 'L706IE' => array( - 'width' => 240, - 'height' => 280, - 'depth' => 262144, - 'color' => 1 - ), - 'L01A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'L03A' => array( - 'width' => 240, - 'height' => 280, - 'depth' => 262144, - 'color' => 1 - ), - - // i-mode compliant HTML 7.0 - // (FOMA 903i etc.) - 'SH903I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P903I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'N903I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'D903I' => array( - 'width' => 230, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F903I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SO903I' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 262144, - 'color' => 1 - ), - 'D903ITV' => array( - 'width' => 230, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F903IX' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P903ITV' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'SH903ITV' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F903IBSC' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P903IX' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'SO903ITV' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 262144, - 'color' => 1 - ), - 'N703ID' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F703I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'P703I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'D703I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH703I' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH703I' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'N703IMYU' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'SO703I' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 262144, - 'color' => 1 - ), - 'P904I' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'D904I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F904I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'N904I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'SH904I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P704I' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'D704I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH704I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N704IMYU' => array( - 'width' => 240, - 'height' => 270, - 'depth' => 262144, - 'color' => 1 - ), - 'F704I' => array( - 'width' => 230, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SO704I' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 262144, - 'color' => 1 - ), - 'F883IES' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'F883IESS' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 65536, - 'color' => 1 - ), - 'F801I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 65536, - 'color' => 1 - ), - 'F705I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'D705I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'D705IMYU' => array( - 'width' => 240, - 'height' => 240, - 'depth' => 262144, - 'color' => 1 - ), - 'SH705I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'SH705I2' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'SH706IE' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F05A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 65536, - 'color' => 1 - ), - - // i-mode compliant HTML 7.1 - // (FOMA 905i etc.) - 'SH905I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'D905I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'N905I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P905I' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'F905I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'SO905I' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 16777216, - 'color' => 1 - ), - 'N905IMYU' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N905IBIZ' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'SH905ITV' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'SO905ICS' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 16777216, - 'color' => 1 - ), - 'F905IBIZ' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'P905ITV' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P705I' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'N705I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N705IMYU' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P705IMYU' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'SO705I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P705ICL' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'F884I' => array( - 'width' => 240, - 'height' => 364, - 'depth' => 262144, - 'color' => 1 - ), - 'F884IES' => array( - 'width' => 240, - 'height' => 282, - 'depth' => 262144, - 'color' => 1 - ), - 'N906IL' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N706I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'SO706I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'P706IMYU' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'N706IE' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N706I2' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N03A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N05A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F07A' => array( - 'width' => 240, - 'height' => 256, - 'depth' => 262144, - 'color' => 1 - ), - - // i-mode compliant HTML 7.2 - // (FOMA 906i etc.) - 'P906I' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'SO906I' => array( - 'width' => 240, - 'height' => 368, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH906I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'N906IMYU' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'F906I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'N906I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'SH906ITV' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'F706I' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'SH706I' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'P706IE' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'SH706IW' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'F01A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'F02A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'F03A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'F04A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 262144, - 'color' => 1 - ), - 'F06A' => array( - 'width' => 240, - 'height' => 352, - 'depth' => 16777216, - 'color' => 1 - ), - 'P01A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P02A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P03A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P04A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P05A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P06A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'P10A' => array( - 'width' => 240, - 'height' => 350, - 'depth' => 262144, - 'color' => 1 - ), - 'SH01A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH02A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH03A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH04A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 16777216, - 'color' => 1 - ), - 'N01A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N02A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - 'N04A' => array( - 'width' => 240, - 'height' => 320, - 'depth' => 262144, - 'color' => 1 - ), - - // i-mode browser 2.0 - 'P07A3' => array( - 'width' => 480, - 'height' => 662, - 'depth' => 262144, - 'color' => 1 - ), - 'P08A3' => array( - 'width' => 480, - 'height' => 662, - 'depth' => 262144, - 'color' => 1 - ), - 'P09A3' => array( - 'width' => 480, - 'height' => 662, - 'depth' => 262144, - 'color' => 1 - ), - 'N06A3' => array( - 'width' => 480, - 'height' => 640, - 'depth' => 262144, - 'color' => 1 - ), - 'N08A3' => array( - 'width' => 480, - 'height' => 640, - 'depth' => 262144, - 'color' => 1 - ), - 'N09A3' => array( - 'width' => 480, - 'height' => 640, - 'depth' => 262144, - 'color' => 1 - ), - 'F08A3' => array( - 'width' => 480, - 'height' => 648, - 'depth' => 262144, - 'color' => 1 - ), - 'F09A3' => array( - 'width' => 480, - 'height' => 648, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH05A3' => array( - 'width' => 480, - 'height' => 592, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH06A3' => array( - 'width' => 480, - 'height' => 592, - 'depth' => 16777216, - 'color' => 1 - ), - 'SH07A3' => array( - 'width' => 480, - 'height' => 592, - 'depth' => 16777216, - 'color' => 1 - ) - ); - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ singleton() - - /** - * Returns the Net_UserAgent_Mobile_DoCoMo_Screen instance if it exists. If it - * not exists, a new instance of Net_UserAgent_Mobile_DoCoMo_Screen will be - * created and returned. - * - * @return Net_UserAgent_Mobile_DoCoMo_ScreenInfo - * @static - */ - function &singleton() - { - if (@is_null($GLOBALS['NET_USERAGENT_MOBILE_DoCoMo_ScreenInfo_Instance'])) { - $GLOBALS['NET_USERAGENT_MOBILE_DoCoMo_ScreenInfo_Instance'] = &new Net_UserAgent_Mobile_DoCoMo_ScreenInfo(); - } - - return $GLOBALS['NET_USERAGENT_MOBILE_DoCoMo_ScreenInfo_Instance']; - } - - // }}} - // {{{ get() - - /** - * Gets the screen information of a given model. - * - * @param string $model - * @return array - */ - function get($model) - { - return $this->_data[ strtoupper($model) ]; - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - // }}} - // {{{ constructor - - /** - * Creates the screen information by a given XML file if DOCOMO_MAP environment - * variable exists. - */ - function Net_UserAgent_Mobile_DoCoMo_ScreenInfo() - { - if (!array_key_exists('DOCOMO_MAP', $_SERVER)) { - return; - } - - // using the specified XML data - do { - if (!function_exists('xml_parser_create') - || !is_readable($_SERVER['DOCOMO_MAP']) - ) { - break; - } - - $xml = file_get_contents($_SERVER['DOCOMO_MAP']); - if ($xml === false) { - break; - } - - $parser = xml_parser_create(); - if ($parser === false) { - break; - } - - xml_parse_into_struct($parser, $xml, $values, $indexes); - if (!xml_parser_free($parser)) { - break; - } - - if (array_key_exists('OPT', $indexes)) { - unset($indexes['OPT']); - } - - $data = array(); - foreach ($indexes as $modelName => $modelIndexes) { - $data[$modelName] = array(); - foreach ($values[ $modelIndexes[0] ]['attributes'] - as $attributeName => $attributeValue - ) { - $data[$modelName][ strtolower($attributeName) ] = $attributeValue; - } - } - - $this->_data = $data; - } while (false); - } - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/EZweb.php b/data/module/Net/UserAgent/Mobile/EZweb.php deleted file mode 100644 index f8c1703cc1..0000000000 --- a/data/module/Net/UserAgent/Mobile/EZweb.php +++ /dev/null @@ -1,342 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://www.au.kddi.com/ezfactory/tec/spec/4_4.html - * @link http://www.au.kddi.com/ezfactory/tec/spec/new_win/ezkishu.html - * @since File available since Release 0.1.0 - */ - -require_once dirname(__FILE__) . '/Common.php'; -require_once dirname(__FILE__) . '/Display.php'; - -// {{{ Net_UserAgent_Mobile_EZweb - -/** - * EZweb implementation - * - * Net_UserAgent_Mobile_EZweb is a subclass of {@link Net_UserAgent_Mobile_Common}, - * which implements EZweb (WAP1.0/2.0) user agents. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $_SERVER['HTTP_USER_AGENT'] = 'UP.Browser/3.01-HI02 UP.Link/3.2.1.2'; - * $agent = &Net_UserAgent_Mobile::factory(); - * - * printf("Name: %s\n", $agent->getName()); // 'UP.Browser' - * printf("Version: %s\n", $agent->getVersion()); // 3.01 - * printf("DeviceID: %s\n", $agent->getDeviceID()); // 'HI02' - * printf("Server: %s\n", $agent->getServer()); // 'UP.Link/3.2.1.2' - * - * e.g.) 'UP.Browser/3.01-HI02 UP.Link/3.2.1.2 (Google WAP Proxy/1.0)' - * printf("Comment: %s\n", $agent->getComment()); // 'Google WAP Proxy/1.0' - * - * e.g.) 'KDDI-TS21 UP.Browser/6.0.2.276 (GUI) MMP/1.1' - * if ($agent->isXHTMLCompliant()) { - * print "XHTML compliant!\n"; // true - * } - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @link http://www.au.kddi.com/ezfactory/tec/spec/4_4.html - * @link http://www.au.kddi.com/ezfactory/tec/spec/new_win/ezkishu.html - * @since Class available since Release 0.1.0 - */ -class Net_UserAgent_Mobile_EZweb extends Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * server string like 'UP.Link/3.2.1.2' - * @var string - */ - var $_serverName = ''; - - /** - * comment like 'Google WAP Proxy/1.0' - * @var string - */ - var $_comment = null; - - /** - * whether it's XHTML compliant or not - * @var boolean - */ - var $_xhtmlCompliant = false; - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ isEZweb() - - /** - * returns true - * - * @return boolean - */ - function isEZweb() - { - return true; - } - - // }}} - // {{{ isTUKa() - - /** - * returns true if the agent is TU-Ka - * - * @return boolean - */ - function isTUKa() - { - $tuka = substr($this->_rawModel, 2, 1); - if ($this->isWAP2()) { - if ($tuka == 'U') { - return true; - } - } else { - if ($tuka == 'T') { - return true; - } - } - - return false; - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - */ - function parse($userAgent) - { - if (preg_match('/^KDDI-(.*)/', $userAgent, $matches)) { - - // KDDI-TS21 UP.Browser/6.0.2.276 (GUI) MMP/1.1 - $this->_xhtmlCompliant = true; - @list($this->_rawModel, $browser, $opt, $this->_serverName) = - explode(' ', $matches[1], 4); - @list($this->name, $version) = explode('/', $browser); - $this->version = "$version $opt"; - } else { - - // UP.Browser/3.01-HI01 UP.Link/3.4.5.2 - @list($browser, $this->_serverName, $comment) = - explode(' ', $userAgent, 3); - @list($this->name, $software) = explode('/', $browser); - @list($this->version, $this->_rawModel) = explode('-', $software); - if ($comment) { - $this->_comment = preg_replace('/^\((.*)\)$/', '$1', $comment); - } - } - } - - // }}} - // {{{ makeDisplay() - - /** - * create a new {@link Net_UserAgent_Mobile_Display} class instance - * - * @return Net_UserAgent_Mobile_Display - */ - function makeDisplay() - { - @list($width, $height) = - explode(',', $this->getHeader('X-UP-DEVCAP-SCREENPIXELS')); - $screenDepth = explode(',', $this->getHeader('X-UP-DEVCAP-SCREENDEPTH')); - $depth = $screenDepth[0] ? pow(2, (integer)$screenDepth[0]) : 0; - $color = $this->getHeader('X-UP-DEVCAP-ISCOLOR') === '1' ? true : false; - return new Net_UserAgent_Mobile_Display(array('width' => $width, - 'height' => $height, - 'color' => $color, - 'depth' => $depth) - ); - } - - // }}} - // {{{ getDeviceID() - - /** - * Returns the device ID of the user agent. - * - * @return string - */ - function getDeviceID() - { - return $this->_rawModel; - } - - // }}} - // {{{ getServer() - - /** - * returns server string like 'UP.Link/3.2.1.2' - * - * @return string - */ - function getServer() - { - return $this->_serverName; - } - - // }}} - // {{{ getComment() - - /** - * returns comment like 'Google WAP Proxy/1.0'. returns null if nothinng. - * - * @return boolean - */ - function getComment() - { - return $this->_comment; - } - - // }}} - // {{{ isXHTMLCompliant() - - /** - * returns whether it's XHTML compliant or not - * - * @return boolean - */ - function isXHTMLCompliant() - { - return $this->_xhtmlCompliant; - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @return string - */ - function getCarrierShortName() - { - return 'E'; - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @return string - */ - function getCarrierLongName() - { - return 'EZweb'; - } - - // }}} - // {{{ isWIN() - - /** - * Returns whether the agent is CDMA 1X WIN or not. - * - * @return boolean - */ - function isWIN() - { - return substr($this->_rawModel, 2, 1) == 3 ? true : false; - } - - // }}} - // {{{ getUID() - - /** - * Gets the UID of a subscriber. - * - * @return string - * @since Method available since Release 1.0.0RC1 - */ - function getUID() - { - if (array_key_exists('HTTP_X_UP_SUBNO', $_SERVER)) { - return $_SERVER['HTTP_X_UP_SUBNO']; - } - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/Error.php b/data/module/Net/UserAgent/Mobile/Error.php deleted file mode 100644 index 19056c816e..0000000000 --- a/data/module/Net/UserAgent/Mobile/Error.php +++ /dev/null @@ -1,80 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Error.php,v 1.1 2009/05/26 08:48:16 kuboa Exp $ - * @since File available since Release 1.0.0RC3 - */ - -require_once dirname(__FILE__) . '/../../../PEAR.php'; - -// {{{ constants - -/** - * Constants for error handling. - */ -define('NET_USERAGENT_MOBILE_OK', 1); -define('NET_USERAGENT_MOBILE_ERROR', -1); -define('NET_USERAGENT_MOBILE_ERROR_NOMATCH', -2); -define('NET_USERAGENT_MOBILE_ERROR_NOT_FOUND', -3); - -// }}} -// {{{ Net_UserAgent_Mobile_Error - -/** - * Net_UserAgent_Mobile_Error implements a class for reporting user agent error - * messages - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @since Class available since Release 0.1 - */ -class Net_UserAgent_Mobile_Error extends PEAR_Error {} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/NonMobile.php b/data/module/Net/UserAgent/Mobile/NonMobile.php deleted file mode 100644 index e2af4242fb..0000000000 --- a/data/module/Net/UserAgent/Mobile/NonMobile.php +++ /dev/null @@ -1,176 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @since File available since Release 0.1.0 - */ - -require_once dirname(__FILE__) . '/Common.php'; -require_once dirname(__FILE__) . '/Display.php'; - -// {{{ Net_UserAgent_Mobile_NonMobile - -/** - * Non-Mobile Agent implementation - * - * Net_UserAgent_Mobile_NonMobile is a subclass of - * {@link Net_UserAgent_Mobile_Common}, which implements non-mobile or unimplemented - * user agents. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0'; - * $agent = &Net_UserAgent_Mobile::factory(); - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @since Class available since Release 0.1.0 - */ -class Net_UserAgent_Mobile_NonMobile extends Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ isNonMobile() - - /** - * returns true - * - * @return boolean - */ - function isNonMobile() - { - return true; - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - */ - function parse($userAgent) - { - @list($this->name, $this->version) = explode('/', $userAgent); - } - - // }}} - // {{{ makeDisplay() - - /** - * create a new {@link Net_UserAgent_Mobile_Display} class instance - * - * @return Net_UserAgent_Mobile_Display - */ - function makeDisplay() - { - return new Net_UserAgent_Mobile_Display(null); - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @return string - */ - function getCarrierShortName() - { - return 'N'; - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @return string - */ - function getCarrierLongName() - { - return 'NonMobile'; - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/SoftBank.php b/data/module/Net/UserAgent/Mobile/SoftBank.php deleted file mode 100644 index e7e42369c0..0000000000 --- a/data/module/Net/UserAgent/Mobile/SoftBank.php +++ /dev/null @@ -1,592 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://creation.mb.softbank.jp/ - * @since File available since Release 0.20.0 - */ - -require_once dirname(__FILE__) . '/Common.php'; -require_once dirname(__FILE__) . '/Display.php'; -require_once dirname(__FILE__) . '/../Mobile.php'; - -// {{{ Net_UserAgent_Mobile_SoftBank - -/** - * SoftBank implementation - * - * Net_UserAgent_Mobile_SoftBank is a subclass of {@link Net_UserAgent_Mobile_Common}, - * which implements SoftBank user agents. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $_SERVER['HTTP_USER_AGENT'] = 'J-PHONE/2.0/J-DN02'; - * $agent = &Net_UserAgent_Mobile::factory(); - * - * printf("Name: %s\n", $agent->getName()); // 'J-PHONE' - * printf("Version: %s\n", $agent->getVersion()); // 2.0 - * printf("Model: %s\n", $agent->getModel()); // 'J-DN02' - * if ($agent->isPacketCompliant()) { - * print "Packet is compliant.\n"; // false - * } - * - * // only availabe in Java compliant - * // e.g.) 'J-PHONE/4.0/J-SH51/SNXXXXXXXXX SH/0001a Profile/MIDP-1.0 Configuration/CLDC-1.0 Ext-Profile/JSCL-1.1.0' - * printf("Serial: %s\n", $agent->getSerialNumber()); // XXXXXXXXX - * printf("Vendor: %s\n", $agent->getVendor()); // 'SH' - * printf("Vendor Version: %s\n", $agent->getVendorVersion()); // '0001a' - * - * $info = $agent->getJavaInfo(); // array - * foreach ($info as $key => $value) { - * print "$key: $value\n"; - * } - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @link http://creation.mb.softbank.jp/ - * @since Class available since Release 0.20.0 - */ -class Net_UserAgent_Mobile_SoftBank extends Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * whether the agent is packet connection complicant or not - * @var boolean - */ - var $_packetCompliant = false; - - /** - * terminal unique serial number - * @var string - */ - var $_serialNumber; - - /** - * vendor code like 'SH' - * @var string - */ - var $_vendor = ''; - - /** - * vendor version like '0001a' - * @var string - */ - var $_vendorVersion; - - /** - * Java profiles - * @var array - */ - var $_javaInfo = array(); - - /** - * whether the agent is 3G - * @var boolean - */ - var $_is3G = true; - - /** - * the name of the mobile phone - * @var string - */ - var $_msname = ''; - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ isJPhone() - - /** - * returns true - * - * @return boolean - */ - function isJPhone() - { - return $this->isSoftBank(); - } - - // }}} - // {{{ isVodafone() - - /** - * returns true - * - * @return boolean - */ - function isVodafone() - { - return $this->isSoftBank(); - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - * @throws Net_UserAgent_Mobile_Error - */ - function parse($userAgent) - { - $agent = explode(' ', $userAgent); - preg_match('!^(?:(SoftBank|Semulator|Vodafone|Vemulator|J-PHONE|J-EMULATOR)/\d\.\d|MOT-|MOTEMULATOR)!', - $agent[0], $matches - ); - if (count($matches) > 1) { - $carrier = $matches[1]; - } else { - $carrier = 'Motorola'; - } - - switch ($carrier) { - case 'SoftBank': - case 'Semulator': - case 'Vodafone': - case 'Vemulator': - $result = $this->_parseVodafone($agent); - break; - case 'J-PHONE': - case 'J-EMULATOR': - $result = $this->_parseJphone($agent); - break; - case 'Motorola': - case 'MOTEMULATOR': - $result = $this->_parseMotorola($agent); - break; - } - - if (Net_UserAgent_Mobile::isError($result)) { - return $result; - } - - $this->_msname = $this->getHeader('X-JPHONE-MSNAME'); - } - - // }}} - // {{{ makeDisplay() - - /** - * create a new {@link Net_UserAgent_Mobile_Display} class instance - * - * @return Net_UserAgent_Mobile_Display - */ - function makeDisplay() - { - @list($width, $height) = explode('*', $this->getHeader('X-JPHONE-DISPLAY')); - $color = false; - $depth = 0; - if ($color_string = $this->getHeader('X-JPHONE-COLOR')) { - preg_match('!^([CG])(\d+)$!', $color_string, $matches); - $color = $matches[1] === 'C' ? true : false; - $depth = $matches[2]; - } - - return new Net_UserAgent_Mobile_Display(array('width' => $width, - 'height' => $height, - 'depth' => $depth, - 'color' => $color) - ); - } - - // }}} - // {{{ isPacketCompliant() - - /** - * returns whether the agent is packet connection complicant or not - * - * @return boolean - */ - function isPacketCompliant() - { - return $this->_packetCompliant; - } - - // }}} - // {{{ getSerialNumber() - - /** - * return terminal unique serial number. returns null if user forbids to send - * his/her serial number. - * - * @return string - */ - function getSerialNumber() - { - return $this->_serialNumber; - } - - // }}} - // {{{ getVendor() - - /** - * returns vendor code like 'SH' - * - * @return string - */ - function getVendor() - { - return $this->_vendor; - } - - // }}} - // {{{ getVendorVersion() - - /** - * returns vendor version like '0001a'. returns null if unknown. - * - * @return string - */ - function getVendorVersion() - { - return $this->_vendorVersion; - } - - // }}} - // {{{ getJavaInfo() - - /** - * returns array of Java profiles - * - * Array structure is something like: - * - * - 'Profile' => 'MIDP-1.0', - * - 'Configuration' => 'CLDC-1.0', - * - 'Ext-Profile' => 'JSCL-1.1.0' - * - * @return array - */ - function getJavaInfo() - { - return $this->_javaInfo; - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @return string - */ - function getCarrierShortName() - { - return 'S'; - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @return string - */ - function getCarrierLongName() - { - return 'SoftBank'; - } - - // }}} - // {{{ isTypeC() - - /** - * returns true if the type is C - * - * @return boolean - */ - function isTypeC() - { - if ($this->_is3G || !preg_match('!^[32]\.!', $this->version)) { - return false; - } - - return true; - } - - // }}} - // {{{ isTypeP() - - /** - * returns true if the type is P - * - * @return boolean - */ - function isTypeP() - { - if ($this->_is3G || !preg_match('!^4\.!', $this->version)) { - return false; - } - - return true; - } - - // }}} - // {{{ isTypeW() - - /** - * returns true if the type is W - * - * @return boolean - */ - function isTypeW() - { - if ($this->_is3G || !preg_match('!^5\.!', $this->version)) { - return false; - } - - return true; - } - - // }}} - // {{{ isType3GC() - - /** - * returns true if the type is 3GC - * - * @return boolean - */ - function isType3GC() - { - return $this->_is3G; - } - - // }}} - // {{{ getMsname() - - /** - * returns the name of the mobile phone - * - * @return string the name of the mobile phone - */ - function getMsname() - { - return $this->_msname; - } - - // }}} - // {{{ isSoftBank() - - /** - * returns true if the agent is SoftBank. - * - * @return boolean - */ - function isSoftBank() - { - return true; - } - - // }}} - // {{{ getUID() - - /** - * Gets the UID of a subscriber. - * - * @return string - * @since Method available since Release 1.0.0RC1 - */ - function getUID() - { - if (array_key_exists('HTTP_X_JPHONE_UID', $_SERVER)) { - return $_SERVER['HTTP_X_JPHONE_UID']; - } - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - // }}} - // {{{ _parseVodafone() - - /** - * parse HTTP_USER_AGENT string for the Vodafone 3G aegnt - * - * @param array $agent parts of the User-Agent string - * @throws Net_UserAgent_Mobile_Error - */ - function _parseVodafone($agent) - { - $this->_packetCompliant = true; - - // Vodafone/1.0/V702NK/NKJ001 Series60/2.6 Nokia6630/2.39.148 Profile/MIDP-2.0 Configuration/CLDC-1.1 - // Vodafone/1.0/V702NK/NKJ001/SN123456789012345 Series60/2.6 Nokia6630/2.39.148 Profile/MIDP-2.0 Configuration/CLDC-1.1 - // Vodafone/1.0/V802SE/SEJ001/SN123456789012345 Browser/SEMC-Browser/4.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 - @list($this->name, $this->version, $this->_rawModel, $modelVersion, - $serialNumber) = explode('/', $agent[0]); - if ($serialNumber) { - if (!preg_match('!^SN(.+)!', $serialNumber, $matches)) { - return $this->noMatch(); - } - - $this->_serialNumber = $matches[1]; - } - - if (!preg_match('!^([a-z]+)((?:[a-z]|\d){4})$!i', $modelVersion, $matches)) { - return $this->noMatch(); - } - - $this->_vendor = $matches[1]; - $this->_vendorVersion = $matches[2]; - - for ($i = 2, $count = count($agent); $i < $count; ++$i) { - @list($key, $value) = explode('/', $agent[$i]); - $this->_javaInfo[$key] = $value; - } - } - - // }}} - // {{{ _parseJphone() - - /** - * parse HTTP_USER_AGENT string for the ancient agent - * - * @param array $agent parts of the User-Agent string - * @throws Net_UserAgent_Mobile_Error - */ - function _parseJphone($agent) - { - $count = count($agent); - $this->_is3G = false; - - if ($count > 1) { - - // J-PHONE/4.0/J-SH51/SNJSHA3029293 SH/0001aa Profile/MIDP-1.0 Configuration/CLDC-1.0 Ext-Profile/JSCL-1.1.0 - $this->_packetCompliant = true; - @list($this->name, $this->version, $this->_rawModel, $serialNumber) = - explode('/', $agent[0]); - if ($serialNumber) { - if (!preg_match('!^SN(.+)!', $serialNumber, $matches)) { - return $this->noMatch(); - } - - $this->_serialNumber = $matches[1]; - } - - @list($this->_vendor, $this->_vendorVersion) = explode('/', $agent[1]); - for ($i = 2; $i < $count; ++$i) { - @list($key, $value) = explode('/', $agent[$i]); - $this->_javaInfo[$key] = $value; - } - } else { - - // J-PHONE/2.0/J-DN02 - @list($this->name, $this->version, $this->_rawModel, $serialNumber) = - explode('/', $agent[0]); - if ($serialNumber) { - if (!preg_match('!^SN(.+)!', $serialNumber, $matches)) { - return $this->noMatch(); - } - - $this->_serialNumber = $matches[1]; - } - - if ($this->_rawModel) { - if (preg_match('!V\d+([A-Z]+)!', $this->_rawModel, $matches)) { - $this->_vendor = $matches[1]; - } elseif (preg_match('!J-([A-Z]+)!', $this->_rawModel, $matches)) { - $this->_vendor = $matches[1]; - } - } - } - } - - // }}} - // {{{ _parseMotorola() - - /** - * parse HTTP_USER_AGENT string for the Motorola 3G aegnt - * - * @param array $agent parts of the User-Agent string - */ - function _parseMotorola($agent) - { - $this->_packetCompliant = true; - $this->_vendor = 'MOT'; - - // MOT-V980/80.2F.2E. MIB/2.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 - @list($this->_rawModel, $this->_vendorVersion) = explode('/', $agent[0]); - $this->_model = substr(strrchr($this->_rawModel, '-'), 1); - - for ($i = 2, $count = count($agent); $i < $count; ++$i) { - @list($key, $value) = explode('/', $agent[$i]); - $this->_javaInfo[$key] = $value; - } - } - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/Net/UserAgent/Mobile/Willcom.php b/data/module/Net/UserAgent/Mobile/Willcom.php deleted file mode 100644 index 4c5119c802..0000000000 --- a/data/module/Net/UserAgent/Mobile/Willcom.php +++ /dev/null @@ -1,293 +0,0 @@ -, - * 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. - * - * 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 Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/homepage/index.html - * @since File available since Release 0.5 - */ - -require_once dirname(__FILE__) . '/Common.php'; -require_once dirname(__FILE__) . '/Display.php'; - -// {{{ Net_UserAgent_Mobile_Willcom - -/** - * AirH"PHONE implementation - * - * Net_UserAgent_Mobile_Willcom is a subclass of {@link Net_UserAgent_Mobile_Common}, - * which implements Willcom's user agents. - * - * SYNOPSIS: - * - * require_once 'Net/UserAgent/Mobile.php'; - * - * $_SERVER['HTTP_USER_AGENT'] = - * 'Mozilla/3.0(DDIPOCKET;JRC/AH-J3001V,AH-J3002V/1.0/0100/c50)CNF/2.0'; - * $agent = &Net_UserAgent_Mobile::factory(); - * - * printf("Name: %s\n", $agent->getName()); // 'DDIPOCKET' - * printf("Verdor: %s\n", $agent->getVendor()); // 'JRC' - * printf("Model: %s\n", $agent->getModel()); // 'AH-J3001V,AH-J3002V' - * printf("Model Version: %s\n", $agent->getModelVersion()); // '1.0' - * printf("Browser Version: %s\n", $agent->getBrowserVersion()); // '0100' - * printf("Cache Size: %s\n", $agent->getCacheSize()); // 50 - * - * - * @category Networking - * @package Net_UserAgent_Mobile - * @author KUBO Atsuhiro - * @copyright 2003-2009 KUBO Atsuhiro - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.0.0 - * @link http://www.willcom-inc.com/ja/service/contents_service/club_air_edge/for_phone/homepage/index.html - * @since Class available since Release 0.5 - */ -class Net_UserAgent_Mobile_Willcom extends Net_UserAgent_Mobile_Common -{ - - // {{{ properties - - /**#@+ - * @access public - */ - - /** - * User-Agent name - * @var string - */ - var $name = 'WILLCOM'; - - /**#@-*/ - - /**#@+ - * @access private - */ - - /** - * vendor name - * @var string - */ - var $_vendor; - - /** - * version number of the model - * @var string - */ - var $_modelVersion; - - /** - * version number of the browser - * @var string - */ - var $_browserVersion; - - /** - * cache size as killobytes unit - * @var integer - */ - var $_cacheSize; - - /**#@-*/ - - /**#@+ - * @access public - */ - - // }}} - // {{{ isAirHPhone() - - /** - * returns true - * - * @return boolean - */ - function isAirHPhone() - { - return $this->isWillcom(); - } - - // }}} - // {{{ parse() - - /** - * Parses HTTP_USER_AGENT string. - * - * @param string $userAgent User-Agent string - */ - function parse($userAgent) - { - if (preg_match('!^Mozilla/3\.0\((?:DDIPOCKET|WILLCOM);(.*)\)!', - $userAgent, $matches) - ) { - list($this->_vendor, $this->_rawModel, $this->_modelVersion, - $this->_browserVersion, $cache) = - explode('/', $matches[1]); - if (!preg_match('/^[Cc](\d+)/', $cache, $matches)) { - return $this->noMatch(); - } - $this->_cacheSize = (integer)$matches[1]; - } else { - $this->noMatch(); - } - } - - // }}} - // {{{ makeDisplay() - - /** - * create a new {@link Net_UserAgent_Mobile_Display} class instance - * - * @return Net_UserAgent_Mobile_Display - */ - function makeDisplay() - { - return new Net_UserAgent_Mobile_Display(null); - } - - // }}} - // {{{ getVendor() - - /** - * returns vendor name - * - * @return string - */ - function getVendor() - { - return $this->_vendor; - } - - // }}} - // {{{ getModelVersion() - - /** - * returns version number of the model - * - * @return string - */ - function getModelVersion() - { - return $this->_modelVersion; - } - - // }}} - // {{{ getBrowserVersion() - - /** - * returns version number of the browser - * - * @return string - */ - function getBrowserVersion() - { - return $this->_browserVersion; - } - - // }}} - // {{{ getCacheSize() - - /** - * returns cache size as killobytes unit - * - * @return integer - */ - function getCacheSize() - { - return $this->_cacheSize; - } - - // }}} - // {{{ getCarrierShortName() - - /** - * returns the short name of the carrier - * - * @return string - */ - function getCarrierShortName() - { - return 'W'; - } - - // }}} - // {{{ getCarrierLongName() - - /** - * returns the long name of the carrier - * - * @return string - */ - function getCarrierLongName() - { - return 'WILLCOM'; - } - - // }}} - // {{{ isWillcom() - - /** - * Returns whether the agent is Willcom or not. - * - * @return boolean - * @since Method available since Release 0.31.0 - */ - function isWillcom() - { - return true; - } - - /**#@-*/ - - /**#@+ - * @access private - */ - - /**#@-*/ - - // }}} -} - -// }}} - -/* - * Local Variables: - * mode: php - * coding: iso-8859-1 - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * indent-tabs-mode: nil - * End: - */ diff --git a/data/module/PEAR.php b/data/module/PEAR.php deleted file mode 100644 index b955a8ec08..0000000000 --- a/data/module/PEAR.php +++ /dev/null @@ -1,1072 +0,0 @@ - - * @author Stig Bakken - * @author Tomas V.V.Cox - * @author Greg Beaver - * @copyright 1997-2010 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: commit 01071ee7b71e4d38c4e96fdf0ae5e411841eaec7 - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/**#@+ - * ERROR constants - */ -define('PEAR_ERROR_RETURN', 1); -define('PEAR_ERROR_PRINT', 2); -define('PEAR_ERROR_TRIGGER', 4); -define('PEAR_ERROR_DIE', 8); -define('PEAR_ERROR_CALLBACK', 16); -/** - * WARNING: obsolete - * @deprecated - */ -define('PEAR_ERROR_EXCEPTION', 32); -/**#@-*/ -define('PEAR_ZE2', (function_exists('version_compare') && - version_compare(zend_version(), "2-dev", "ge"))); - -if (substr(PHP_OS, 0, 3) == 'WIN') { - define('OS_WINDOWS', true); - define('OS_UNIX', false); - define('PEAR_OS', 'Windows'); -} else { - define('OS_WINDOWS', false); - define('OS_UNIX', true); - define('PEAR_OS', 'Unix'); // blatant assumption -} - -$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; -$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; -$GLOBALS['_PEAR_destructor_object_list'] = array(); -$GLOBALS['_PEAR_shutdown_funcs'] = array(); -$GLOBALS['_PEAR_error_handler_stack'] = array(); - -@ini_set('track_errors', true); - -/** - * Base class for other PEAR classes. Provides rudimentary - * emulation of destructors. - * - * If you want a destructor in your class, inherit PEAR and make a - * destructor method called _yourclassname (same name as the - * constructor, but with a "_" prefix). Also, in your constructor you - * have to call the PEAR constructor: $this->PEAR();. - * The destructor method will be called without parameters. Note that - * at in some SAPI implementations (such as Apache), any output during - * the request shutdown (in which destructors are called) seems to be - * discarded. If you need to get any debug information from your - * destructor, use error_log(), syslog() or something similar. - * - * IMPORTANT! To use the emulated destructors you need to create the - * objects by reference: $obj =& new PEAR_child; - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Greg Beaver - * @copyright 1997-2006 The PHP Group - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/PEAR - * @see PEAR_Error - * @since Class available since PHP 4.0.2 - * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear - */ -class PEAR -{ - /** - * Whether to enable internal debug messages. - * - * @var bool - * @access private - */ - var $_debug = false; - - /** - * Default error mode for this object. - * - * @var int - * @access private - */ - var $_default_error_mode = null; - - /** - * Default error options used for this object when error mode - * is PEAR_ERROR_TRIGGER. - * - * @var int - * @access private - */ - var $_default_error_options = null; - - /** - * Default error handler (callback) for this object, if error mode is - * PEAR_ERROR_CALLBACK. - * - * @var string - * @access private - */ - var $_default_error_handler = ''; - - /** - * Which class to use for error objects. - * - * @var string - * @access private - */ - var $_error_class = 'PEAR_Error'; - - /** - * An array of expected errors. - * - * @var array - * @access private - */ - var $_expected_errors = array(); - - /** - * Constructor. Registers this object in - * $_PEAR_destructor_object_list for destructor emulation if a - * destructor object exists. - * - * @param string $error_class (optional) which class to use for - * error objects, defaults to PEAR_Error. - * @access public - * @return void - */ - function PEAR($error_class = null) - { - $classname = strtolower(get_class($this)); - if ($this->_debug) { - print "PEAR constructor called, class=$classname\n"; - } - - if ($error_class !== null) { - $this->_error_class = $error_class; - } - - while ($classname && strcasecmp($classname, "pear")) { - $destructor = "_$classname"; - if (method_exists($this, $destructor)) { - global $_PEAR_destructor_object_list; - $_PEAR_destructor_object_list[] = &$this; - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; - } - break; - } else { - $classname = get_parent_class($classname); - } - } - } - - /** - * Destructor (the emulated type of...). Does nothing right now, - * but is included for forward compatibility, so subclass - * destructors should always call it. - * - * See the note in the class desciption about output from - * destructors. - * - * @access public - * @return void - */ - function _PEAR() { - if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); - } - } - - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; - } - - return $properties[$class][$var]; - } - - /** - * Use this function to register a shutdown method for static - * classes. - * - * @access public - * @param mixed $func The function name (or array of class/method) to call - * @param mixed $args The arguments to pass to the function - * @return void - */ - function registerShutdownFunc($func, $args = array()) - { - // if we are called statically, there is a potential - // that no shutdown func is registered. Bug #6445 - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; - } - $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); - } - - /** - * Tell whether a value is a PEAR error. - * - * @param mixed $data the value to test - * @param int $code if $data is an error object, return true - * only if $code is a string and - * $obj->getMessage() == $code or - * $code is an integer and $obj->getCode() == $code - * @access public - * @return bool true if parameter is an error - */ - function isError($data, $code = null) - { - if (!is_object($data)) { - return false; - } - if (!is_a($data, 'PEAR_Error')) { - return false; - } - - if (is_null($code)) { - return true; - } elseif (is_string($code)) { - return $data->getMessage() == $code; - } - - return $data->getCode() == $code; - } - - /** - * Sets how errors generated by this object should be handled. - * Can be invoked both in objects and statically. If called - * statically, setErrorHandling sets the default behaviour for all - * PEAR objects. If called in an object, setErrorHandling sets - * the default behaviour for that object. - * - * @param int $mode - * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. - * - * @param mixed $options - * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one - * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * - * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected - * to be the callback function or method. A callback - * function is a string with the name of the function, a - * callback method is an array of two elements: the element - * at index 0 is the object, and the element at index 1 is - * the name of the method to call in the object. - * - * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is - * a printf format string used when printing the error - * message. - * - * @access public - * @return void - * @see PEAR_ERROR_RETURN - * @see PEAR_ERROR_PRINT - * @see PEAR_ERROR_TRIGGER - * @see PEAR_ERROR_DIE - * @see PEAR_ERROR_CALLBACK - * @see PEAR_ERROR_EXCEPTION - * - * @since PHP 4.0.5 - */ - function setErrorHandling($mode = null, $options = null) - { - if (isset($this) && is_a($this, 'PEAR')) { - $setmode = &$this->_default_error_mode; - $setoptions = &$this->_default_error_options; - } else { - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - } - - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; - - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } - } - - /** - * This method is used to tell which errors you expect to get. - * Expected errors are always returned with error mode - * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, - * and this method pushes a new element onto it. The list of - * expected errors are in effect until they are popped off the - * stack with the popExpect() method. - * - * Note that this method can not be called statically - * - * @param mixed $code a single error code or an array of error codes to expect - * - * @return int the new depth of the "expected errors" stack - * @access public - */ - function expectError($code = '*') - { - if (is_array($code)) { - array_push($this->_expected_errors, $code); - } else { - array_push($this->_expected_errors, array($code)); - } - return count($this->_expected_errors); - } - - /** - * This method pops one element off the expected error codes - * stack. - * - * @return array the list of error codes that were popped - */ - function popExpect() - { - return array_pop($this->_expected_errors); - } - - /** - * This method checks unsets an error code if available - * - * @param mixed error code - * @return bool true if the error code was unset, false otherwise - * @access private - * @since PHP 4.3.0 - */ - function _checkDelExpect($error_code) - { - $deleted = false; - foreach ($this->_expected_errors as $key => $error_array) { - if (in_array($error_code, $error_array)) { - unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); - $deleted = true; - } - - // clean up empty arrays - if (0 == count($this->_expected_errors[$key])) { - unset($this->_expected_errors[$key]); - } - } - - return $deleted; - } - - /** - * This method deletes all occurences of the specified element from - * the expected error codes stack. - * - * @param mixed $error_code error code that should be deleted - * @return mixed list of error codes that were deleted or error - * @access public - * @since PHP 4.3.0 - */ - function delExpect($error_code) - { - $deleted = false; - if ((is_array($error_code) && (0 != count($error_code)))) { - // $error_code is a non-empty array here; we walk through it trying - // to unset all values - foreach ($error_code as $key => $error) { - $deleted = $this->_checkDelExpect($error) ? true : false; - } - - return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } elseif (!empty($error_code)) { - // $error_code comes alone, trying to unset it - if ($this->_checkDelExpect($error_code)) { - return true; - } - - return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } - - // $error_code is empty - return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME - } - - /** - * This method is a wrapper that returns an instance of the - * configured error class with this object's default error - * handling applied. If the $mode and $options parameters are not - * specified, the object's defaults are used. - * - * @param mixed $message a text error message or a PEAR error object - * - * @param int $code a numeric error code (it is up to your class - * to define these if you want to use codes) - * - * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. - * - * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter - * specifies the PHP-internal error level (one of - * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * If $mode is PEAR_ERROR_CALLBACK, this - * parameter specifies the callback function or - * method. In other error modes this parameter - * is ignored. - * - * @param string $userinfo If you need to pass along for example debug - * information, this parameter is meant for that. - * - * @param string $error_class The returned error object will be - * instantiated from this class, if specified. - * - * @param bool $skipmsg If true, raiseError will only pass error codes, - * the error message parameter will be dropped. - * - * @access public - * @return object a PEAR error object - * @see PEAR::setErrorHandling - * @since PHP 4.0.5 - */ - function &raiseError($message = null, - $code = null, - $mode = null, - $options = null, - $userinfo = null, - $error_class = null, - $skipmsg = false) - { - // The error is yet a PEAR error object - if (is_object($message)) { - $code = $message->getCode(); - $userinfo = $message->getUserInfo(); - $error_class = $message->getType(); - $message->error_message_prefix = ''; - $message = $message->getMessage(); - - // Make sure right data gets passed. - $r = new ReflectionClass($error_class); - $c = $r->getConstructor(); - $p = array_shift($c->getParameters()); - $skipmsg = ($p->getName() != 'message'); - } - - if ( - isset($this) && - isset($this->_expected_errors) && - count($this->_expected_errors) > 0 && - count($exp = end($this->_expected_errors)) - ) { - if ($exp[0] == "*" || - (is_int(reset($exp)) && in_array($code, $exp)) || - (is_string(reset($exp)) && in_array($message, $exp)) - ) { - $mode = PEAR_ERROR_RETURN; - } - } - - // No mode given, try global ones - if ($mode === null) { - // Class error handler - if (isset($this) && isset($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - $options = $this->_default_error_options; - // Global error handler - } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { - $mode = $GLOBALS['_PEAR_default_error_mode']; - $options = $GLOBALS['_PEAR_default_error_options']; - } - } - - if ($error_class !== null) { - $ec = $error_class; - } elseif (isset($this) && isset($this->_error_class)) { - $ec = $this->_error_class; - } else { - $ec = 'PEAR_Error'; - } - - if (intval(PHP_VERSION) < 5) { - // little non-eval hack to fix bug #12147 - include 'PEAR/FixPHP5PEARWarnings.php'; - return $a; - } - - if ($skipmsg) { - $a = new $ec($code, $mode, $options, $userinfo); - } else { - $a = new $ec($message, $code, $mode, $options, $userinfo); - } - - return $a; - } - - /** - * Simpler form of raiseError with fewer options. In most cases - * message, code and userinfo are enough. - * - * @param mixed $message a text error message or a PEAR error object - * - * @param int $code a numeric error code (it is up to your class - * to define these if you want to use codes) - * - * @param string $userinfo If you need to pass along for example debug - * information, this parameter is meant for that. - * - * @access public - * @return object a PEAR error object - * @see PEAR::raiseError - */ - function &throwError($message = null, $code = null, $userinfo = null) - { - if (isset($this) && is_a($this, 'PEAR')) { - $a = &$this->raiseError($message, $code, null, null, $userinfo); - return $a; - } - - $a = &PEAR::raiseError($message, $code, null, null, $userinfo); - return $a; - } - - function staticPushErrorHandling($mode, $options = null) - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - $stack[] = array($def_mode, $def_options); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $def_mode = $mode; - $def_options = $options; - break; - - case PEAR_ERROR_CALLBACK: - $def_mode = $mode; - // class/object method callback - if (is_callable($options)) { - $def_options = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } - $stack[] = array($mode, $options); - return true; - } - - function staticPopErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; - - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } - return true; - } - - /** - * Push a new error handler on top of the error handler options stack. With this - * you can easily override the actual error handler for some code and restore - * it later with popErrorHandling. - * - * @param mixed $mode (same as setErrorHandling) - * @param mixed $options (same as setErrorHandling) - * - * @return bool Always true - * - * @see PEAR::setErrorHandling - */ - function pushErrorHandling($mode, $options = null) - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { - $def_mode = &$this->_default_error_mode; - $def_options = &$this->_default_error_options; - } else { - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - } - $stack[] = array($def_mode, $def_options); - - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); - } else { - PEAR::setErrorHandling($mode, $options); - } - $stack[] = array($mode, $options); - return true; - } - - /** - * Pop the last error handler used - * - * @return bool Always true - * - * @see PEAR::pushErrorHandling - */ - function popErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); - } else { - PEAR::setErrorHandling($mode, $options); - } - return true; - } - - /** - * OS independant PHP extension load. Remember to take care - * on the correct extension name for case sensitive OSes. - * - * @param string $ext The extension name - * @return bool Success or not on the dl() call - */ - function loadExtension($ext) - { - if (extension_loaded($ext)) { - return true; - } - - // if either returns true dl() will produce a FATAL error, stop that - if ( - function_exists('dl') === false || - ini_get('enable_dl') != 1 || - ini_get('safe_mode') == 1 - ) { - return false; - } - - if (OS_WINDOWS) { - $suffix = '.dll'; - } elseif (PHP_OS == 'HP-UX') { - $suffix = '.sl'; - } elseif (PHP_OS == 'AIX') { - $suffix = '.a'; - } elseif (PHP_OS == 'OSX') { - $suffix = '.bundle'; - } else { - $suffix = '.so'; - } - - return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); - } -} - -if (PEAR_ZE2) { - include_once 'PEAR5.php'; -} - -function _PEAR_call_destructors() -{ - global $_PEAR_destructor_object_list; - if (is_array($_PEAR_destructor_object_list) && - sizeof($_PEAR_destructor_object_list)) - { - reset($_PEAR_destructor_object_list); - if (PEAR_ZE2) { - $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); - } else { - $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); - } - - if ($destructLifoExists) { - $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); - } - - while (list($k, $objref) = each($_PEAR_destructor_object_list)) { - $classname = get_class($objref); - while ($classname) { - $destructor = "_$classname"; - if (method_exists($objref, $destructor)) { - $objref->$destructor(); - break; - } else { - $classname = get_parent_class($classname); - } - } - } - // Empty the object list to ensure that destructors are - // not called more than once. - $_PEAR_destructor_object_list = array(); - } - - // Now call the shutdown functions - if ( - isset($GLOBALS['_PEAR_shutdown_funcs']) && - is_array($GLOBALS['_PEAR_shutdown_funcs']) && - !empty($GLOBALS['_PEAR_shutdown_funcs']) - ) { - foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { - call_user_func_array($value[0], $value[1]); - } - } -} - -/** - * Standard PEAR error class for PHP 4 - * - * This class is supserseded by {@link PEAR_Exception} in PHP 5 - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Gregory Beaver - * @copyright 1997-2006 The PHP Group - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/manual/en/core.pear.pear-error.php - * @see PEAR::raiseError(), PEAR::throwError() - * @since Class available since PHP 4.0.2 - */ -class PEAR_Error -{ - var $error_message_prefix = ''; - var $mode = PEAR_ERROR_RETURN; - var $level = E_USER_NOTICE; - var $code = -1; - var $message = ''; - var $userinfo = ''; - var $backtrace = null; - - /** - * PEAR_Error constructor - * - * @param string $message message - * - * @param int $code (optional) error code - * - * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, - * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION - * - * @param mixed $options (optional) error level, _OR_ in the case of - * PEAR_ERROR_CALLBACK, the callback function or object/method - * tuple. - * - * @param string $userinfo (optional) additional user/debug info - * - * @access public - * - */ - function PEAR_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - if ($mode === null) { - $mode = PEAR_ERROR_RETURN; - } - $this->message = $message; - $this->code = $code; - $this->mode = $mode; - $this->userinfo = $userinfo; - - if (PEAR_ZE2) { - $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); - } else { - $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); - } - - if (!$skiptrace) { - $this->backtrace = debug_backtrace(); - if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { - unset($this->backtrace[0]['object']); - } - } - - if ($mode & PEAR_ERROR_CALLBACK) { - $this->level = E_USER_NOTICE; - $this->callback = $options; - } else { - if ($options === null) { - $options = E_USER_NOTICE; - } - - $this->level = $options; - $this->callback = null; - } - - if ($this->mode & PEAR_ERROR_PRINT) { - if (is_null($options) || is_int($options)) { - $format = "%s"; - } else { - $format = $options; - } - - printf($format, $this->getMessage()); - } - - if ($this->mode & PEAR_ERROR_TRIGGER) { - trigger_error($this->getMessage(), $this->level); - } - - if ($this->mode & PEAR_ERROR_DIE) { - $msg = $this->getMessage(); - if (is_null($options) || is_int($options)) { - $format = "%s"; - if (substr($msg, -1) != "\n") { - $msg .= "\n"; - } - } else { - $format = $options; - } - die(sprintf($format, $msg)); - } - - if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { - call_user_func($this->callback, $this); - } - - if ($this->mode & PEAR_ERROR_EXCEPTION) { - trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); - eval('$e = new Exception($this->message, $this->code);throw($e);'); - } - } - - /** - * Get the error mode from an error object. - * - * @return int error mode - * @access public - */ - function getMode() - { - return $this->mode; - } - - /** - * Get the callback function/method from an error object. - * - * @return mixed callback function or object/method array - * @access public - */ - function getCallback() - { - return $this->callback; - } - - /** - * Get the error message from an error object. - * - * @return string full error message - * @access public - */ - function getMessage() - { - return ($this->error_message_prefix . $this->message); - } - - /** - * Get error code from an error object - * - * @return int error code - * @access public - */ - function getCode() - { - return $this->code; - } - - /** - * Get the name of this error/exception. - * - * @return string error/exception name (type) - * @access public - */ - function getType() - { - return get_class($this); - } - - /** - * Get additional user-supplied information. - * - * @return string user-supplied information - * @access public - */ - function getUserInfo() - { - return $this->userinfo; - } - - /** - * Get additional debug information supplied by the application. - * - * @return string debug information - * @access public - */ - function getDebugInfo() - { - return $this->getUserInfo(); - } - - /** - * Get the call backtrace from where the error was generated. - * Supported with PHP 4.3.0 or newer. - * - * @param int $frame (optional) what frame to fetch - * @return array Backtrace, or NULL if not available. - * @access public - */ - function getBacktrace($frame = null) - { - if (defined('PEAR_IGNORE_BACKTRACE')) { - return null; - } - if ($frame === null) { - return $this->backtrace; - } - return $this->backtrace[$frame]; - } - - function addUserInfo($info) - { - if (empty($this->userinfo)) { - $this->userinfo = $info; - } else { - $this->userinfo .= " ** $info"; - } - } - - function __toString() - { - return $this->getMessage(); - } - - /** - * Make a string representation of this object. - * - * @return string a string with an object summary - * @access public - */ - function toString() - { - $modes = array(); - $levels = array(E_USER_NOTICE => 'notice', - E_USER_WARNING => 'warning', - E_USER_ERROR => 'error'); - if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_array($this->callback)) { - $callback = (is_object($this->callback[0]) ? - strtolower(get_class($this->callback[0])) : - $this->callback[0]) . '::' . - $this->callback[1]; - } else { - $callback = $this->callback; - } - return sprintf('[%s: message="%s" code=%d mode=callback '. - 'callback=%s prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - $callback, $this->error_message_prefix, - $this->userinfo); - } - if ($this->mode & PEAR_ERROR_PRINT) { - $modes[] = 'print'; - } - if ($this->mode & PEAR_ERROR_TRIGGER) { - $modes[] = 'trigger'; - } - if ($this->mode & PEAR_ERROR_DIE) { - $modes[] = 'die'; - } - if ($this->mode & PEAR_ERROR_RETURN) { - $modes[] = 'return'; - } - return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. - 'prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - implode("|", $modes), $levels[$this->level], - $this->error_message_prefix, - $this->userinfo); - } -} - -/* - * Local Variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/data/module/PEAR5.php b/data/module/PEAR5.php deleted file mode 100644 index 5cee090351..0000000000 --- a/data/module/PEAR5.php +++ /dev/null @@ -1,33 +0,0 @@ - | -// +-----------------------------------------------------------------------+ -// -// $Id$ -// -// Search and Replace Utility -// - -/** - * Search and Replace Utility - * - * - * @author Richard Heyes - * @version 1.0 - * @package File - */ -class File_SearchReplace -{ - - // {{{ Properties (All private) - - var $find; - var $replace; - var $files; - var $directories; - var $include_subdir; - var $ignore_lines; - var $ignore_sep; - var $occurences; - var $search_function; - var $php5; - var $last_error; - - // }}} - // {{{ Constructor - - /** - * Sets up the object - * - * @access public - * @param string $find The string/regex to find. - * @param string $replace The string/regex to replace $find with. - * @param array $files The file(s) to perform this operation on. - * @param array $directories (optional) The directories to perform this operation on. - * @param bool $include_subdir If performing on directories, whether to traverse subdirectories. - * @param array $ignore_lines Ignore lines beginning with any of the strings in this array. This - * feature only works with the "normal" search. - */ - function File_SearchReplace($find, $replace, $files, $directories = '', $include_subdir = TRUE, $ignore_lines = array()) - { - - $this->find = $find; - $this->replace = $replace; - $this->files = $files; - $this->directories = $directories; - $this->include_subdir = $include_subdir; - $this->ignore_lines = (array) $ignore_lines; - - $this->occurences = 0; - $this->search_function = 'search'; - $this->php5 = (substr(PHP_VERSION, 0, 1) == 5) ? TRUE : FALSE; - $this->last_error = ''; - - } - - // }}} - // {{{ getNumOccurences() - - /** - * Accessor to return the number of occurences found. - * - * @access public - * @return int Number of occurences found. - */ - function getNumOccurences() - { - return $this->occurences; - } - - // }}} - // {{{ getLastError() - - /** - * Accessor for retrieving last error. - * - * @access public - * @return string The last error that occurred, if any. - */ - function getLastError() - { - return $this->last_error; - } - - // }}} - // {{{ setFind() - - /** - * Accessor for setting find variable. - * - * @access public - * @param string $find The string/regex to find. - */ - function setFind($find) - { - $this->find = $find; - } - - // }}} - // {{{ setReplace() - - /** - * Accessor for setting replace variable. - * - * @access public - * @param string $replace The string/regex to replace the find string/regex with. - */ - function setReplace($replace) - { - $this->replace = $replace; - } - - // }}} - // {{{ setFiles() - - /** - * Accessor for setting files variable. - * - * @access public - * @param array $files The file(s) to perform this operation on. - */ - function setFiles($files) - { - $this->files = $files; - } - - // }}} - // {{{ setDirectories() - - /** - * Accessor for setting directories variable. - * - * @access public - * @param array $directories The directories to perform this operation on. - */ - function setDirectories($directories) - { - $this->directories = $directories; - } - - // }}} - // {{{ setIncludeSubdir - - /** - * Accessor for setting include_subdir variable. - * - * @access public - * @param bool $include_subdir Whether to traverse subdirectories or not. - */ - function setIncludeSubdir($include_subdir) - { - $this->include_subdir = $include_subdir; - } - - // }}} - // {{{ setIgnoreLines() - - /** - * Accessor for setting ignore_lines variable. - * - * @access public - * @param array $ignore_lines Ignore lines beginning with any of the strings in this array. This - * feature only works with the "normal" search. - */ - function setIgnoreLines($ignore_lines) - { - $this->ignore_lines = $ignore_lines; - } - - // }}} - // {{{ setSearchFunction() - - /** - * Function to determine which search function is used. - * - * @access public - * @param string The search function that should be used. Can be any one of: - * normal - Default search. Goes line by line. Ignore lines feature only works with this type. - * quick - Uses str_replace for straight replacement throughout file. Quickest of the lot. - * preg - Uses preg_replace(), so any regex valid with this function is valid here. - * ereg - Uses ereg_replace(), so any regex valid with this function is valid here. - */ - function setSearchFunction($search_function) - { - switch($search_function) { - case 'normal': $this->search_function = 'search'; - return TRUE; - break; - - case 'quick' : $this->search_function = 'quickSearch'; - return TRUE; - break; - - case 'preg' : $this->search_function = 'pregSearch'; - return TRUE; - break; - - case 'ereg' : $this->search_function = 'eregSearch'; - return TRUE; - break; - - default : $this->last_error = 'Invalid search function specified'; - return FALSE; - break; - } - } - - // }}} - // {{{ search() - - /** - * Default ("normal") search routine. - * - * @access private - * @param string $filename The filename to search and replace upon. - * @return array Will return an array containing the new file contents and the number of occurences. - * Will return FALSE if there are no occurences. - */ - function search($filename) - { - $occurences = 0; - $file_array = file($filename); - - if (empty($this->ignore_lines) && $this->php5) { // PHP5 acceleration - $file_array = str_replace($this->find, $this->replace, $file_array, $occurences); - - } else { // str_replace() doesn't return number of occurences in PHP4 - // so we need to count them manually and/or filter strings - $ignore_lines_num = count($this->ignore_lines); - - // just for the sake of catching occurences - $local_find = array_values((array) $this->find); - $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; - - for ($i=0; $i < count($file_array); $i++) { - - if ($ignore_lines_num > 0) { - for ($j=0; $j < $ignore_lines_num; $j++) { - if (substr($file_array[$i],0,strlen($this->ignore_lines[$j])) == $this->ignore_lines[$j]) continue 2; - } - } - - if ($this->php5) { - $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i], $counted); - $occurences += $counted; - } else { - foreach ($local_find as $fk => $ff) { - $occurences += substr_count($file_array[$i], $ff); - if (!is_array($local_replace)) { - $fr = $local_replace; - } else { - $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; - } - $file_array[$i] = str_replace($ff, $fr, $file_array[$i]); - } - } - } - - } - if ($occurences > 0) $return = array($occurences, implode('', $file_array)); else $return = FALSE; - return $return; - - } - - // }}} - // {{{ quickSearch() - - /** - * Quick search routine. - * - * @access private - * @param string $filename The filename to search and replace upon. - * @return array Will return an array containing the new file contents and the number of occurences. - * Will return FALSE if there are no occurences. - */ - function quickSearch($filename) - { - - clearstatcache(); - - $file = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); - $local_find = array_values((array) $this->find); - $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; - - $occurences = 0; - - // logic is the same as in str_replace function with one exception: - // if is a string and is an array - substitution - // is done from the first element of array. str_replace in this case - // usualy fails with notice and returns "ArrayArrayArray..." string - // (this exclusive logic of SearchReplace will not work for php5, though, - // because I haven't decided yet whether it is bug or feature) - - if ($this->php5) { - $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i], $counted); - $occurences += $counted; - } else { - foreach ($local_find as $fk => $ff) { - $occurences += substr_count($file, $ff); - if (!is_array($local_replace)) { - $fr = $local_replace; - } else { - $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; - } - $file = str_replace($ff, $fr, $file); - } - } - - if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; - return $return; - - } - - // }}} - // {{{ pregSearch() - - /** - * Preg search routine. - * - * @access private - * @param string $filename The filename to search and replace upon. - * @return array Will return an array containing the new file contents and the number of occurences. - * Will return FALSE if there are no occurences. - */ - function pregSearch($filename) - { - - clearstatcache(); - - $file = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); - $local_find = array_values((array) $this->find); - $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; - - $occurences = 0; - - foreach($local_find as $fk => $ff) { - $occurences += preg_match_all($ff, $file, $matches); - if (!is_array($local_replace)) { - $fr = $local_replace; - } else { - $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; - } - $file = preg_replace($ff, $fr, $file); - } - - if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; - return $return; - - } - - // }}} - // {{{ eregSearch() - - /** - * Ereg search routine. - * - * @access private - * @param string $filename The filename to search and replace upon. - * @return array Will return an array containing the new file contents and the number of occurences. - * Will return FALSE if there are no occurences. - */ - function eregSearch($filename) - { - - clearstatcache(); - - $file = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); - $local_find = array_values((array) $this->find); - $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; - - $occurences = 0; - - foreach($local_find as $fk => $ff) { - $occurences += count(split($ff, $file)) - 1; - if (!is_array($local_replace)) { - $fr = $local_replace; - } else { - $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; - } - $file = ereg_replace($ff, $fr, $file); - } - - if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; - return $return; - - } - - // }}} - // {{{ writeout() - - /** - * Function to writeout the file contents. - * - * @access private - * @param string $filename The filename of the file to write. - * @param string $contents The contents to write to the file. - */ - function writeout($filename, $contents) - { - - if ($fp = @fopen($filename, 'w')) { - flock($fp,2); - fwrite($fp, $contents); - flock($fp,3); - fclose($fp); - } else { - $this->last_error = 'Could not open file: '.$filename; - } - - } - - // }}} - // {{{ doFiles() - - /** - * Function called by doSearch() to go through any files that need searching. - * - * @access private - * @param string $ser_func The search function to use. - */ - function doFiles($ser_func) - { - if (!is_array($this->files)) $this->files = explode(',', $this->files); - for ($i=0; $ifiles); $i++) { - if ($this->files[$i] == '.' OR $this->files[$i] == '..') continue; - if (is_dir($this->files[$i]) == TRUE) continue; - $newfile = $this->$ser_func($this->files[$i]); - if (is_array($newfile) == TRUE){ - $this->writeout($this->files[$i], $newfile[1]); - $this->occurences += $newfile[0]; - } - } - } - - // }}} - // {{{ doDirectories() - - /** - * Function called by doSearch() to go through any directories that need searching. - * - * @access private - * @param string $ser_func The search function to use. - */ - function doDirectories($ser_func) - { - if (!is_array($this->directories)) $this->directories = explode(',', $this->directories); - for ($i=0; $idirectories); $i++) { - $dh = opendir($this->directories[$i]); - while ($file = readdir($dh)) { - if ($file == '.' OR $file == '..') continue; - - if (is_dir($this->directories[$i].$file) == TRUE) { - if ($this->include_subdir == TRUE) { - $this->directories[] = $this->directories[$i].$file.'/'; - continue; - } else { - continue; - } - } - - $newfile = $this->$ser_func($this->directories[$i].$file); - if (is_array($newfile) == TRUE) { - $this->writeout($this->directories[$i].$file, $newfile[1]); - $this->occurences += $newfile[0]; - } - } - } - } - - // }}} - // {{{ doSearch() - - /** - * This starts the search/replace off. The behavior of this function will likely - * to be changed in future versions to work in read only mode. If you want to do - * actual replace with writing files - use doReplace method instead. - * - * @access public - */ - function doSearch() - { - $this->doReplace(); - } - - // }}} - // {{{ doReplace() - - /** - * This starts the search/replace off. Call this to do the replace. - * First do whatever files are specified, and/or if directories are specified, - * do those too. - * - * @access public - */ - function doReplace() - { - $this->occurences = 0; - if ($this->find != '') { - if ((is_array($this->files) AND count($this->files) > 0) OR $this->files != '') $this->doFiles($this->search_function); - if ($this->directories != '') $this->doDirectories($this->search_function); - } - } - - // }}} - -} -?> diff --git a/data/module/Services/JSON.php b/data/module/Services/JSON.php deleted file mode 100644 index 8283e7ef77..0000000000 --- a/data/module/Services/JSON.php +++ /dev/null @@ -1,806 +0,0 @@ - - * @author Matt Knapp - * @author Brett Stimmerman - * @copyright 2005 Michal Migurski - * @version CVS: $Id$ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_SLICE', 1); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_STR', 2); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_ARR', 3); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_OBJ', 4); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_CMT', 5); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_LOOSE_TYPE', 16); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_SUPPRESS_ERRORS', 32); - -/** - * Converts to and from JSON format. - * - * Brief example of use: - * - * - * // create a new instance of Services_JSON - * $json = new Services_JSON(); - * - * // convert a complexe value to JSON notation, and send it to the browser - * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); - * $output = $json->encode($value); - * - * print($output); - * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] - * - * // accept incoming POST data, assumed to be in JSON notation - * $input = file_get_contents('php://input', 1000000); - * $value = $json->decode($input); - * - */ -class Services_JSON -{ - /** - * constructs a new JSON instance - * - * @param int $use object behavior flags; combine with boolean-OR - * - * possible values: - * - SERVICES_JSON_LOOSE_TYPE: loose typing. - * "{...}" syntax creates associative arrays - * instead of objects in decode(). - * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. - * Values which can't be encoded (e.g. resources) - * appear as NULL instead of throwing errors. - * By default, a deeply-nested resource will - * bubble up with an error, so all return values - * from encode() should be checked with isError() - */ - function Services_JSON($use = 0) - { - $this->use = $use; - } - - /** - * convert a string from one UTF-16 char to one UTF-8 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf16 UTF-16 character - * @return string UTF-8 character - * @access private - */ - function utf162utf8($utf16) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); - } - - $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); - - switch(true) { - case ((0x7F & $bytes) == $bytes): - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x7F & $bytes); - - case (0x07FF & $bytes) == $bytes: - // return a 2-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xC0 | (($bytes >> 6) & 0x1F)) - . chr(0x80 | ($bytes & 0x3F)); - - case (0xFFFF & $bytes) == $bytes: - // return a 3-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xE0 | (($bytes >> 12) & 0x0F)) - . chr(0x80 | (($bytes >> 6) & 0x3F)) - . chr(0x80 | ($bytes & 0x3F)); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - function utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - function encode($var) - { - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array_map(array($this, 'name_value'), - array_keys($var), - array_values($var)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - } - - // treat it like a regular array - $elements = array_map(array($this, 'encode'), $var); - - foreach($elements as $element) { - if(Services_JSON::isError($element)) { - return $element; - } - } - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = get_object_vars($var); - - $properties = array_map(array($this, 'name_value'), - array_keys($vars), - array_values($vars)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - - default: - return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) - ? 'null' - : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - function name_value($name, $value) - { - $encoded_value = $this->encode($value); - - if(Services_JSON::isError($encoded_value)) { - return $encoded_value; - } - - return $this->encode(strval($name)) . ':' . $encoded_value; - } - - /** - * reduce a string by removing leading and trailing comments and whitespace - * - * @param $str string string value to strip of comments and whitespace - * - * @return string string value stripped of comments and whitespace - * @access private - */ - function reduce_string($str) - { - $str = preg_replace(array( - - // eliminate single line comments in '// ...' form - '#^\s*//(.+)$#m', - - // eliminate multi-line comments in '/* ... */' form, at start of string - '#^\s*/\*(.+)\*/#Us', - - // eliminate multi-line comments in '/* ... */' form, at end of string - '#/\*(.+)\*/\s*$#Us' - - ), '', $str); - - // eliminate extraneous space - return trim($str); - } - - /** - * decodes a JSON string into appropriate variable - * - * @param string $str JSON-formatted string - * - * @return mixed number, boolean, string, array, or object - * corresponding to given JSON input string. - * See argument 1 to Services_JSON() above for object-output behavior. - * Note that decode() always returns strings - * in ASCII or UTF-8 format! - * @access public - */ - function decode($str) - { - $str = $this->reduce_string($str); - - switch (strtolower($str)) { - case 'true': - return true; - - case 'false': - return false; - - case 'null': - return null; - - default: - $m = array(); - - if (is_numeric($str)) { - // Lookie-loo, it's a number - - // This would work on its own, but I'm trying to be - // good about returning integers where appropriate: - // return (float)$str; - - // Return float or int, as appropriate - return ((float)$str == (integer)$str) - ? (integer)$str - : (float)$str; - - } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { - // STRINGS RETURNED IN UTF-8 FORMAT - $delim = substr($str, 0, 1); - $chrs = substr($str, 1, -1); - $utf8 = ''; - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c < $strlen_chrs; ++$c) { - - $substr_chrs_c_2 = substr($chrs, $c, 2); - $ord_chrs_c = ord($chrs{$c}); - - switch (true) { - case $substr_chrs_c_2 == '\b': - $utf8 .= chr(0x08); - ++$c; - break; - case $substr_chrs_c_2 == '\t': - $utf8 .= chr(0x09); - ++$c; - break; - case $substr_chrs_c_2 == '\n': - $utf8 .= chr(0x0A); - ++$c; - break; - case $substr_chrs_c_2 == '\f': - $utf8 .= chr(0x0C); - ++$c; - break; - case $substr_chrs_c_2 == '\r': - $utf8 .= chr(0x0D); - ++$c; - break; - - case $substr_chrs_c_2 == '\\"': - case $substr_chrs_c_2 == '\\\'': - case $substr_chrs_c_2 == '\\\\': - case $substr_chrs_c_2 == '\\/': - if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || - ($delim == "'" && $substr_chrs_c_2 != '\\"')) { - $utf8 .= $chrs{++$c}; - } - break; - - case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): - // single, escaped unicode character - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) - . chr(hexdec(substr($chrs, ($c + 4), 2))); - $utf8 .= $this->utf162utf8($utf16); - $c += 5; - break; - - case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): - $utf8 .= $chrs{$c}; - break; - - case ($ord_chrs_c & 0xE0) == 0xC0: - // characters U-00000080 - U-000007FF, mask 110XXXXX - //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 2); - ++$c; - break; - - case ($ord_chrs_c & 0xF0) == 0xE0: - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 3); - $c += 2; - break; - - case ($ord_chrs_c & 0xF8) == 0xF0: - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 4); - $c += 3; - break; - - case ($ord_chrs_c & 0xFC) == 0xF8: - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 5); - $c += 4; - break; - - case ($ord_chrs_c & 0xFE) == 0xFC: - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 6); - $c += 5; - break; - - } - - } - - return $utf8; - - } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { - // array, or object notation - - if ($str{0} == '[') { - $stk = array(SERVICES_JSON_IN_ARR); - $arr = array(); - } else { - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = array(); - } else { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = new stdClass(); - } - } - - array_push($stk, array('what' => SERVICES_JSON_SLICE, - 'where' => 0, - 'delim' => false)); - - $chrs = substr($str, 1, -1); - $chrs = $this->reduce_string($chrs); - - if ($chrs == '') { - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } else { - return $obj; - - } - } - - //print("\nparsing {$chrs}\n"); - - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c <= $strlen_chrs; ++$c) { - - $top = end($stk); - $substr_chrs_c_2 = substr($chrs, $c, 2); - - if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { - // found a comma that is not inside a string, array, etc., - // OR we've reached the end of the character list - $slice = substr($chrs, $top['where'], ($c - $top['where'])); - array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); - //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - // we are in an array, so just push an element onto the stack - array_push($arr, $this->decode($slice)); - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - // we are in an object, so figure - // out the property name and set an - // element in an associative array, - // for now - $parts = array(); - - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // "name":value pair - $key = $this->decode($parts[1]); - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // name:value pair, where name is unquoted - $key = $parts[1]; - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } - - } - - } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { - // found a quote, and we are not inside a string - array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); - //print("Found start of string at {$c}\n"); - - } elseif (($chrs{$c} == $top['delim']) && - ($top['what'] == SERVICES_JSON_IN_STR) && - ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { - // found a quote, we're in a string, and it's not escaped - // we know that it's not escaped becase there is _not_ an - // odd number of backslashes at the end of the string so far - array_pop($stk); - //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '[') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-bracket, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); - //print("Found start of array at {$c}\n"); - - } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { - // found a right-bracket, and we're in an array - array_pop($stk); - //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '{') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-brace, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); - //print("Found start of object at {$c}\n"); - - } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { - // found a right-brace, and we're in an object - array_pop($stk); - //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($substr_chrs_c_2 == '/*') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a comment start, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); - $c++; - //print("Found start of comment at {$c}\n"); - - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { - // found a comment end, and we're in one now - array_pop($stk); - $c++; - - for ($i = $top['where']; $i <= $c; ++$i) - $chrs = substr_replace($chrs, ' ', $i, 1); - - //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } - - } - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - return $obj; - - } - - } - } - } - - /** - * @todo Ultimately, this should just call PEAR::isError() - */ - function isError($data, $code = null) - { - if (class_exists('pear')) { - return PEAR::isError($data, $code); - } elseif (is_object($data) && (get_class($data) == 'services_json_error' || - is_subclass_of($data, 'services_json_error'))) { - return true; - } - - return false; - } -} - -if (class_exists('PEAR_Error')) { - - class Services_JSON_Error extends PEAR_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - parent::PEAR_Error($message, $code, $mode, $options, $userinfo); - } - } - -} else { - - /** - * @todo Ultimately, this class shall be descended from PEAR_Error - */ - class Services_JSON_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - - } - } - -} - -?> diff --git a/data/module/Services/JSON/LICENSE b/data/module/Services/JSON/LICENSE deleted file mode 100644 index 4ae6bef55d..0000000000 --- a/data/module/Services/JSON/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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. - -THIS SOFTWARE IS PROVIDED ``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 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. diff --git a/data/module/Services/JSON/Test-JSON.php b/data/module/Services/JSON/Test-JSON.php deleted file mode 100644 index 49ac3a4355..0000000000 --- a/data/module/Services/JSON/Test-JSON.php +++ /dev/null @@ -1,521 +0,0 @@ - - * @author Matt Knapp - * @author Brett Stimmerman - * @copyright 2005 Michal Migurski - * @version CVS: $Id$ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - - error_reporting(E_ALL); - - require_once 'PHPUnit.php'; - require_once 'JSON.php'; - - class Services_JSON_EncDec_TestCase extends PHPUnit_TestCase { - - function Services_JSON_EncDec_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json = new Services_JSON(); - - $obj = new stdClass(); - $obj->a_string = '"he":llo}:{world'; - $obj->an_array = array(1, 2, 3); - $obj->obj = new stdClass(); - $obj->obj->a_number = 123; - - $this->obj = $obj; - $this->obj_j = '{"a_string":"\"he\":llo}:{world","an_array":[1,2,3],"obj":{"a_number":123}}'; - $this->obj_d = 'object with properties, nested object and arrays'; - - $this->arr = array(null, true, array(1, 2, 3), "hello\"],[world!"); - $this->arr_j = '[null,true,[1,2,3],"hello\"],[world!"]'; - $this->arr_d = 'array with elements and nested arrays'; - - $this->str1 = 'hello world'; - $this->str1_j = '"hello world"'; - $this->str1_j_ = "'hello world'"; - $this->str1_d = 'hello world'; - $this->str1_d_ = 'hello world, double quotes'; - - $this->str2 = "hello\t\"world\""; - $this->str2_j = '"hello\\t\\"world\\""'; - $this->str2_d = 'hello world, with tab, double-quotes'; - - $this->str3 = "\\\r\n\t\"/"; - $this->str3_j = '"\\\\\\r\\n\\t\\"\\/"'; - $this->str3_d = 'backslash, return, newline, tab, double-quote'; - - $this->str4 = 'héllö wørłd'; - $this->str4_j = '"h\u00e9ll\u00f6 w\u00f8r\u0142d"'; - $this->str4_j_ = '"héllö wørłd"'; - $this->str4_d = 'hello world, with unicode'; - } - - function test_to_JSON() - { - $this->assertEquals('null', $this->json->encode(null), 'type case: null'); - $this->assertEquals('true', $this->json->encode(true), 'type case: boolean true'); - $this->assertEquals('false', $this->json->encode(false), 'type case: boolean false'); - - $this->assertEquals('1', $this->json->encode(1), 'numeric case: 1'); - $this->assertEquals('-1', $this->json->encode(-1), 'numeric case: -1'); - $this->assertEquals('1.000000', $this->json->encode(1.0), 'numeric case: 1.0'); - $this->assertEquals('1.100000', $this->json->encode(1.1), 'numeric case: 1.1'); - - $this->assertEquals($this->str1_j, $this->json->encode($this->str1), "string case: {$this->str1_d}"); - $this->assertEquals($this->str2_j, $this->json->encode($this->str2), "string case: {$this->str2_d}"); - $this->assertEquals($this->str3_j, $this->json->encode($this->str3), "string case: {$this->str3_d}"); - $this->assertEquals($this->str4_j, $this->json->encode($this->str4), "string case: {$this->str4_d}"); - - $this->assertEquals($this->arr_j, $this->json->encode($this->arr), "array case: {$this->arr_d}"); - $this->assertEquals($this->obj_j, $this->json->encode($this->obj), "object case: {$this->obj_d}"); - } - - function test_from_JSON() - { - $this->assertEquals(null, $this->json->decode('null'), 'type case: null'); - $this->assertEquals(true, $this->json->decode('true'), 'type case: boolean true'); - $this->assertEquals(false, $this->json->decode('false'), 'type case: boolean false'); - - $this->assertEquals(1, $this->json->decode('1'), 'numeric case: 1'); - $this->assertEquals(-1, $this->json->decode('-1'), 'numeric case: -1'); - $this->assertEquals(1.0, $this->json->decode('1.0'), 'numeric case: 1.0'); - $this->assertEquals(1.1, $this->json->decode('1.1'), 'numeric case: 1.1'); - - $this->assertEquals(11.0, $this->json->decode('1.1e1'), 'numeric case: 1.1e1'); - $this->assertEquals(11.0, $this->json->decode('1.10e+1'), 'numeric case: 1.10e+1'); - $this->assertEquals(0.11, $this->json->decode('1.1e-1'), 'numeric case: 1.1e-1'); - $this->assertEquals(-0.11, $this->json->decode('-1.1e-1'), 'numeric case: -1.1e-1'); - - $this->assertEquals($this->str1, $this->json->decode($this->str1_j), "string case: {$this->str1_d}"); - $this->assertEquals($this->str1, $this->json->decode($this->str1_j_), "string case: {$this->str1_d_}"); - $this->assertEquals($this->str2, $this->json->decode($this->str2_j), "string case: {$this->str2_d}"); - $this->assertEquals($this->str3, $this->json->decode($this->str3_j), "string case: {$this->str3_d}"); - $this->assertEquals($this->str4, $this->json->decode($this->str4_j), "string case: {$this->str4_d}"); - $this->assertEquals($this->str4, $this->json->decode($this->str4_j_), "string case: {$this->str4_d}"); - - $this->assertEquals($this->arr, $this->json->decode($this->arr_j), "array case: {$this->arr_d}"); - $this->assertEquals($this->obj, $this->json->decode($this->obj_j), "object case: {$this->obj_d}"); - } - - function test_to_then_from_JSON() - { - $this->assertEquals(null, $this->json->decode($this->json->encode(null)), 'type case: null'); - $this->assertEquals(true, $this->json->decode($this->json->encode(true)), 'type case: boolean true'); - $this->assertEquals(false, $this->json->decode($this->json->encode(false)), 'type case: boolean false'); - - $this->assertEquals(1, $this->json->decode($this->json->encode(1)), 'numeric case: 1'); - $this->assertEquals(-1, $this->json->decode($this->json->encode(-1)), 'numeric case: -1'); - $this->assertEquals(1.0, $this->json->decode($this->json->encode(1.0)), 'numeric case: 1.0'); - $this->assertEquals(1.1, $this->json->decode($this->json->encode(1.1)), 'numeric case: 1.1'); - - $this->assertEquals($this->str1, $this->json->decode($this->json->encode($this->str1)), "string case: {$this->str1_d}"); - $this->assertEquals($this->str2, $this->json->decode($this->json->encode($this->str2)), "string case: {$this->str2_d}"); - $this->assertEquals($this->str3, $this->json->decode($this->json->encode($this->str3)), "string case: {$this->str3_d}"); - $this->assertEquals($this->str4, $this->json->decode($this->json->encode($this->str4)), "string case: {$this->str4_d}"); - - $this->assertEquals($this->arr, $this->json->decode($this->json->encode($this->arr)), "array case: {$this->arr_d}"); - $this->assertEquals($this->obj, $this->json->decode($this->json->encode($this->obj)), "object case: {$this->obj_d}"); - } - - function test_from_then_to_JSON() - { - $this->assertEquals('null', $this->json->encode($this->json->decode('null')), 'type case: null'); - $this->assertEquals('true', $this->json->encode($this->json->decode('true')), 'type case: boolean true'); - $this->assertEquals('false', $this->json->encode($this->json->decode('false')), 'type case: boolean false'); - - $this->assertEquals('1', $this->json->encode($this->json->decode('1')), 'numeric case: 1'); - $this->assertEquals('-1', $this->json->encode($this->json->decode('-1')), 'numeric case: -1'); - $this->assertEquals('1.0', $this->json->encode($this->json->decode('1.0')), 'numeric case: 1.0'); - $this->assertEquals('1.1', $this->json->encode($this->json->decode('1.1')), 'numeric case: 1.1'); - - $this->assertEquals($this->str1_j, $this->json->encode($this->json->decode($this->str1_j)), "string case: {$this->str1_d}"); - $this->assertEquals($this->str2_j, $this->json->encode($this->json->decode($this->str2_j)), "string case: {$this->str2_d}"); - $this->assertEquals($this->str3_j, $this->json->encode($this->json->decode($this->str3_j)), "string case: {$this->str3_d}"); - $this->assertEquals($this->str4_j, $this->json->encode($this->json->decode($this->str4_j)), "string case: {$this->str4_d}"); - $this->assertEquals($this->str4_j, $this->json->encode($this->json->decode($this->str4_j_)), "string case: {$this->str4_d}"); - - $this->assertEquals($this->arr_j, $this->json->encode($this->json->decode($this->arr_j)), "array case: {$this->arr_d}"); - $this->assertEquals($this->obj_j, $this->json->encode($this->json->decode($this->obj_j)), "object case: {$this->obj_d}"); - } - } - - class Services_JSON_AssocArray_TestCase extends PHPUnit_TestCase { - - function Services_JSON_AssocArray_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json_l = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $this->json_s = new Services_JSON(); - - $this->arr = array('car1'=> array('color'=> 'tan', 'model' => 'sedan'), - 'car2' => array('color' => 'red', 'model' => 'sports')); - $this->arr_jo = '{"car1":{"color":"tan","model":"sedan"},"car2":{"color":"red","model":"sports"}}'; - $this->arr_d = 'associative array with nested associative arrays'; - - $this->arn = array(0=> array(0=> 'tan\\', 'model\\' => 'sedan'), 1 => array(0 => 'red', 'model' => 'sports')); - $this->arn_ja = '[{"0":"tan\\\\","model\\\\":"sedan"},{"0":"red","model":"sports"}]'; - $this->arn_d = 'associative array with nested associative arrays, and some numeric keys thrown in'; - - $this->arrs = array (1 => 'one', 2 => 'two', 5 => 'five'); - $this->arrs_jo = '{"1":"one","2":"two","5":"five"}'; - $this->arrs_d = 'associative array numeric keys which are not fully populated in a range of 0 to length-1'; - } - - function test_type() - { - $this->assertEquals('array', gettype($this->json_l->decode($this->arn_ja)), "loose type should be array"); - $this->assertEquals('array', gettype($this->json_s->decode($this->arn_ja)), "strict type should be array"); - } - - function test_to_JSON() - { - // both strict and loose JSON should result in an object - $this->assertEquals($this->arr_jo, $this->json_l->encode($this->arr), "array case - loose: {$this->arr_d}"); - $this->assertEquals($this->arr_jo, $this->json_s->encode($this->arr), "array case - strict: {$this->arr_d}"); - - // ...unless the input array has some numeric indeces, in which case the behavior is to degrade to a regular array - $this->assertEquals($this->arn_ja, $this->json_s->encode($this->arn), "array case - strict: {$this->arn_d}"); - - // Test a sparsely populated numerically indexed associative array - $this->assertEquals($this->arrs_jo, $this->json_l->encode($this->arrs), "sparse numeric assoc array: {$this->arrs_d}"); - } - - function test_to_then_from_JSON() - { - // these tests motivated by a bug in which strings that end - // with backslashes followed by quotes were incorrectly decoded. - - foreach(array('\\"', '\\\\"', '\\"\\"', '\\""\\""', '\\\\"\\\\"') as $v) { - $this->assertEquals(array($v), $this->json_l->decode($this->json_l->encode(array($v)))); - $this->assertEquals(array('a' => $v), $this->json_l->decode($this->json_l->encode(array('a' => $v)))); - } - } - } - - class Services_JSON_NestedArray_TestCase extends PHPUnit_TestCase { - - function Services_JSON_NestedArray_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - - $this->str1 = '[{"this":"that"}]'; - $this->arr1 = array(array('this' => 'that')); - - $this->str2 = '{"this":["that"]}'; - $this->arr2 = array('this' => array('that')); - - $this->str3 = '{"params":[{"foo":["1"],"bar":"1"}]}'; - $this->arr3 = array('params' => array(array('foo' => array('1'), 'bar' => '1'))); - - $this->str4 = '{"0": {"foo": "bar", "baz": "winkle"}}'; - $this->arr4 = array('0' => array('foo' => 'bar', 'baz' => 'winkle')); - - $this->str5 = '{"params":[{"options": {"old": [ ], "new": {"0": {"elements": {"old": [], "new": {"0": {"elementName": "aa", "isDefault": false, "elementRank": "0", "priceAdjust": "0", "partNumber": ""}}}, "optionName": "aa", "isRequired": false, "optionDesc": null}}}}]}'; - $this->arr5 = array ( - 'params' => array ( - 0 => array ( - 'options' => - array ( - 'old' => array(), - 'new' => array ( - 0 => array ( - 'elements' => array ( - 'old' => array(), - 'new' => array ( - 0 => array ( - 'elementName' => 'aa', - 'isDefault' => false, - 'elementRank' => '0', - 'priceAdjust' => '0', - 'partNumber' => '', - ), - ), - ), - 'optionName' => 'aa', - 'isRequired' => false, - 'optionDesc' => NULL, - ), - ), - ), - ), - ), - ); - } - - function test_type() - { - $this->assertEquals('array', gettype($this->json->decode($this->str1)), "loose type should be array"); - $this->assertEquals('array', gettype($this->json->decode($this->str2)), "loose type should be array"); - $this->assertEquals('array', gettype($this->json->decode($this->str3)), "loose type should be array"); - } - - function test_from_JSON() - { - $this->assertEquals($this->arr1, $this->json->decode($this->str1), "simple compactly-nested array"); - $this->assertEquals($this->arr2, $this->json->decode($this->str2), "simple compactly-nested array"); - $this->assertEquals($this->arr3, $this->json->decode($this->str3), "complex compactly nested array"); - $this->assertEquals($this->arr4, $this->json->decode($this->str4), "complex compactly nested array"); - $this->assertEquals($this->arr5, $this->json->decode($this->str5), "super complex compactly nested array"); - } - - function _test_from_JSON() - { - $super = '{"params":[{"options": {"old": {}, "new": {"0": {"elements": {"old": {}, "new": {"0": {"elementName": "aa", "isDefault": false, "elementRank": "0", "priceAdjust": "0", "partNumber": ""}}}, "optionName": "aa", "isRequired": false, "optionDesc": ""}}}}]}'; - print("trying {$super}...\n"); - print var_export($this->json->decode($super)); - } - } - - class Services_JSON_Object_TestCase extends PHPUnit_TestCase { - - function Services_JSON_Object_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json_l = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $this->json_s = new Services_JSON(); - - $this->obj_j = '{"a_string":"\"he\":llo}:{world","an_array":[1,2,3],"obj":{"a_number":123}}'; - - $this->obj1->car1->color = 'tan'; - $this->obj1->car1->model = 'sedan'; - $this->obj1->car2->color = 'red'; - $this->obj1->car2->model = 'sports'; - $this->obj1_j = '{"car1":{"color":"tan","model":"sedan"},"car2":{"color":"red","model":"sports"}}'; - $this->obj1_d = 'Object with nested objects'; - } - - function test_type() - { - $this->assertEquals('object', gettype($this->json_s->decode($this->obj_j)), "checking whether decoded type is object"); - $this->assertEquals('array', gettype($this->json_l->decode($this->obj_j)), "checking whether decoded type is array"); - } - - function test_to_JSON() - { - $this->assertEquals($this->obj1_j, $this->json_s->encode($this->obj1), "object - strict: {$this->obj1_d}"); - $this->assertEquals($this->obj1_j, $this->json_l->encode($this->obj1), "object - loose: {$this->obj1_d}"); - } - - function test_from_then_to_JSON() - { - $this->assertEquals($this->obj_j, $this->json_s->encode($this->json_s->decode($this->obj_j)), "object case"); - $this->assertEquals($this->obj_j, $this->json_l->encode($this->json_l->decode($this->obj_j)), "array case"); - } - } - - class Services_JSON_Spaces_Comments_TestCase extends PHPUnit_TestCase { - - function Services_JSON_Spaces_Comments_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - - $this->obj_j = '{"a_string":"\"he\":llo}:{world","an_array":[1,2,3],"obj":{"a_number":123}}'; - - $this->obj_js = '{"a_string": "\"he\":llo}:{world", - "an_array":[1, 2, 3], - "obj": {"a_number":123}}'; - - $this->obj_jc1 = '{"a_string": "\"he\":llo}:{world", - // here is a comment, hoorah - "an_array":[1, 2, 3], - "obj": {"a_number":123}}'; - - $this->obj_jc2 = '/* this here is the sneetch */ "the sneetch" - // this has been the sneetch.'; - - $this->obj_jc3 = '{"a_string": "\"he\":llo}:{world", - /* here is a comment, hoorah */ - "an_array":[1, 2, 3 /* and here is another */], - "obj": {"a_number":123}}'; - - $this->obj_jc4 = '{\'a_string\': "\"he\":llo}:{world", - /* here is a comment, hoorah */ - \'an_array\':[1, 2, 3 /* and here is another */], - "obj": {"a_number":123}}'; - } - - function test_spaces() - { - $this->assertEquals($this->json->decode($this->obj_j), $this->json->decode($this->obj_js), "checking whether notation with spaces works"); - } - - function test_comments() - { - $this->assertEquals($this->json->decode($this->obj_j), $this->json->decode($this->obj_jc1), "checking whether notation with single line comments works"); - $this->assertEquals('the sneetch', $this->json->decode($this->obj_jc2), "checking whether notation with multiline comments works"); - $this->assertEquals($this->json->decode($this->obj_j), $this->json->decode($this->obj_jc3), "checking whether notation with multiline comments works"); - $this->assertEquals($this->json->decode($this->obj_j), $this->json->decode($this->obj_jc4), "checking whether notation with single-quotes and multiline comments works"); - } - } - - class Services_JSON_Empties_TestCase extends PHPUnit_TestCase { - - function Services_JSON_Empties_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json_l = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $this->json_s = new Services_JSON(); - - $this->obj0_j = '{}'; - $this->arr0_j = '[]'; - - $this->obj1_j = '{ }'; - $this->arr1_j = '[ ]'; - - $this->obj2_j = '{ /* comment inside */ }'; - $this->arr2_j = '[ /* comment inside */ ]'; - } - - function test_type() - { - $this->assertEquals('array', gettype($this->json_l->decode($this->arr0_j)), "should be array"); - $this->assertEquals('object', gettype($this->json_s->decode($this->obj0_j)), "should be object"); - - $this->assertEquals(0, count($this->json_l->decode($this->arr0_j)), "should be empty array"); - $this->assertEquals(0, count(get_object_vars($this->json_s->decode($this->obj0_j))), "should be empty object"); - - $this->assertEquals('array', gettype($this->json_l->decode($this->arr1_j)), "should be array, even with space"); - $this->assertEquals('object', gettype($this->json_s->decode($this->obj1_j)), "should be object, even with space"); - - $this->assertEquals(0, count($this->json_l->decode($this->arr1_j)), "should be empty array, even with space"); - $this->assertEquals(0, count(get_object_vars($this->json_s->decode($this->obj1_j))), "should be empty object, even with space"); - - $this->assertEquals('array', gettype($this->json_l->decode($this->arr2_j)), "should be array, despite comment"); - $this->assertEquals('object', gettype($this->json_s->decode($this->obj2_j)), "should be object, despite comment"); - - $this->assertEquals(0, count($this->json_l->decode($this->arr2_j)), "should be empty array, despite comment"); - $this->assertEquals(0, count(get_object_vars($this->json_s->decode($this->obj2_j))), "should be empty object, despite commentt"); - } - } - - class Services_JSON_UnquotedKeys_TestCase extends PHPUnit_TestCase { - - function Services_JSON_UnquotedKeys_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - - $this->arn = array(0=> array(0=> 'tan', 'model' => 'sedan'), 1 => array(0 => 'red', 'model' => 'sports')); - $this->arn_ja = '[{0:"tan","model":"sedan"},{"0":"red",model:"sports"}]'; - $this->arn_d = 'associative array with unquoted keys, nested associative arrays, and some numeric keys thrown in'; - - $this->arrs = array (1 => 'one', 2 => 'two', 5 => 'fi"ve'); - $this->arrs_jo = '{"1":"one",2:"two","5":\'fi"ve\'}'; - $this->arrs_d = 'associative array with unquoted keys, single-quoted values, numeric keys which are not fully populated in a range of 0 to length-1'; - } - - function test_from_JSON() - { - // ...unless the input array has some numeric indeces, in which case the behavior is to degrade to a regular array - $this->assertEquals($this->arn, $this->json->decode($this->arn_ja), "array case - strict: {$this->arn_d}"); - - // Test a sparsely populated numerically indexed associative array - $this->assertEquals($this->arrs, $this->json->decode($this->arrs_jo), "sparse numeric assoc array: {$this->arrs_d}"); - } - } - - class Services_JSON_ErrorSuppression_TestCase extends PHPUnit_TestCase { - - function Services_JSON_ErrorSuppression_TestCase($name) { - $this->PHPUnit_TestCase($name); - } - - function setUp() { - $this->json = new Services_JSON(); - $this->json_ = new Services_JSON(SERVICES_JSON_SUPPRESS_ERRORS); - - $this->res = tmpfile(); - $this->res_j_ = 'null'; - $this->res_d = 'naked resource'; - - $this->arr = array('a', 1, tmpfile()); - $this->arr_j_ = '["a",1,null]'; - $this->arr_d = 'array with string, number and resource'; - - $obj = new stdClass(); - $obj->a_string = '"he":llo}:{world'; - $obj->an_array = array(1, 2, 3); - $obj->resource = tmpfile(); - - $this->obj = $obj; - $this->obj_j_ = '{"a_string":"\"he\":llo}:{world","an_array":[1,2,3],"resource":null}'; - $this->obj_d = 'object with properties, array, and nested resource'; - } - - function test_to_JSON() - { - $this->assertTrue(Services_JSON::isError($this->json->encode($this->res)), "resource case: {$this->res_d}"); - $this->assertTrue(Services_JSON::isError($this->json->encode($this->arr)), "array case: {$this->arr_d}"); - $this->assertTrue(Services_JSON::isError($this->json->encode($this->obj)), "object case: {$this->obj_d}"); - } - - function test_to_JSON_suppressed() - { - $this->assertEquals($this->res_j_, $this->json_->encode($this->res), "resource case: {$this->res_d}"); - $this->assertEquals($this->arr_j_, $this->json_->encode($this->arr), "array case: {$this->arr_d}"); - $this->assertEquals($this->obj_j_, $this->json_->encode($this->obj), "object case: {$this->obj_d}"); - } - } - - $suite = new PHPUnit_TestSuite('Services_JSON_EncDec_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_AssocArray_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_NestedArray_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_Object_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_Spaces_Comments_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_Empties_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_UnquotedKeys_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - - $suite = new PHPUnit_TestSuite('Services_JSON_ErrorSuppression_TestCase'); - $result = PHPUnit::run($suite); - echo $result->toString(); - -?> diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON.html deleted file mode 100644 index 31475788b7..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - Docs For Class Services_JSON - - - - -
-

Class Services_JSON

- - -
-
Description
- -
- -

Converts to and from JSON format.

-

Brief example of use:


1 // create a new instance of Services_JSON
2 $json = new Services_JSON();
3
4 // convert a complexe value to JSON notation, and send it to the browser
5 $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
6 $output = $json->encode($value);
7
8 print($output);
9 // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
10
11 // accept incoming POST data, assumed to be in JSON notation
12 $input = file_get_contents('php://input', 1000000);
13 $value = $json->decode($input);

-

- Located in /JSON.php (line 115) -

- - -

-	
-			
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON - Services_JSON - (int $use) -
- -
- mixed - decode - (string $str) -
- -
- mixed - encode - (mixed $var) -
- -
- void - isError - (mixed $data, [mixed $code = null]) -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON (line 133) -
- - -

constructs a new JSON instance

- -
- Services_JSON - - Services_JSON - - (int $use) -
- -
    -
  • - int - $use:

    object behavior flags; combine with boolean-OR

    possible values:

    • SERVICES_JSON_LOOSE_TYPE: loose typing. - "{...}" syntax creates associative arrays - instead of objects in decode().
    • SERVICES_JSON_SUPPRESS_ERRORS: error suppression. - Values which can't be encoded (e.g. resources) - appear as NULL instead of throwing errors. - By default, a deeply-nested resource will - bubble up with an error, so all return values - from encode() should be checked with isError()

  • -
- - -
- -
- -
- decode (line 484) -
- - -

decodes a JSON string into appropriate variable

-
    -
  • return: number, boolean, string, array, or object corresponding to given JSON input string. See argument 1 to Services_JSON() above for object-output behavior. Note that decode() always returns strings in ASCII or UTF-8 format!
  • -
  • access: public
  • -
- -
- mixed - - decode - - (string $str) -
- -
    -
  • - string - $str: JSON-formatted string
  • -
- - -
- -
- -
- encode (line 237) -
- - -

encodes an arbitrary variable into JSON format

-
    -
  • return: JSON string representation of input var or an error if a problem occurs
  • -
  • access: public
  • -
- -
- mixed - - encode - - (mixed $var) -
- -
    -
  • - mixed - $var: any number, boolean, string, array, or object to be encoded. see argument 1 to Services_JSON() above for array-parsing behavior. if var is a strng, note that encode() always expects it to be in ASCII or UTF-8 format!
  • -
- - -
- -
- -
- isError (line 766) -
- - -
    -
  • todo: Ultimately, this should just call PEAR::isError()
  • -
- -
- void - - isError - - (mixed $data, [mixed $code = null]) -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:25 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_AssocArray_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_AssocArray_TestCase.html deleted file mode 100644 index 4cbc05f433..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_AssocArray_TestCase.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Docs For Class Services_JSON_AssocArray_TestCase - - - - -
-

Class Services_JSON_AssocArray_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 157) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_AssocArray_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_AssocArray_TestCase - Services_JSON_AssocArray_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_to_JSON - () -
- -
- void - test_to_then_from_JSON - () -
- -
- void - test_type - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_AssocArray_TestCase (line 159) -
- - - -
- Services_JSON_AssocArray_TestCase - - Services_JSON_AssocArray_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 163) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_to_JSON (line 187) -
- - - -
- void - - test_to_JSON - - () -
- - - -
- -
- -
- test_to_then_from_JSON (line 200) -
- - - -
- void - - test_to_then_from_JSON - - () -
- - - -
- -
- -
- test_type (line 181) -
- - - -
- void - - test_type - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Empties_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Empties_TestCase.html deleted file mode 100644 index 7184b0a1b5..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Empties_TestCase.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - Docs For Class Services_JSON_Empties_TestCase - - - - -
-

Class Services_JSON_Empties_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 364) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_Empties_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_Empties_TestCase - Services_JSON_Empties_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_type - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_Empties_TestCase (line 366) -
- - - -
- Services_JSON_Empties_TestCase - - Services_JSON_Empties_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 370) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_type (line 384) -
- - - -
- void - - test_type - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_EncDec_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_EncDec_TestCase.html deleted file mode 100644 index 9203d6859a..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_EncDec_TestCase.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - Docs For Class Services_JSON_EncDec_TestCase - - - - -
-

Class Services_JSON_EncDec_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 25) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_EncDec_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_EncDec_TestCase - Services_JSON_EncDec_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_from_JSON - () -
- -
- void - test_from_then_to_JSON - () -
- -
- void - test_to_JSON - () -
- -
- void - test_to_then_from_JSON - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_EncDec_TestCase (line 27) -
- - - -
- Services_JSON_EncDec_TestCase - - Services_JSON_EncDec_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 31) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_from_JSON (line 88) -
- - - -
- void - - test_from_JSON - - () -
- - - -
- -
- -
- test_from_then_to_JSON (line 135) -
- - - -
- void - - test_from_then_to_JSON - - () -
- - - -
- -
- -
- test_to_JSON (line 68) -
- - - -
- void - - test_to_JSON - - () -
- - - -
- -
- -
- test_to_then_from_JSON (line 115) -
- - - -
- void - - test_to_then_from_JSON - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Error.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Error.html deleted file mode 100644 index f607ab6985..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Error.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - Docs For Class Services_JSON_Error - - - - -
-

Class Services_JSON_Error

- - -
-
Description
- -
- -

- Located in /JSON.php (line 781) -

- - -
PEAR_Error
-   |
-   --Services_JSON_Error
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_Error - Services_JSON_Error - ([mixed $message = 'unknown error'], [mixed $code = null], [mixed $mode = null], [mixed $options = null], [mixed $userinfo = null]) -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_Error (line 783) -
- - - -
- Services_JSON_Error - - Services_JSON_Error - - ([mixed $message = 'unknown error'], [mixed $code = null], [mixed $mode = null], [mixed $options = null], [mixed $userinfo = null]) -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_ErrorSuppression_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_ErrorSuppression_TestCase.html deleted file mode 100644 index 5948f96446..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_ErrorSuppression_TestCase.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - Docs For Class Services_JSON_ErrorSuppression_TestCase - - - - -
-

Class Services_JSON_ErrorSuppression_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 434) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_ErrorSuppression_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_ErrorSuppression_TestCase - Services_JSON_ErrorSuppression_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_to_JSON - () -
- -
- void - test_to_JSON_suppressed - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_ErrorSuppression_TestCase (line 436) -
- - - -
- Services_JSON_ErrorSuppression_TestCase - - Services_JSON_ErrorSuppression_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 440) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_to_JSON (line 462) -
- - - -
- void - - test_to_JSON - - () -
- - - -
- -
- -
- test_to_JSON_suppressed (line 469) -
- - - -
- void - - test_to_JSON_suppressed - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_NestedArray_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_NestedArray_TestCase.html deleted file mode 100644 index b2ad40951f..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_NestedArray_TestCase.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Docs For Class Services_JSON_NestedArray_TestCase - - - - -
-

Class Services_JSON_NestedArray_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 212) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_NestedArray_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_NestedArray_TestCase - Services_JSON_NestedArray_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_from_JSON - () -
- -
- void - test_type - () -
- -
- void - _test_from_JSON - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_NestedArray_TestCase (line 214) -
- - - -
- Services_JSON_NestedArray_TestCase - - Services_JSON_NestedArray_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 218) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_from_JSON (line 272) -
- - - -
- void - - test_from_JSON - - () -
- - - -
- -
- -
- test_type (line 265) -
- - - -
- void - - test_type - - () -
- - - -
- -
- -
- _test_from_JSON (line 281) -
- - - -
- void - - _test_from_JSON - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Object_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Object_TestCase.html deleted file mode 100644 index bab4319097..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Object_TestCase.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - Docs For Class Services_JSON_Object_TestCase - - - - -
-

Class Services_JSON_Object_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 289) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_Object_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_Object_TestCase - Services_JSON_Object_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_from_then_to_JSON - () -
- -
- void - test_to_JSON - () -
- -
- void - test_type - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_Object_TestCase (line 291) -
- - - -
- Services_JSON_Object_TestCase - - Services_JSON_Object_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 295) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_from_then_to_JSON (line 321) -
- - - -
- void - - test_from_then_to_JSON - - () -
- - - -
- -
- -
- test_to_JSON (line 315) -
- - - -
- void - - test_to_JSON - - () -
- - - -
- -
- -
- test_type (line 309) -
- - - -
- void - - test_type - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Spaces_Comments_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Spaces_Comments_TestCase.html deleted file mode 100644 index c9e4c2f937..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_Spaces_Comments_TestCase.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - Docs For Class Services_JSON_Spaces_Comments_TestCase - - - - -
-

Class Services_JSON_Spaces_Comments_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 328) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_Spaces_Comments_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_Spaces_Comments_TestCase - Services_JSON_Spaces_Comments_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_comments - () -
- -
- void - test_spaces - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_Spaces_Comments_TestCase (line 330) -
- - - -
- Services_JSON_Spaces_Comments_TestCase - - Services_JSON_Spaces_Comments_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 334) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_comments (line 355) -
- - - -
- void - - test_comments - - () -
- - - -
- -
- -
- test_spaces (line 350) -
- - - -
- void - - test_spaces - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_UnquotedKeys_TestCase.html b/data/module/Services/JSON/doc/Services_JSON/Services_JSON_UnquotedKeys_TestCase.html deleted file mode 100644 index ea2d0b81bf..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/Services_JSON_UnquotedKeys_TestCase.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - Docs For Class Services_JSON_UnquotedKeys_TestCase - - - - -
-

Class Services_JSON_UnquotedKeys_TestCase

- - -
-
Description
- -
- -

- Located in /Test-JSON.php (line 406) -

- - -
PHPUnit_TestCase
-   |
-   --Services_JSON_UnquotedKeys_TestCase
- -
-
- - - - -
-
Method Summary
- -
-
- -
- Services_JSON_UnquotedKeys_TestCase - Services_JSON_UnquotedKeys_TestCase - (mixed $name) -
- -
- void - setUp - () -
- -
- void - test_from_JSON - () -
-
-
-
- - - -
-
Methods
- -
- - -
- -
- Constructor Services_JSON_UnquotedKeys_TestCase (line 408) -
- - - -
- Services_JSON_UnquotedKeys_TestCase - - Services_JSON_UnquotedKeys_TestCase - - (mixed $name) -
- - - -
- -
- -
- setUp (line 412) -
- - - -
- void - - setUp - - () -
- - - -
- -
- -
- test_from_JSON (line 424) -
- - - -
- void - - test_from_JSON - - () -
- - - -
- -
-
- -

- Documentation generated on Tue, 27 Jun 2006 22:54:27 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/_JSON_php.html b/data/module/Services/JSON/doc/Services_JSON/_JSON_php.html deleted file mode 100644 index 8d33a8febc..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/_JSON_php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - Docs for page JSON.php - - - - -
-

/JSON.php

- - -
-
Description
- -
- -

Converts to and from JSON format.

-

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. This feature can also be found in Python. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, TCL, and many others. These properties make JSON an ideal data-interchange language.

This package provides a simple encoder and decoder for JSON notation. It is intended for use with client-side Javascript applications that make use of HTTPRequest to perform server communication functions - data can be encoded into JSON notation for use in a client-side javascript, or decoded from incoming Javascript requests. JSON format is native to Javascript, and can be directly eval()'ed with no further parsing overhead

All strings should be in ASCII or UTF-8 format!

LICENSE: 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.

THIS SOFTWARE IS PROVIDED ``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 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.

- - -
-
- - -
-
Classes
- -
- - - - - - - - - - - - - -
ClassDescription
- Services_JSON - - Converts to and from JSON format. -
- Services_JSON_Error - - -
-
-
- - - -
-
Constants
- -
- -
- -
- - SERVICES_JSON_IN_ARR = 3 - (line 72) - -
- - -

Marker constant for Services_JSON::decode(), used to flag stack state

- - -
- -
- -
- - SERVICES_JSON_IN_CMT = 5 - (line 82) - -
- - -

Marker constant for Services_JSON::decode(), used to flag stack state

- - -
- -
- -
- - SERVICES_JSON_IN_OBJ = 4 - (line 77) - -
- - -

Marker constant for Services_JSON::decode(), used to flag stack state

- - -
- -
- -
- - SERVICES_JSON_IN_STR = 2 - (line 67) - -
- - -

Marker constant for Services_JSON::decode(), used to flag stack state

- - -
- -
- -
- - SERVICES_JSON_LOOSE_TYPE = 16 - (line 87) - -
- - -

Behavior switch for Services_JSON::decode()

- - -
- -
- -
- - SERVICES_JSON_SLICE = 1 - (line 62) - -
- - -

Marker constant for Services_JSON::decode(), used to flag stack state

- - -
- -
- -
- - SERVICES_JSON_SUPPRESS_ERRORS = 32 - (line 92) - -
- - -

Behavior switch for Services_JSON::decode()

- - -
-
-
- - - -

- Documentation generated on Tue, 27 Jun 2006 22:54:25 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/Services_JSON/_Test-JSON_php.html b/data/module/Services/JSON/doc/Services_JSON/_Test-JSON_php.html deleted file mode 100644 index 789bcdb930..0000000000 --- a/data/module/Services/JSON/doc/Services_JSON/_Test-JSON_php.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - Docs for page Test-JSON.php - - - - -
-

/Test-JSON.php

- - -
-
Description
- -
- -

Unit tests for Services_JSON.

- - -
-
- - -
-
Classes
- - -
- - -
-
Includes
- -
- -
- -
- - require_once - ('PHPUnit.php') - (line 22) - -
- - - -
- -
- -
- - require_once - ('JSON.php') - (line 23) - -
- - - -
-
-
- - - - -

- Documentation generated on Tue, 27 Jun 2006 22:54:26 -0700 by phpDocumentor 1.2.3 -

-
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/blank.html b/data/module/Services/JSON/doc/blank.html deleted file mode 100644 index 9b62ca9b9c..0000000000 --- a/data/module/Services/JSON/doc/blank.html +++ /dev/null @@ -1,13 +0,0 @@ - - - Generated Documentation - - - - -

Generated Documentation

-Welcome to default!
-
-This documentation was generated by phpDocumentor v1.2.3
- - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/classtrees_Services_JSON.html b/data/module/Services/JSON/doc/classtrees_Services_JSON.html deleted file mode 100644 index 535fcfd4e0..0000000000 --- a/data/module/Services/JSON/doc/classtrees_Services_JSON.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - -

- -

-

Root class Services_JSON

- - -

Root class Services_JSON_AssocArray_TestCase

- - -

Root class Services_JSON_Empties_TestCase

- - -

Root class Services_JSON_EncDec_TestCase

- - -

Root class Services_JSON_Error

- - -

Root class Services_JSON_ErrorSuppression_TestCase

- - -

Root class Services_JSON_NestedArray_TestCase

- - -

Root class Services_JSON_Object_TestCase

- - -

Root class Services_JSON_Spaces_Comments_TestCase

- - -

Root class Services_JSON_UnquotedKeys_TestCase

- - -

- Documentation generated on Tue, 27 Jun 2006 22:54:25 -0700 by phpDocumentor 1.2.3 -

- - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/elementindex.html b/data/module/Services/JSON/doc/elementindex.html deleted file mode 100644 index f5a4c80ecf..0000000000 --- a/data/module/Services/JSON/doc/elementindex.html +++ /dev/null @@ -1,457 +0,0 @@ - - - - - - - - - - - -

Full index

-

Package indexes

- -
-
- d - e - i - - s - t -
- - -
-
d
- -
-
-
-
- decode -
-
- -
decodes a JSON string into appropriate variable
-
-
- -
-
e
- -
-
-
-
- encode -
-
- -
encodes an arbitrary variable into JSON format
-
-
- -
-
i
- -
-
-
-
- isError -
-
- -
-
- -
-
j
- -
-
-
-
- JSON.php -
-
-
JSON.php in JSON.php
-
-
- -
-
s
- -
-
-
-
- Services_JSON -
-
-
Services_JSON in JSON.php
-
Converts to and from JSON format.
-
-
- Services_JSON -
-
- -
constructs a new JSON instance
-
-
- Services_JSON_AssocArray_TestCase -
-
- -
-
- Services_JSON_AssocArray_TestCase -
-
- -
-
- Services_JSON_Empties_TestCase -
-
- -
-
- Services_JSON_Empties_TestCase -
-
- -
-
- Services_JSON_EncDec_TestCase -
-
- -
-
- Services_JSON_EncDec_TestCase -
-
- -
-
- Services_JSON_Error -
-
- -
-
- Services_JSON_Error -
-
- -
-
- Services_JSON_ErrorSuppression_TestCase -
-
- -
-
- Services_JSON_ErrorSuppression_TestCase -
-
- -
-
- SERVICES_JSON_IN_ARR -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_CMT -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_OBJ -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_STR -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_LOOSE_TYPE -
-
- -
Behavior switch for Services_JSON::decode()
-
-
- Services_JSON_NestedArray_TestCase -
-
- -
-
- Services_JSON_NestedArray_TestCase -
-
- -
-
- Services_JSON_Object_TestCase -
-
- -
-
- Services_JSON_Object_TestCase -
-
- -
-
- SERVICES_JSON_SLICE -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- Services_JSON_Spaces_Comments_TestCase -
-
- -
-
- Services_JSON_Spaces_Comments_TestCase -
-
- -
-
- SERVICES_JSON_SUPPRESS_ERRORS -
-
- -
Behavior switch for Services_JSON::decode()
-
-
- Services_JSON_UnquotedKeys_TestCase -
-
- -
-
- Services_JSON_UnquotedKeys_TestCase -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- -
-
t
- -
-
-
-
- Test-JSON.php -
-
-
Test-JSON.php in Test-JSON.php
-
-
- test_comments -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_then_to_JSON -
-
- -
-
- test_from_then_to_JSON -
-
- -
-
- test_spaces -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON_suppressed -
-
- -
-
- test_to_then_from_JSON -
-
- -
-
- test_to_then_from_JSON -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- -
-
_
- -
-
-
-
- _test_from_JSON -
-
- -
-
- -
- d - e - i - - s - t -
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/elementindex_Services_JSON.html b/data/module/Services/JSON/doc/elementindex_Services_JSON.html deleted file mode 100644 index d1ca236cbd..0000000000 --- a/data/module/Services/JSON/doc/elementindex_Services_JSON.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - - - - - -

[Services_JSON] element index

-All elements -
-
- d - e - i - j - s - t - _ -
- - -
-
_
- -
-
-
-
- _test_from_JSON -
-
- -
-
- -
-
d
- -
-
-
-
- decode -
-
- -
decodes a JSON string into appropriate variable
-
-
- -
-
e
- -
-
-
-
- encode -
-
- -
encodes an arbitrary variable into JSON format
-
-
- -
-
i
- -
-
-
-
- isError -
-
- -
-
- -
-
j
- -
-
-
-
- JSON.php -
-
-
JSON.php in JSON.php
-
-
- -
-
s
- -
-
-
-
- Services_JSON -
-
-
Services_JSON in JSON.php
-
Converts to and from JSON format.
-
-
- Services_JSON -
-
- -
constructs a new JSON instance
-
-
- Services_JSON_AssocArray_TestCase -
-
- -
-
- Services_JSON_AssocArray_TestCase -
-
- -
-
- Services_JSON_Empties_TestCase -
-
- -
-
- Services_JSON_Empties_TestCase -
-
- -
-
- Services_JSON_EncDec_TestCase -
-
- -
-
- Services_JSON_EncDec_TestCase -
-
- -
-
- Services_JSON_Error -
-
- -
-
- Services_JSON_Error -
-
- -
-
- Services_JSON_ErrorSuppression_TestCase -
-
- -
-
- Services_JSON_ErrorSuppression_TestCase -
-
- -
-
- SERVICES_JSON_IN_ARR -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_CMT -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_OBJ -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_IN_STR -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- SERVICES_JSON_LOOSE_TYPE -
-
- -
Behavior switch for Services_JSON::decode()
-
-
- Services_JSON_NestedArray_TestCase -
-
- -
-
- Services_JSON_NestedArray_TestCase -
-
- -
-
- Services_JSON_Object_TestCase -
-
- -
-
- Services_JSON_Object_TestCase -
-
- -
-
- SERVICES_JSON_SLICE -
-
- -
Marker constant for Services_JSON::decode(), used to flag stack state
-
-
- Services_JSON_Spaces_Comments_TestCase -
-
- -
-
- Services_JSON_Spaces_Comments_TestCase -
-
- -
-
- SERVICES_JSON_SUPPRESS_ERRORS -
-
- -
Behavior switch for Services_JSON::decode()
-
-
- Services_JSON_UnquotedKeys_TestCase -
-
- -
-
- Services_JSON_UnquotedKeys_TestCase -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- setUp -
-
- -
-
- -
-
t
- -
-
-
-
- Test-JSON.php -
-
-
Test-JSON.php in Test-JSON.php
-
-
- test_comments -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_JSON -
-
- -
-
- test_from_then_to_JSON -
-
- -
-
- test_from_then_to_JSON -
-
- -
-
- test_spaces -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON -
-
- -
-
- test_to_JSON_suppressed -
-
- -
-
- test_to_then_from_JSON -
-
- -
-
- test_to_then_from_JSON -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- test_type -
-
- -
-
- -
- d - e - i - j - s - t - _ -
- \ No newline at end of file diff --git a/data/module/Services/JSON/doc/errors.html b/data/module/Services/JSON/doc/errors.html deleted file mode 100644 index d4a1d0e05f..0000000000 --- a/data/module/Services/JSON/doc/errors.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - phpDocumentor Parser Errors and Warnings - - - - - Post-parsing
-Test-JSON.php
- -

Post-parsing

-

Warnings:


-Warning - Class Services_JSON_ErrorSuppression_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_Spaces_Comments_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_Empties_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_UnquotedKeys_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_Error parent PEAR_Error not found
-Warning - Class Services_JSON_AssocArray_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_EncDec_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_NestedArray_TestCase parent PHPUnit_TestCase not found
-Warning - Class Services_JSON_Object_TestCase parent PHPUnit_TestCase not found
- -

JSON.php

-

Warnings:


-Warning on line 115 - no @package tag was used in a DocBlock for class Services_JSON
-Warning on line 781 - no @package tag was used in a DocBlock for class Services_JSON_Error
-Warning on line 795 - no @package tag was used in a DocBlock for class Services_JSON_Error
-Warning on line 795 - -duplicate class element "Services_JSON_Error" in file /Users/migurski/Sites/JSON-PHP/JSON.php will be ignored. -Use an @ignore tag on the original if you want this case to be documented.
- -

Test-JSON.php

-

Warnings:


-Warning on line 19 - package default is already in category , will now replace with category
-Warning on line 21 - Page-level DocBlock precedes "require_once Test-JSON.php", use another DocBlock to document the source element
-Warning on line 24 - no @package tag was used in a DocBlock for class Services_JSON_EncDec_TestCase
-Warning on line 156 - no @package tag was used in a DocBlock for class Services_JSON_AssocArray_TestCase
-Warning on line 211 - no @package tag was used in a DocBlock for class Services_JSON_NestedArray_TestCase
-Warning on line 288 - no @package tag was used in a DocBlock for class Services_JSON_Object_TestCase
-Warning on line 327 - no @package tag was used in a DocBlock for class Services_JSON_Spaces_Comments_TestCase
-Warning on line 363 - no @package tag was used in a DocBlock for class Services_JSON_Empties_TestCase
-Warning on line 405 - no @package tag was used in a DocBlock for class Services_JSON_UnquotedKeys_TestCase
-Warning on line 433 - no @package tag was used in a DocBlock for class Services_JSON_ErrorSuppression_TestCase
-

- Documentation generated on Tue, 27 Jun 2006 22:54:27 -0700 by phpDocumentor 1.2.3 -

- - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/index.html b/data/module/Services/JSON/doc/index.html deleted file mode 100644 index 3b1f52ab3f..0000000000 --- a/data/module/Services/JSON/doc/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Generated Documentation - - - - - - - - - - - <H2>Frame Alert</H2> - <P>This document is designed to be viewed using the frames feature. - If you see this message, you are using a non-frame-capable web client.</P> - - - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/li_Services_JSON.html b/data/module/Services/JSON/doc/li_Services_JSON.html deleted file mode 100644 index a9e4edb902..0000000000 --- a/data/module/Services/JSON/doc/li_Services_JSON.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - -
Services_JSON
- -

phpDocumentor v 1.2.3

- - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/media/banner.css b/data/module/Services/JSON/doc/media/banner.css deleted file mode 100644 index f2149ebb4d..0000000000 --- a/data/module/Services/JSON/doc/media/banner.css +++ /dev/null @@ -1,32 +0,0 @@ -body -{ - background-color: #CCCCFF; - margin: 0px; - padding: 0px; -} - -/* Banner (top bar) classes */ - -.banner { } - -.banner-menu -{ - clear: both; - padding: .5em; - border-top: 2px solid #6666AA; -} - -.banner-title -{ - text-align: right; - font-size: 20pt; - font-weight: bold; - margin: .2em; -} - -.package-selector -{ - background-color: #AAAADD; - border: 1px solid black; - color: yellow; -} diff --git a/data/module/Services/JSON/doc/media/stylesheet.css b/data/module/Services/JSON/doc/media/stylesheet.css deleted file mode 100644 index 380dcee2cf..0000000000 --- a/data/module/Services/JSON/doc/media/stylesheet.css +++ /dev/null @@ -1,134 +0,0 @@ -a { color: #336699; text-decoration: none; } -a:hover { color: #6699CC; text-decoration: underline; } -a:active { color: #6699CC; text-decoration: underline; } - -body { background : #FFFFFF; } -body, table { font-family: Georgia, Times New Roman, Times, serif; font-size: 10pt } -p, li { line-height: 140% } -a img { border: 0px; } -dd { margin-left: 0px; padding-left: 1em; } - -/* Page layout/boxes */ - -.info-box {} -.info-box-title { margin: 1em 0em 0em 0em; padding: .25em; font-weight: normal; font-size: 14pt; border: 2px solid #999999; background-color: #CCCCFF } -.info-box-body { border: 1px solid #999999; padding: .5em; } -.nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; } - -.oddrow { background-color: #F8F8F8; border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em} -.evenrow { border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em} - -.page-body { max-width: 800px; margin: auto; } -.tree dl { margin: 0px } - -/* Index formatting classes */ - -.index-item-body { margin-top: .5em; margin-bottom: .5em} -.index-item-description { margin-top: .25em } -.index-item-details { font-weight: normal; font-style: italic; font-size: 8pt } -.index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em} -.index-letter-title { font-size: 12pt; font-weight: bold } -.index-letter-menu { text-align: center; margin: 1em } -.index-letter { font-size: 12pt } - -/* Docbook classes */ - -.description {} -.short-description { font-weight: bold; color: #666666; } -.tags { padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; } -.parameters { padding-left: 0em; margin-left: 3em; font-style: italic; list-style-type: square; } -.redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; } -.package { } -.package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black } -.package-details { font-size: 85%; } -.sub-package { font-weight: bold; font-size: 120% } -.tutorial { border-width: thin; border-color: #0066ff } -.tutorial-nav-box { width: 100%; border: 1px solid #999999; background-color: #F8F8F8; } -.nav-button-disabled { color: #999999; } -.nav-button:active, -.nav-button:focus, -.nav-button:hover { background-color: #DDDDDD; outline: 1px solid #999999; text-decoration: none } -.folder-title { font-style: italic } - -/* Generic formatting */ - -.field { font-weight: bold; } -.detail { font-size: 8pt; } -.notes { font-style: italic; font-size: 8pt; } -.separator { background-color: #999999; height: 2px; } -.warning { color: #FF6600; } -.disabled { font-style: italic; color: #999999; } - -/* Code elements */ - -.line-number { } - -.class-table { width: 100%; } -.class-table-header { border-bottom: 1px dotted #666666; text-align: left} -.class-name { color: #000000; font-weight: bold; } - -.method-summary { padding-left: 1em; font-size: 8pt } -.method-header { } -.method-definition { margin-bottom: .3em } -.method-title { font-weight: bold; } -.method-name { font-weight: bold; } -.method-signature { font-size: 85%; color: #666666; margin: .5em 0em } -.method-result { font-style: italic; } - -.var-summary { padding-left: 1em; font-size: 8pt; } -.var-header { } -.var-title { margin-bottom: .3em } -.var-type { font-style: italic; } -.var-name { font-weight: bold; } -.var-default {} -.var-description { font-weight: normal; color: #000000; } - -.include-title { } -.include-type { font-style: italic; } -.include-name { font-weight: bold; } - -.const-title { } -.const-name { font-weight: bold; } - -/* Syntax highlighting */ - -.src-code { border: 1px solid #336699; padding: 1em; background-color: #EEEEEE; } - -.src-comm { color: green; } -.src-id { } -.src-inc { color: #0000FF; } -.src-key { color: #0000FF; } -.src-num { color: #CC0000; } -.src-str { color: #66cccc; } -.src-sym { font-weight: bold; } -.src-var { } - -.src-php { font-weight: bold; } - -.src-doc { color: #009999 } -.src-doc-close-template { color: #0000FF } -.src-doc-coretag { color: #0099FF; font-weight: bold } -.src-doc-inlinetag { color: #0099FF } -.src-doc-internal { color: #6699cc } -.src-doc-tag { color: #0080CC } -.src-doc-template { color: #0000FF } -.src-doc-type { font-style: italic } -.src-doc-var { font-style: italic } - -/* tutorial */ - -.authors { } -.author { font-style: italic; font-weight: bold } -.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal } -.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em } -.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap } -.release-info { font-size: 85%; font-style: italic; margin: 1em 0em } -.ref-title-box { } -.ref-title { } -.ref-purpose { font-style: italic; color: #666666 } -.ref-synopsis { } -.title { font-weight: bold; margin: 1em 0em 0em 0em; padding: .25em; border: 2px solid #999999; background-color: #CCCCFF } -.cmd-synopsis { margin: 1em 0em } -.cmd-title { font-weight: bold } -.toc { margin-left: 2em; padding-left: 0em } - diff --git a/data/module/Services/JSON/doc/packages.html b/data/module/Services/JSON/doc/packages.html deleted file mode 100644 index 7058c6b73a..0000000000 --- a/data/module/Services/JSON/doc/packages.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data/module/Services/JSON/doc/todolist.html b/data/module/Services/JSON/doc/todolist.html deleted file mode 100644 index 4c060b9ac0..0000000000 --- a/data/module/Services/JSON/doc/todolist.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Todo List - - - - -

Todo List

-

Services_JSON

-

Services_JSON::isError()

-
    -
  • Ultimately, this should just call PEAR::isError()
  • -
-

- Documentation generated on Tue, 27 Jun 2006 22:54:27 -0700 by phpDocumentor 1.2.3 -

- - \ No newline at end of file diff --git a/data/module/Text/Password.php b/data/module/Text/Password.php deleted file mode 100644 index 2b75b9c98f..0000000000 --- a/data/module/Text/Password.php +++ /dev/null @@ -1,533 +0,0 @@ - - * @author Olivier Vanhoucke - * @copyright 2004-2005 Martin Jansen, Olivier Vanhoucke - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: Password.php,v 1.18 2008/11/30 13:38:56 mj Exp $ - * @link http://pear.php.net/package/Text_Password - */ - -/** - * Number of possible characters in the password - */ -$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 0; - -/** - * Main class for the Text_Password package - * - * @category Text - * @package Text_Password - * @author Martin Jansen - * @author Olivier Vanhoucke - * @copyright 2004-2005 Martin Jansen, Olivier Vanhoucke - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/Text_Password - */ -class Text_Password { - - /** - * Create a single password. - * - * @access public - * @param integer Length of the password. - * @param string Type of password (pronounceable, unpronounceable) - * @param string Character which could be use in the - * unpronounceable password ex : 'ABCDEFG' - * or numeric, alphabetical or alphanumeric. - * @return string Returns the generated password. - */ - function create($length = 10, $type = 'pronounceable', $chars = '') - { - switch ($type) { - case 'unpronounceable' : - return Text_Password::_createUnpronounceable($length, $chars); - - case 'pronounceable' : - default : - return Text_Password::_createPronounceable($length); - } - } - - /** - * Create multiple, different passwords - * - * Method to create a list of different passwords which are - * all different. - * - * @access public - * @param integer Number of different password - * @param integer Length of the password - * @param string Type of password (pronounceable, unpronounceable) - * @param string Character which could be use in the - * unpronounceable password ex : 'A,B,C,D,E,F,G' - * or numeric, alphabetical or alphanumeric. - * @return array Array containing the passwords - */ - function createMultiple($number, $length = 10, $type = 'pronounceable', $chars = '') - { - $passwords = array(); - - while ($number > 0) { - while (true) { - $password = Text_Password::create($length, $type, $chars); - if (!in_array($password, $passwords)) { - $passwords[] = $password; - break; - } - } - $number--; - } - return $passwords; - } - - /** - * Create password from login - * - * Method to create password from login - * - * @access public - * @param string Login - * @param string Type - * @param integer Key - * @return string - */ - function createFromLogin($login, $type, $key = 0) - { - switch ($type) { - case 'reverse': - return strrev($login); - - case 'shuffle': - return Text_Password::_shuffle($login); - - case 'xor': - return Text_Password::_xor($login, $key); - - case 'rot13': - return str_rot13($login); - - case 'rotx': - return Text_Password::_rotx($login, $key); - - case 'rotx++': - return Text_Password::_rotxpp($login, $key); - - case 'rotx--': - return Text_Password::_rotxmm($login, $key); - - case 'ascii_rotx': - return Text_Password::_asciiRotx($login, $key); - - case 'ascii_rotx++': - return Text_Password::_asciiRotxpp($login, $key); - - case 'ascii_rotx--': - return Text_Password::_asciiRotxmm($login, $key); - } - } - - /** - * Create multiple, different passwords from an array of login - * - * Method to create a list of different password from login - * - * @access public - * @param array Login - * @param string Type - * @param integer Key - * @return array Array containing the passwords - */ - function createMultipleFromLogin($login, $type, $key = 0) - { - $passwords = array(); - $number = count($login); - $save = $number; - - while ($number > 0) { - while (true) { - $password = Text_Password::createFromLogin($login[$save - $number], $type, $key); - if (!in_array($password, $passwords)) { - $passwords[] = $password; - break; - } - } - $number--; - } - return $passwords; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _xor($login, $key) - { - $tmp = ''; - - for ($i = 0; $i < strlen($login); $i++) { - $next = ord($login{$i}) ^ $key; - if ($next > 255) { - $next -= 255; - } elseif ($next < 0) { - $next += 255; - } - $tmp .= chr($next); - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * lowercase only - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _rotx($login, $key) - { - $tmp = ''; - $login = strtolower($login); - - for ($i = 0; $i < strlen($login); $i++) { - if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase - $next = ord($login{$i}) + $key; - if ($next > 122) { - $next -= 26; - } elseif ($next < 97) { - $next += 26; - } - $tmp .= chr($next); - } else { - $tmp .= $login{$i}; - } - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * lowercase only - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _rotxpp($login, $key) - { - $tmp = ''; - $login = strtolower($login); - - for ($i = 0; $i < strlen($login); $i++, $key++) { - if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase - $next = ord($login{$i}) + $key; - if ($next > 122) { - $next -= 26; - } elseif ($next < 97) { - $next += 26; - } - $tmp .= chr($next); - } else { - $tmp .= $login{$i}; - } - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * lowercase only - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _rotxmm($login, $key) - { - $tmp = ''; - $login = strtolower($login); - - for ($i = 0; $i < strlen($login); $i++, $key--) { - if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase - $next = ord($login{$i}) + $key; - if ($next > 122) { - $next -= 26; - } elseif ($next < 97) { - $next += 26; - } - $tmp .= chr($next); - } else { - $tmp .= $login{$i}; - } - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _asciiRotx($login, $key) - { - $tmp = ''; - - for ($i = 0; $i < strlen($login); $i++) { - $next = ord($login{$i}) + $key; - if ($next > 255) { - $next -= 255; - } elseif ($next < 0) { - $next += 255; - } - switch ($next) { // delete white space - case 0x09: - case 0x20: - case 0x0A: - case 0x0D: - $next++; - } - $tmp .= chr($next); - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _asciiRotxpp($login, $key) - { - $tmp = ''; - - for ($i = 0; $i < strlen($login); $i++, $key++) { - $next = ord($login{$i}) + $key; - if ($next > 255) { - $next -= 255; - } elseif ($next < 0) { - $next += 255; - } - switch ($next) { // delete white space - case 0x09: - case 0x20: - case 0x0A: - case 0x0D: - $next++; - } - $tmp .= chr($next); - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * - * @access private - * @param string Login - * @param integer Key - * @return string - */ - function _asciiRotxmm($login, $key) - { - $tmp = ''; - - for ($i = 0; $i < strlen($login); $i++, $key--) { - $next = ord($login{$i}) + $key; - if ($next > 255) { - $next -= 255; - } elseif ($next < 0) { - $next += 255; - } - switch ($next) { // delete white space - case 0x09: - case 0x20: - case 0x0A: - case 0x0D: - $next++; - } - $tmp .= chr($next); - } - - return $tmp; - } - - /** - * Helper method to create password - * - * Method to create a password from a login - * - * @access private - * @param string Login - * @return string - */ - function _shuffle($login) - { - $tmp = array(); - - for ($i = 0; $i < strlen($login); $i++) { - $tmp[] = $login{$i}; - } - - shuffle($tmp); - - return implode($tmp, ''); - } - - /** - * Create pronounceable password - * - * This method creates a string that consists of - * vowels and consonats. - * - * @access private - * @param integer Length of the password - * @return string Returns the password - */ - function _createPronounceable($length) - { - - $retVal = ''; - - /** - * List of vowels and vowel sounds - */ - $v = array('a', 'e', 'i', 'o', 'u', 'ae', 'ou', 'io', - 'ea', 'ou', 'ia', 'ai' - ); - - /** - * List of consonants and consonant sounds - */ - $c = array('b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 'm', - 'n', 'p', 'r', 's', 't', 'u', 'v', 'w', - 'tr', 'cr', 'fr', 'dr', 'wr', 'pr', 'th', - 'ch', 'ph', 'st', 'sl', 'cl' - ); - - $v_count = 12; - $c_count = 29; - - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = $v_count + $c_count; - - for ($i = 0; $i < $length; $i++) { - $retVal .= $c[mt_rand(0, $c_count-1)] . $v[mt_rand(0, $v_count-1)]; - } - - return substr($retVal, 0, $length); - } - - /** - * Create unpronounceable password - * - * This method creates a random unpronounceable password - * - * @access private - * @param integer Length of the password - * @param string Character which could be use in the - * unpronounceable password ex : 'ABCDEFG' - * or numeric, alphabetical or alphanumeric. - * @return string Returns the password - */ - function _createUnpronounceable($length, $chars) - { - $password = ''; - - /** - * List of character which could be use in the password - */ - switch($chars) { - - case 'alphanumeric': - $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 62; - break; - - case 'alphabetical': - $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 52; - break; - - case 'numeric': - $chars = '0123456789'; - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 10; - break; - - case '': - $chars = '_#@%&ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 67; - break; - - default: - /** - * Some characters shouldn't be used - */ - $chars = trim($chars); - $chars = str_replace(array('+', '|', '$', '^', '/', '\\', ','), '', $chars); - - $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = strlen($chars); - } - - /** - * Generate password - */ - for ($i = 0; $i < $length; $i++) { - $num = mt_rand(0, $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] - 1); - $password .= $chars{$num}; - } - - /** - * Return password - */ - return $password; - } -} -?> diff --git a/data/module/XML/Parser.php b/data/module/XML/Parser.php deleted file mode 100644 index a38a161aef..0000000000 --- a/data/module/XML/Parser.php +++ /dev/null @@ -1,768 +0,0 @@ - - * @author Tomas V.V.Cox - * @author Stephan Schmidt - * @copyright 2002-2008 The PHP Group - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Parser.php 302733 2010-08-24 01:09:09Z clockwerx $ - * @link http://pear.php.net/package/XML_Parser - */ - -/** - * uses PEAR's error handling - */ -require_once 'PEAR.php'; - -/** - * resource could not be created - */ -define('XML_PARSER_ERROR_NO_RESOURCE', 200); - -/** - * unsupported mode - */ -define('XML_PARSER_ERROR_UNSUPPORTED_MODE', 201); - -/** - * invalid encoding was given - */ -define('XML_PARSER_ERROR_INVALID_ENCODING', 202); - -/** - * specified file could not be read - */ -define('XML_PARSER_ERROR_FILE_NOT_READABLE', 203); - -/** - * invalid input - */ -define('XML_PARSER_ERROR_INVALID_INPUT', 204); - -/** - * remote file cannot be retrieved in safe mode - */ -define('XML_PARSER_ERROR_REMOTE', 205); - -/** - * XML Parser class. - * - * This is an XML parser based on PHP's "xml" extension, - * based on the bundled expat library. - * - * Notes: - * - It requires PHP 4.0.4pl1 or greater - * - From revision 1.17, the function names used by the 'func' mode - * are in the format "xmltag_$elem", for example: use "xmltag_name" - * to handle the tags of your xml file. - * - different parsing modes - * - * @category XML - * @package XML_Parser - * @author Stig Bakken - * @author Tomas V.V.Cox - * @author Stephan Schmidt - * @copyright 2002-2008 The PHP Group - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/XML_Parser - * @todo create XML_Parser_Namespace to parse documents with namespaces - * @todo create XML_Parser_Pull - * @todo Tests that need to be made: - * - mixing character encodings - * - a test using all expat handlers - * - options (folding, output charset) - */ -class XML_Parser extends PEAR -{ - // {{{ properties - - /** - * XML parser handle - * - * @var resource - * @see xml_parser_create() - */ - var $parser; - - /** - * File handle if parsing from a file - * - * @var resource - */ - var $fp; - - /** - * Whether to do case folding - * - * If set to true, all tag and attribute names will - * be converted to UPPER CASE. - * - * @var boolean - */ - var $folding = true; - - /** - * Mode of operation, one of "event" or "func" - * - * @var string - */ - var $mode; - - /** - * Mapping from expat handler function to class method. - * - * @var array - */ - var $handler = array( - 'character_data_handler' => 'cdataHandler', - 'default_handler' => 'defaultHandler', - 'processing_instruction_handler' => 'piHandler', - 'unparsed_entity_decl_handler' => 'unparsedHandler', - 'notation_decl_handler' => 'notationHandler', - 'external_entity_ref_handler' => 'entityrefHandler' - ); - - /** - * source encoding - * - * @var string - */ - var $srcenc; - - /** - * target encoding - * - * @var string - */ - var $tgtenc; - - /** - * handler object - * - * @var object - */ - var $_handlerObj; - - /** - * valid encodings - * - * @var array - */ - var $_validEncodings = array('ISO-8859-1', 'UTF-8', 'US-ASCII'); - - // }}} - // {{{ php4 constructor - - /** - * Creates an XML parser. - * - * This is needed for PHP4 compatibility, it will - * call the constructor, when a new instance is created. - * - * @param string $srcenc source charset encoding, use NULL (default) to use - * whatever the document specifies - * @param string $mode how this parser object should work, "event" for - * startelement/endelement-type events, "func" - * to have it call functions named after elements - * @param string $tgtenc a valid target encoding - */ - function XML_Parser($srcenc = null, $mode = 'event', $tgtenc = null) - { - XML_Parser::__construct($srcenc, $mode, $tgtenc); - } - // }}} - // {{{ php5 constructor - - /** - * PHP5 constructor - * - * @param string $srcenc source charset encoding, use NULL (default) to use - * whatever the document specifies - * @param string $mode how this parser object should work, "event" for - * startelement/endelement-type events, "func" - * to have it call functions named after elements - * @param string $tgtenc a valid target encoding - */ - function __construct($srcenc = null, $mode = 'event', $tgtenc = null) - { - $this->PEAR('XML_Parser_Error'); - - $this->mode = $mode; - $this->srcenc = $srcenc; - $this->tgtenc = $tgtenc; - } - // }}} - - /** - * Sets the mode of the parser. - * - * Possible modes are: - * - func - * - event - * - * You can set the mode using the second parameter - * in the constructor. - * - * This method is only needed, when switching to a new - * mode at a later point. - * - * @param string $mode mode, either 'func' or 'event' - * - * @return boolean|object true on success, PEAR_Error otherwise - * @access public - */ - function setMode($mode) - { - if ($mode != 'func' && $mode != 'event') { - $this->raiseError('Unsupported mode given', - XML_PARSER_ERROR_UNSUPPORTED_MODE); - } - - $this->mode = $mode; - return true; - } - - /** - * Sets the object, that will handle the XML events - * - * This allows you to create a handler object independent of the - * parser object that you are using and easily switch the underlying - * parser. - * - * If no object will be set, XML_Parser assumes that you - * extend this class and handle the events in $this. - * - * @param object &$obj object to handle the events - * - * @return boolean will always return true - * @access public - * @since v1.2.0beta3 - */ - function setHandlerObj(&$obj) - { - $this->_handlerObj = &$obj; - return true; - } - - /** - * Init the element handlers - * - * @return mixed - * @access private - */ - function _initHandlers() - { - if (!is_resource($this->parser)) { - return false; - } - - if (!is_object($this->_handlerObj)) { - $this->_handlerObj = &$this; - } - switch ($this->mode) { - - case 'func': - xml_set_object($this->parser, $this->_handlerObj); - xml_set_element_handler($this->parser, - array(&$this, 'funcStartHandler'), array(&$this, 'funcEndHandler')); - break; - - case 'event': - xml_set_object($this->parser, $this->_handlerObj); - xml_set_element_handler($this->parser, 'startHandler', 'endHandler'); - break; - default: - return $this->raiseError('Unsupported mode given', - XML_PARSER_ERROR_UNSUPPORTED_MODE); - break; - } - - /** - * set additional handlers for character data, entities, etc. - */ - foreach ($this->handler as $xml_func => $method) { - if (method_exists($this->_handlerObj, $method)) { - $xml_func = 'xml_set_' . $xml_func; - $xml_func($this->parser, $method); - } - } - } - - // {{{ _create() - - /** - * create the XML parser resource - * - * Has been moved from the constructor to avoid - * problems with object references. - * - * Furthermore it allows us returning an error - * if something fails. - * - * NOTE: uses '@' error suppresion in this method - * - * @return bool|PEAR_Error true on success, PEAR_Error otherwise - * @access private - * @see xml_parser_create - */ - function _create() - { - if ($this->srcenc === null) { - $xp = @xml_parser_create(); - } else { - $xp = @xml_parser_create($this->srcenc); - } - if (is_resource($xp)) { - if ($this->tgtenc !== null) { - if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING, - $this->tgtenc) - ) { - return $this->raiseError('invalid target encoding', - XML_PARSER_ERROR_INVALID_ENCODING); - } - } - $this->parser = $xp; - $result = $this->_initHandlers($this->mode); - if ($this->isError($result)) { - return $result; - } - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding); - return true; - } - if (!in_array(strtoupper($this->srcenc), $this->_validEncodings)) { - return $this->raiseError('invalid source encoding', - XML_PARSER_ERROR_INVALID_ENCODING); - } - return $this->raiseError('Unable to create XML parser resource.', - XML_PARSER_ERROR_NO_RESOURCE); - } - - // }}} - // {{{ reset() - - /** - * Reset the parser. - * - * This allows you to use one parser instance - * to parse multiple XML documents. - * - * @access public - * @return boolean|object true on success, PEAR_Error otherwise - */ - function reset() - { - $result = $this->_create(); - if ($this->isError($result)) { - return $result; - } - return true; - } - - // }}} - // {{{ setInputFile() - - /** - * Sets the input xml file to be parsed - * - * @param string $file Filename (full path) - * - * @return resource fopen handle of the given file - * @access public - * @throws XML_Parser_Error - * @see setInput(), setInputString(), parse() - */ - function setInputFile($file) - { - /** - * check, if file is a remote file - */ - if (preg_match('/^(http|ftp):\/\//i', substr($file, 0, 10))) { - if (!ini_get('allow_url_fopen')) { - return $this-> - raiseError('Remote files cannot be parsed, as safe mode is enabled.', - XML_PARSER_ERROR_REMOTE); - } - } - - $fp = @fopen($file, 'rb'); - if (is_resource($fp)) { - $this->fp = $fp; - return $fp; - } - return $this->raiseError('File could not be opened.', - XML_PARSER_ERROR_FILE_NOT_READABLE); - } - - // }}} - // {{{ setInputString() - - /** - * XML_Parser::setInputString() - * - * Sets the xml input from a string - * - * @param string $data a string containing the XML document - * - * @return null - */ - function setInputString($data) - { - $this->fp = $data; - return null; - } - - // }}} - // {{{ setInput() - - /** - * Sets the file handle to use with parse(). - * - * You should use setInputFile() or setInputString() if you - * pass a string - * - * @param mixed $fp Can be either a resource returned from fopen(), - * a URL, a local filename or a string. - * - * @return mixed - * @access public - * @see parse() - * @uses setInputString(), setInputFile() - */ - function setInput($fp) - { - if (is_resource($fp)) { - $this->fp = $fp; - return true; - } elseif (preg_match('/^[a-z]+:\/\//i', substr($fp, 0, 10))) { - // see if it's an absolute URL (has a scheme at the beginning) - return $this->setInputFile($fp); - } elseif (file_exists($fp)) { - // see if it's a local file - return $this->setInputFile($fp); - } else { - // it must be a string - $this->fp = $fp; - return true; - } - - return $this->raiseError('Illegal input format', - XML_PARSER_ERROR_INVALID_INPUT); - } - - // }}} - // {{{ parse() - - /** - * Central parsing function. - * - * @return bool|PEAR_Error returns true on success, or a PEAR_Error otherwise - * @access public - */ - function parse() - { - /** - * reset the parser - */ - $result = $this->reset(); - if ($this->isError($result)) { - return $result; - } - // if $this->fp was fopened previously - if (is_resource($this->fp)) { - - while ($data = fread($this->fp, 4096)) { - if (!$this->_parseString($data, feof($this->fp))) { - $error = &$this->raiseError(); - $this->free(); - return $error; - } - } - } else { - // otherwise, $this->fp must be a string - if (!$this->_parseString($this->fp, true)) { - $error = &$this->raiseError(); - $this->free(); - return $error; - } - } - $this->free(); - - return true; - } - - /** - * XML_Parser::_parseString() - * - * @param string $data data - * @param bool $eof end-of-file flag - * - * @return bool - * @access private - * @see parseString() - **/ - function _parseString($data, $eof = false) - { - return xml_parse($this->parser, $data, $eof); - } - - // }}} - // {{{ parseString() - - /** - * XML_Parser::parseString() - * - * Parses a string. - * - * @param string $data XML data - * @param boolean $eof If set and TRUE, data is the last piece - * of data sent in this parser - * - * @return bool|PEAR_Error true on success or a PEAR Error - * @throws XML_Parser_Error - * @see _parseString() - */ - function parseString($data, $eof = false) - { - if (!isset($this->parser) || !is_resource($this->parser)) { - $this->reset(); - } - - if (!$this->_parseString($data, $eof)) { - $error = &$this->raiseError(); - $this->free(); - return $error; - } - - if ($eof === true) { - $this->free(); - } - return true; - } - - /** - * XML_Parser::free() - * - * Free the internal resources associated with the parser - * - * @return null - **/ - function free() - { - if (isset($this->parser) && is_resource($this->parser)) { - xml_parser_free($this->parser); - unset( $this->parser ); - } - if (isset($this->fp) && is_resource($this->fp)) { - fclose($this->fp); - } - unset($this->fp); - return null; - } - - /** - * XML_Parser::raiseError() - * - * Throws a XML_Parser_Error - * - * @param string $msg the error message - * @param integer $ecode the error message code - * - * @return XML_Parser_Error reference to the error object - **/ - function &raiseError($msg = null, $ecode = 0) - { - $msg = !is_null($msg) ? $msg : $this->parser; - $err = &new XML_Parser_Error($msg, $ecode); - return parent::raiseError($err); - } - - // }}} - // {{{ funcStartHandler() - - /** - * derives and calls the Start Handler function - * - * @param mixed $xp ?? - * @param mixed $elem ?? - * @param mixed $attribs ?? - * - * @return void - */ - function funcStartHandler($xp, $elem, $attribs) - { - $func = 'xmltag_' . $elem; - $func = str_replace(array('.', '-', ':'), '_', $func); - if (method_exists($this->_handlerObj, $func)) { - call_user_func(array(&$this->_handlerObj, $func), $xp, $elem, $attribs); - } elseif (method_exists($this->_handlerObj, 'xmltag')) { - call_user_func(array(&$this->_handlerObj, 'xmltag'), - $xp, $elem, $attribs); - } - } - - // }}} - // {{{ funcEndHandler() - - /** - * derives and calls the End Handler function - * - * @param mixed $xp ?? - * @param mixed $elem ?? - * - * @return void - */ - function funcEndHandler($xp, $elem) - { - $func = 'xmltag_' . $elem . '_'; - $func = str_replace(array('.', '-', ':'), '_', $func); - if (method_exists($this->_handlerObj, $func)) { - call_user_func(array(&$this->_handlerObj, $func), $xp, $elem); - } elseif (method_exists($this->_handlerObj, 'xmltag_')) { - call_user_func(array(&$this->_handlerObj, 'xmltag_'), $xp, $elem); - } - } - - // }}} - // {{{ startHandler() - - /** - * abstract method signature for Start Handler - * - * @param mixed $xp ?? - * @param mixed $elem ?? - * @param mixed &$attribs ?? - * - * @return null - * @abstract - */ - function startHandler($xp, $elem, &$attribs) - { - return null; - } - - // }}} - // {{{ endHandler() - - /** - * abstract method signature for End Handler - * - * @param mixed $xp ?? - * @param mixed $elem ?? - * - * @return null - * @abstract - */ - function endHandler($xp, $elem) - { - return null; - } - - - // }}}me -} - -/** - * error class, replaces PEAR_Error - * - * An instance of this class will be returned - * if an error occurs inside XML_Parser. - * - * There are three advantages over using the standard PEAR_Error: - * - All messages will be prefixed - * - check for XML_Parser error, using is_a( $error, 'XML_Parser_Error' ) - * - messages can be generated from the xml_parser resource - * - * @category XML - * @package XML_Parser - * @author Stig Bakken - * @author Tomas V.V.Cox - * @author Stephan Schmidt - * @copyright 2002-2008 The PHP Group - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/XML_Parser - * @see PEAR_Error - */ -class XML_Parser_Error extends PEAR_Error -{ - // {{{ properties - - /** - * prefix for all messages - * - * @var string - */ - var $error_message_prefix = 'XML_Parser: '; - - // }}} - // {{{ constructor() - /** - * construct a new error instance - * - * You may either pass a message or an xml_parser resource as first - * parameter. If a resource has been passed, the last error that - * happened will be retrieved and returned. - * - * @param string|resource $msgorparser message or parser resource - * @param integer $code error code - * @param integer $mode error handling - * @param integer $level error level - * - * @access public - * @todo PEAR CS - can't meet 85char line limit without arg refactoring - */ - function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE) - { - if (is_resource($msgorparser)) { - $code = xml_get_error_code($msgorparser); - $msgorparser = sprintf('%s at XML input line %d:%d', - xml_error_string($code), - xml_get_current_line_number($msgorparser), - xml_get_current_column_number($msgorparser)); - } - $this->PEAR_Error($msgorparser, $code, $mode, $level); - } - // }}} -} -?> diff --git a/data/module/XML/Parser/Simple.php b/data/module/XML/Parser/Simple.php deleted file mode 100644 index 9ed0abfc6c..0000000000 --- a/data/module/XML/Parser/Simple.php +++ /dev/null @@ -1,326 +0,0 @@ - - * @copyright 2004-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Simple.php 265444 2008-08-24 21:48:21Z ashnazg $ - * @link http://pear.php.net/package/XML_Parser - */ - -/** - * built on XML_Parser - */ -require_once 'XML/Parser.php'; - -/** - * Simple XML parser class. - * - * This class is a simplified version of XML_Parser. - * In most XML applications the real action is executed, - * when a closing tag is found. - * - * XML_Parser_Simple allows you to just implement one callback - * for each tag that will receive the tag with its attributes - * and CData. - * - * - * require_once '../Parser/Simple.php'; - * - * class myParser extends XML_Parser_Simple - * { - * function myParser() - * { - * $this->XML_Parser_Simple(); - * } - * - * function handleElement($name, $attribs, $data) - * { - * printf('handle %s
', $name); - * } - * } - * - * $p = &new myParser(); - * - * $result = $p->setInputFile('myDoc.xml'); - * $result = $p->parse(); - *
- * - * @category XML - * @package XML_Parser - * @author Stephan Schmidt - * @copyright 2004-2008 The PHP Group - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/XML_Parser - */ -class XML_Parser_Simple extends XML_Parser -{ - /** - * element stack - * - * @access private - * @var array - */ - var $_elStack = array(); - - /** - * all character data - * - * @access private - * @var array - */ - var $_data = array(); - - /** - * element depth - * - * @access private - * @var integer - */ - var $_depth = 0; - - /** - * Mapping from expat handler function to class method. - * - * @var array - */ - var $handler = array( - 'default_handler' => 'defaultHandler', - 'processing_instruction_handler' => 'piHandler', - 'unparsed_entity_decl_handler' => 'unparsedHandler', - 'notation_decl_handler' => 'notationHandler', - 'external_entity_ref_handler' => 'entityrefHandler' - ); - - /** - * Creates an XML parser. - * - * This is needed for PHP4 compatibility, it will - * call the constructor, when a new instance is created. - * - * @param string $srcenc source charset encoding, use NULL (default) to use - * whatever the document specifies - * @param string $mode how this parser object should work, "event" for - * handleElement(), "func" to have it call functions - * named after elements (handleElement_$name()) - * @param string $tgtenc a valid target encoding - */ - function XML_Parser_Simple($srcenc = null, $mode = 'event', $tgtenc = null) - { - $this->XML_Parser($srcenc, $mode, $tgtenc); - } - - /** - * inits the handlers - * - * @return mixed - * @access private - */ - function _initHandlers() - { - if (!is_object($this->_handlerObj)) { - $this->_handlerObj = &$this; - } - - if ($this->mode != 'func' && $this->mode != 'event') { - return $this->raiseError('Unsupported mode given', - XML_PARSER_ERROR_UNSUPPORTED_MODE); - } - xml_set_object($this->parser, $this->_handlerObj); - - xml_set_element_handler($this->parser, array(&$this, 'startHandler'), - array(&$this, 'endHandler')); - xml_set_character_data_handler($this->parser, array(&$this, 'cdataHandler')); - - /** - * set additional handlers for character data, entities, etc. - */ - foreach ($this->handler as $xml_func => $method) { - if (method_exists($this->_handlerObj, $method)) { - $xml_func = 'xml_set_' . $xml_func; - $xml_func($this->parser, $method); - } - } - } - - /** - * Reset the parser. - * - * This allows you to use one parser instance - * to parse multiple XML documents. - * - * @access public - * @return boolean|object true on success, PEAR_Error otherwise - */ - function reset() - { - $this->_elStack = array(); - $this->_data = array(); - $this->_depth = 0; - - $result = $this->_create(); - if ($this->isError($result)) { - return $result; - } - return true; - } - - /** - * start handler - * - * Pushes attributes and tagname onto a stack - * - * @param resource $xp xml parser resource - * @param string $elem element name - * @param array &$attribs attributes - * - * @return mixed - * @access private - * @final - */ - function startHandler($xp, $elem, &$attribs) - { - array_push($this->_elStack, array( - 'name' => $elem, - 'attribs' => $attribs - )); - $this->_depth++; - $this->_data[$this->_depth] = ''; - } - - /** - * end handler - * - * Pulls attributes and tagname from a stack - * - * @param resource $xp xml parser resource - * @param string $elem element name - * - * @return mixed - * @access private - * @final - */ - function endHandler($xp, $elem) - { - $el = array_pop($this->_elStack); - $data = $this->_data[$this->_depth]; - $this->_depth--; - - switch ($this->mode) { - case 'event': - $this->_handlerObj->handleElement($el['name'], $el['attribs'], $data); - break; - case 'func': - $func = 'handleElement_' . $elem; - if (strchr($func, '.')) { - $func = str_replace('.', '_', $func); - } - if (method_exists($this->_handlerObj, $func)) { - call_user_func(array(&$this->_handlerObj, $func), - $el['name'], $el['attribs'], $data); - } - break; - } - } - - /** - * handle character data - * - * @param resource $xp xml parser resource - * @param string $data data - * - * @return void - * @access private - * @final - */ - function cdataHandler($xp, $data) - { - $this->_data[$this->_depth] .= $data; - } - - /** - * handle a tag - * - * Implement this in your parser - * - * @param string $name element name - * @param array $attribs attributes - * @param string $data character data - * - * @return void - * @access public - * @abstract - */ - function handleElement($name, $attribs, $data) - { - } - - /** - * get the current tag depth - * - * The root tag is in depth 0. - * - * @access public - * @return integer - */ - function getCurrentDepth() - { - return $this->_depth; - } - - /** - * add some string to the current ddata. - * - * This is commonly needed, when a document is parsed recursively. - * - * @param string $data data to add - * - * @return void - * @access public - */ - function addToData($data) - { - $this->_data[$this->_depth] .= $data; - } -} -?> diff --git a/data/module/XML/Serializer.php b/data/module/XML/Serializer.php deleted file mode 100644 index a757d4b00d..0000000000 --- a/data/module/XML/Serializer.php +++ /dev/null @@ -1,1255 +0,0 @@ - - * 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. - * * The name of the author 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 XML - * @package XML_Serializer - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Serializer.php 294967 2010-02-12 03:10:19Z clockwerx $ - * @link http://pear.php.net/package/XML_Serializer - * @see XML_Unserializer - */ - -/** - * uses PEAR error management - */ -require_once 'PEAR.php'; - -/** - * uses XML_Util to create XML tags - */ -require_once 'XML/Util.php'; - -/** - * option: string used for indentation - * - * Possible values: - * - any string (default is any string) - */ -define('XML_SERIALIZER_OPTION_INDENT', 'indent'); - -/** - * option: string used for linebreaks - * - * Possible values: - * - any string (default is \n) - */ -define('XML_SERIALIZER_OPTION_LINEBREAKS', 'linebreak'); - -/** - * option: enable type hints - * - * Possible values: - * - true - * - false - */ -define('XML_SERIALIZER_OPTION_TYPEHINTS', 'typeHints'); - -/** - * option: add an XML declaration - * - * Possible values: - * - true - * - false - */ -define('XML_SERIALIZER_OPTION_XML_DECL_ENABLED', 'addDecl'); - -/** - * option: encoding of the document - * - * Possible values: - * - any valid encoding - * - null (default) - */ -define('XML_SERIALIZER_OPTION_XML_ENCODING', 'encoding'); - -/** - * option: default name for tags - * - * Possible values: - * - any string (XML_Serializer_Tag is default) - */ -define('XML_SERIALIZER_OPTION_DEFAULT_TAG', 'defaultTagName'); - -/** - * option: use classname for objects in indexed arrays - * - * Possible values: - * - true - * - false (default) - */ -define('XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME', 'classAsTagName'); - -/** - * option: attribute where original key is stored - * - * Possible values: - * - any string (default is _originalKey) - */ -define('XML_SERIALIZER_OPTION_ATTRIBUTE_KEY', 'keyAttribute'); - -/** - * option: attribute for type (only if typeHints => true) - * - * Possible values: - * - any string (default is _type) - */ -define('XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE', 'typeAttribute'); - -/** - * option: attribute for class (only if typeHints => true) - * - * Possible values: - * - any string (default is _class) - */ -define('XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS', 'classAttribute'); - -/** - * option: scalar values (strings, ints,..) will be serialized as attribute - * - * Possible values: - * - true - * - false (default) - * - array which sets this option on a per-tag basis - */ -define('XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES', 'scalarAsAttributes'); - -/** - * option: prepend string for attributes - * - * Possible values: - * - any string (default is any string) - */ -define('XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES', 'prependAttributes'); - -/** - * option: indent the attributes, if set to '_auto', - * it will indent attributes so they all start at the same column - * - * Possible values: - * - true - * - false (default) - * - '_auto' - */ -define('XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES', 'indentAttributes'); - -/** - * option: use 'simplexml' to use parent name as tagname - * if transforming an indexed array - * - * Possible values: - * - XML_SERIALIZER_MODE_DEFAULT (default) - * - XML_SERIALIZER_MODE_SIMPLEXML - */ -define('XML_SERIALIZER_OPTION_MODE', 'mode'); - -/** - * option: add a doctype declaration - * - * Possible values: - * - true - * - false (default) - */ -define('XML_SERIALIZER_OPTION_DOCTYPE_ENABLED', 'addDoctype'); - -/** - * option: supply a string or an array with id and uri - * ({@see XML_Util::getDoctypeDeclaration()} - * - * Possible values: - * - string - * - array - */ -define('XML_SERIALIZER_OPTION_DOCTYPE', 'doctype'); - -/** - * option: name of the root tag - * - * Possible values: - * - string - * - null (default) - */ -define('XML_SERIALIZER_OPTION_ROOT_NAME', 'rootName'); - -/** - * option: attributes of the root tag - * - * Possible values: - * - array - */ -define('XML_SERIALIZER_OPTION_ROOT_ATTRIBS', 'rootAttributes'); - -/** - * option: all values in this key will be treated as attributes - * - * Possible values: - * - string - */ -define('XML_SERIALIZER_OPTION_ATTRIBUTES_KEY', 'attributesArray'); - -/** - * option: this value will be used directly as content, - * instead of creating a new tag, may only be used - * in conjuction with attributesArray - * - * Possible values: - * - string - * - null (default) - */ -define('XML_SERIALIZER_OPTION_CONTENT_KEY', 'contentName'); - -/** - * option: this value will be used in a comment, instead of creating a new tag - * - * Possible values: - * - string - * - null (default) - */ -define('XML_SERIALIZER_OPTION_COMMENT_KEY', 'commentName'); - -/** - * option: tag names that will be changed - * - * Possible values: - * - array - */ -define('XML_SERIALIZER_OPTION_TAGMAP', 'tagMap'); - -/** - * option: function that will be applied before serializing - * - * Possible values: - * - any valid PHP callback - */ -define('XML_SERIALIZER_OPTION_ENCODE_FUNC', 'encodeFunction'); - -/** - * option: namespace to use for the document - * - * Possible values: - * - string - * - null (default) - */ -define('XML_SERIALIZER_OPTION_NAMESPACE', 'namespace'); - -/** - * option: type of entities to replace - * - * Possible values: - * - XML_SERIALIZER_ENTITIES_NONE - * - XML_SERIALIZER_ENTITIES_XML (default) - * - XML_SERIALIZER_ENTITIES_XML_REQUIRED - * - XML_SERIALIZER_ENTITIES_HTML - */ -define('XML_SERIALIZER_OPTION_ENTITIES', 'replaceEntities'); - -/** - * option: whether to return the result of the serialization from serialize() - * - * Possible values: - * - true - * - false (default) - */ -define('XML_SERIALIZER_OPTION_RETURN_RESULT', 'returnResult'); - -/** - * option: whether to ignore properties that are set to null - * - * Possible values: - * - true - * - false (default) - */ -define('XML_SERIALIZER_OPTION_IGNORE_NULL', 'ignoreNull'); - -/** - * option: whether to use cdata sections for character data - * - * Possible values: - * - true - * - false (default) - */ -define('XML_SERIALIZER_OPTION_CDATA_SECTIONS', 'cdata'); - -/** - * option: whether a boolean FALSE value should become a string - * - * Possible values: - * - true - * - false (default) - * - * @since 0.20.0 - */ -define('XML_SERIALIZER_OPTION_FALSE_AS_STRING', 'falseAsString'); - -/** - * default mode - */ -define('XML_SERIALIZER_MODE_DEFAULT', 'default'); - -/** - * SimpleXML mode - * - * When serializing indexed arrays, the key of the parent value is used as a tagname. - */ -define('XML_SERIALIZER_MODE_SIMPLEXML', 'simplexml'); - -/** - * error code for no serialization done - */ -define('XML_SERIALIZER_ERROR_NO_SERIALIZATION', 51); - -/** - * do not replace entitites - */ -define('XML_SERIALIZER_ENTITIES_NONE', XML_UTIL_ENTITIES_NONE); - -/** - * replace all XML entitites - * This setting will replace <, >, ", ' and & - */ -define('XML_SERIALIZER_ENTITIES_XML', XML_UTIL_ENTITIES_XML); - -/** - * replace only required XML entitites - * This setting will replace <, " and & - */ -define('XML_SERIALIZER_ENTITIES_XML_REQUIRED', XML_UTIL_ENTITIES_XML_REQUIRED); - -/** - * replace HTML entitites - * @link http://www.php.net/htmlentities - */ -define('XML_SERIALIZER_ENTITIES_HTML', XML_UTIL_ENTITIES_HTML); - -/** - * Creates XML documents from PHP data structures like arrays, objects or scalars. - * - * This class can be used in two modes: - * - * 1. Create an XML document from an array or object that is processed by other - * applications. That means you can create an RDF document from an array in the - * following format: - * - * $data = array( - * 'channel' => array( - * 'title' => 'Example RDF channel', - * 'link' => 'http://www.php-tools.de', - * 'image' => array( - * 'title' => 'Example image', - * 'url' => 'http://www.php-tools.de/image.gif', - * 'link' => 'http://www.php-tools.de' - * ), - * array( - * 'title' => 'Example item', - * 'link' => 'http://example.com' - * ), - * array( - * 'title' => 'Another Example item', - * 'link' => 'http://example.org' - * ) - * ) - * ); - * - * - * To create an RDF document from this array, do the following: - * - * - * require_once 'XML/Serializer.php'; - * $options = array( - * XML_SERIALIZER_OPTION_INDENT => "\t", // indent with tabs - * XML_SERIALIZER_OPTION_LINEBREAKS => "\n", // use UNIX line breaks - * XML_SERIALIZER_OPTION_ROOT_NAME => 'rdf:RDF',// root tag - * XML_SERIALIZER_OPTION_DEFAULT_TAG => 'item' // tag for values - * // with numeric keys - * ); - * $serializer = new XML_Serializer($options); - * $rdf = $serializer->serialize($data); - * - * - * You will get a complete XML document that can be processed like any RDF document. - * - * 2. This class can be used to serialize any data structure in a way that it can - * later be unserialized again. XML_Serializer will store the type of the value - * and additional meta information in attributes of the surrounding tag. This - * meta information can later be used to restore the original data structure - * in PHP. If you want XML_Serializer to add meta information to the tags, add - * - * XML_SERIALIZER_OPTION_TYPEHINTS => true - * - * to the options array in the constructor. - * - * @category XML - * @package XML_Serializer - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/XML_Serializer - * @see XML_Unserializer - * @todo replace extending PEAR class with instead using a PEAR_Error object - */ -class XML_Serializer extends PEAR -{ - /** - * List of all available options - * - * @access private - * @var array - */ - var $_knownOptions = array( - XML_SERIALIZER_OPTION_INDENT, - XML_SERIALIZER_OPTION_LINEBREAKS, - XML_SERIALIZER_OPTION_TYPEHINTS, - XML_SERIALIZER_OPTION_XML_DECL_ENABLED, - XML_SERIALIZER_OPTION_XML_ENCODING, - XML_SERIALIZER_OPTION_DEFAULT_TAG, - XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME, - XML_SERIALIZER_OPTION_ATTRIBUTE_KEY, - XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE, - XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS, - XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES, - XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES, - XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES, - XML_SERIALIZER_OPTION_MODE, - XML_SERIALIZER_OPTION_DOCTYPE_ENABLED, - XML_SERIALIZER_OPTION_DOCTYPE, - XML_SERIALIZER_OPTION_ROOT_NAME, - XML_SERIALIZER_OPTION_ROOT_ATTRIBS, - XML_SERIALIZER_OPTION_ATTRIBUTES_KEY, - XML_SERIALIZER_OPTION_CONTENT_KEY, - XML_SERIALIZER_OPTION_COMMENT_KEY, - XML_SERIALIZER_OPTION_TAGMAP, - XML_SERIALIZER_OPTION_ENCODE_FUNC, - XML_SERIALIZER_OPTION_NAMESPACE, - XML_SERIALIZER_OPTION_ENTITIES, - XML_SERIALIZER_OPTION_RETURN_RESULT, - XML_SERIALIZER_OPTION_IGNORE_NULL, - XML_SERIALIZER_OPTION_CDATA_SECTIONS, - ); - - /** - * Default options for the serialization - * - * @access private - * @var array - */ - var $_defaultOptions = array( - - // string used for indentation - XML_SERIALIZER_OPTION_INDENT => '', - - // string used for newlines - XML_SERIALIZER_OPTION_LINEBREAKS => "\n", - - // automatically add type hin attributes - XML_SERIALIZER_OPTION_TYPEHINTS => false, - - // add an XML declaration - XML_SERIALIZER_OPTION_XML_DECL_ENABLED => false, - - // encoding specified in the XML declaration - XML_SERIALIZER_OPTION_XML_ENCODING => null, - - // tag used for indexed arrays or invalid names - XML_SERIALIZER_OPTION_DEFAULT_TAG => 'XML_Serializer_Tag', - - // use classname for objects in indexed arrays - XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME => false, - - // attribute where original key is stored - XML_SERIALIZER_OPTION_ATTRIBUTE_KEY => '_originalKey', - - // attribute for type (only if typeHints => true) - XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE => '_type', - - // attribute for class of objects (only if typeHints => true) - XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS => '_class', - - // scalar values (strings, ints,..) will be serialized as attribute - XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES => false, - - // prepend string for attributes - XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES => '', - - // indent the attributes, if set to '_auto', - // it will indent attributes so they all start at the same column - XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES => false, - - // use XML_SERIALIZER_MODE_SIMPLEXML to use parent name as tagname - // if transforming an indexed array - XML_SERIALIZER_OPTION_MODE => XML_SERIALIZER_MODE_DEFAULT, - - // add a doctype declaration - XML_SERIALIZER_OPTION_DOCTYPE_ENABLED => false, - - // supply a string or an array with id and uri - // ({@see XML_Util::getDoctypeDeclaration()} - XML_SERIALIZER_OPTION_DOCTYPE => null, - - // name of the root tag - XML_SERIALIZER_OPTION_ROOT_NAME => null, - - // attributes of the root tag - XML_SERIALIZER_OPTION_ROOT_ATTRIBS => array(), - - // all values in this key will be treated as attributes - XML_SERIALIZER_OPTION_ATTRIBUTES_KEY => null, - - // this value will be used directly as content, - // instead of creating a new tag, may only be used - // in conjuction with attributesArray - XML_SERIALIZER_OPTION_CONTENT_KEY => null, - - // this value will be used directly as comment, - // instead of creating a new tag, may only be used - // in conjuction with attributesArray - XML_SERIALIZER_OPTION_COMMENT_KEY => null, - - // tag names that will be changed - XML_SERIALIZER_OPTION_TAGMAP => array(), - - // function that will be applied before serializing - XML_SERIALIZER_OPTION_ENCODE_FUNC => null, - - // namespace to use - XML_SERIALIZER_OPTION_NAMESPACE => null, - - // type of entities to replace, - XML_SERIALIZER_OPTION_ENTITIES => XML_SERIALIZER_ENTITIES_XML, - - // serialize() returns the result of the serialization instead of true - XML_SERIALIZER_OPTION_RETURN_RESULT => false, - - // ignore properties that are set to null - XML_SERIALIZER_OPTION_IGNORE_NULL => false, - - // Whether to use cdata sections for plain character data - XML_SERIALIZER_OPTION_CDATA_SECTIONS => false, - - // Whether to convert a boolean FALSE into a string - XML_SERIALIZER_OPTION_FALSE_AS_STRING => false, - ); - - /** - * Options for the serialization - * - * @access public - * @var array - */ - var $options = array(); - - /** - * Current tag depth - * - * @access private - * @var integer - */ - var $_tagDepth = 0; - - /** - * Serialized representation of the data - * - * @access private - * @var string - */ - var $_serializedData = null; - - /** - * Constructor - * - * @param mixed $options array containing options for the serialization - * - * @access public - */ - function XML_Serializer( $options = null ) - { - $this->PEAR(); - if (is_array($options)) { - $this->options = array_merge($this->_defaultOptions, $options); - } else { - $this->options = $this->_defaultOptions; - } - } - - /** - * Return the package version number - * - * @access public - * @static - * @return string the version number of XML_Serializer - */ - function apiVersion() - { - return '@package_version@'; - } - - /** - * Reset all options to default options - * - * @return void - * @access public - */ - function resetOptions() - { - $this->options = $this->_defaultOptions; - } - - /** - * Set an option - * - * You can use this method if you do not want - * to set all options in the constructor. - * - * @param string $name option name - * @param mixed $value option value - * - * @return void - * @access public - */ - function setOption($name, $value) - { - $this->options[$name] = $value; - } - - /** - * Sets several options at once - * - * You can use this method if you do not want - * to set all options in the constructor. - * - * @param array $options options array - * - * @return void - * @access public - */ - function setOptions($options) - { - $this->options = array_merge($this->options, $options); - } - - /** - * serialize data - * - * @param mixed $data data to serialize - * @param array $options options array - * - * @return boolean true on success, pear error on failure - * @access public - * @uses XML_Util::getDoctypeDeclaration() - * @uses XML_Util::getXMLDeclaration() - * @internal uses error suppression "@settype()" - */ - function serialize($data, $options = null) - { - // if options have been specified, use them instead - // of the previously defined ones - if (is_array($options)) { - $optionsBak = $this->options; - if (isset($options['overrideOptions']) - && $options['overrideOptions'] == true - ) { - $this->options = array_merge($this->_defaultOptions, $options); - } else { - $this->options = array_merge($this->options, $options); - } - } else { - $optionsBak = null; - } - - // start depth is zero - $this->_tagDepth = 0; - - $rootAttributes = $this->options[XML_SERIALIZER_OPTION_ROOT_ATTRIBS]; - if (isset($this->options[XML_SERIALIZER_OPTION_NAMESPACE]) - && is_array($this->options[XML_SERIALIZER_OPTION_NAMESPACE]) - ) { - $rootAttributes['xmlns:' - . $this->options[XML_SERIALIZER_OPTION_NAMESPACE][0]] = - $this->options[XML_SERIALIZER_OPTION_NAMESPACE][1]; - } - - $this->_serializedData = ''; - // serialize an array - if (is_array($data)) { - if (isset($this->options[XML_SERIALIZER_OPTION_ROOT_NAME])) { - $tagName = $this->options[XML_SERIALIZER_OPTION_ROOT_NAME]; - } else { - $tagName = 'array'; - } - - $this->_serializedData .= - $this->_serializeArray($data, $tagName, $rootAttributes); - } elseif (is_object($data)) { - // serialize an object - if (isset($this->options[XML_SERIALIZER_OPTION_ROOT_NAME])) { - $tagName = $this->options[XML_SERIALIZER_OPTION_ROOT_NAME]; - } else { - $tagName = get_class($data); - } - $this->_serializedData .= - $this->_serializeObject($data, $tagName, $rootAttributes); - } else { - $tag = array(); - if (isset($this->options[XML_SERIALIZER_OPTION_ROOT_NAME])) { - $tag['qname'] = $this->options[XML_SERIALIZER_OPTION_ROOT_NAME]; - } else { - $tag['qname'] = gettype($data); - } - $tagName = $tag['qname']; - if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { - $rootAttributes[$this-> - options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = gettype($data); - } - - if (!is_bool($data)) { - $tag['content'] = $data; - } elseif ($data === false) { - if ($this->options[XML_SERIALIZER_OPTION_FALSE_AS_STRING] === true) { - $tag['content'] = '0'; - } else { - $tag['content'] = ''; - } - } else { - $tag['content'] = $data; - } - - @settype($data, 'string'); - $tag['attributes'] = $rootAttributes; - $this->_serializedData = $this->_createXMLTag($tag); - } - - // add doctype declaration - if ($this->options[XML_SERIALIZER_OPTION_DOCTYPE_ENABLED] === true) { - $this->_serializedData = - XML_Util::getDoctypeDeclaration($tagName, - $this->options[XML_SERIALIZER_OPTION_DOCTYPE]) - . $this->options[XML_SERIALIZER_OPTION_LINEBREAKS] - . $this->_serializedData; - } - - // build xml declaration - if ($this->options[XML_SERIALIZER_OPTION_XML_DECL_ENABLED]) { - $atts = array(); - $this->_serializedData = XML_Util::getXMLDeclaration('1.0', - $this->options[XML_SERIALIZER_OPTION_XML_ENCODING]) - . $this->options[XML_SERIALIZER_OPTION_LINEBREAKS] - . $this->_serializedData; - } - - if ($this->options[XML_SERIALIZER_OPTION_RETURN_RESULT] === true) { - $result = $this->_serializedData; - } else { - $result = true; - } - - if ($optionsBak !== null) { - $this->options = $optionsBak; - } - - return $result; - } - - /** - * get the result of the serialization - * - * @access public - * @return string serialized XML - */ - function getSerializedData() - { - if ($this->_serializedData == null) { - return $this->raiseError('No serialized data available. ' - . 'Use XML_Serializer::serialize() first.', - XML_SERIALIZER_ERROR_NO_SERIALIZATION); - } - return $this->_serializedData; - } - - /** - * serialize any value - * - * This method checks for the type of the value and calls the appropriate method - * - * @param mixed $value tag value - * @param string $tagName tag name - * @param array $attributes attributes - * - * @return string - * @access private - */ - function _serializeValue($value, $tagName = null, $attributes = array()) - { - if (is_array($value)) { - $xml = $this->_serializeArray($value, $tagName, $attributes); - } elseif (is_object($value)) { - $xml = $this->_serializeObject($value, $tagName); - } else { - $tag = array( - 'qname' => $tagName, - 'attributes' => $attributes, - 'content' => $value - ); - $xml = $this->_createXMLTag($tag); - } - return $xml; - } - - /** - * serialize an array - * - * @param array &$array array to serialize - * @param string $tagName name of the root tag - * @param array $attributes attributes for the root tag - * - * @return string $string serialized data - * @access private - * @uses XML_Util::isValidName() to check, whether key has to be substituted - * @uses XML_Util::replaceEntities() - * @uses XML_Util::createComment() - * @uses PEAR::popExpect() - * @uses PEAR::expectError() - */ - function _serializeArray(&$array, $tagName = null, $attributes = array()) - { - $_content = null; - $_comment = null; - - // check for comment - if ($this->options[XML_SERIALIZER_OPTION_COMMENT_KEY] !== null) { - if (isset($array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]]) - ) { - $_comment = - $array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]]; - unset($array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]]); - } - } - - /** - * check for special attributes - */ - if ($this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY] !== null) { - if (isset($array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]]) - ) { - $attributes = - $array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]]; - unset($array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]]); - } - /** - * check for special content - */ - if ($this->options[XML_SERIALIZER_OPTION_CONTENT_KEY] !== null) { - if (isset($array[$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]]) - ) { - $_content = - XML_Util::replaceEntities($array - [$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]]); - unset($array[$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]]); - } - } - } - - if ($this->options[XML_SERIALIZER_OPTION_IGNORE_NULL] === true) { - foreach (array_keys($array) as $key) { - if (is_null($array[$key])) { - unset($array[$key]); - } - } - } - - /* - * if mode is set to simpleXML, check whether - * the array is associative or indexed - */ - if (is_array($array) && !empty($array) - && $this->options[XML_SERIALIZER_OPTION_MODE] - == XML_SERIALIZER_MODE_SIMPLEXML - ) { - $indexed = true; - foreach ($array as $key => $val) { - if (!is_int($key)) { - $indexed = false; - break; - } - } - - if ($indexed - && $this->options[XML_SERIALIZER_OPTION_MODE] - == XML_SERIALIZER_MODE_SIMPLEXML - ) { - $string = ''; - foreach ($array as $key => $val) { - $string .= $this->_serializeValue($val, $tagName, $attributes); - - $string .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; - // do indentation - if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null - && $this->_tagDepth>0 - ) { - $string .= - str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], - $this->_tagDepth); - } - } - return rtrim($string); - } - } - - $scalarAsAttributes = false; - if (is_array($this->options[XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES]) - && isset($this->options[XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES] - [$tagName]) - ) { - $scalarAsAttributes = - $this->options[XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES][$tagName]; - } elseif ($this->options[XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES] === true - ) { - $scalarAsAttributes = true; - } - - if ($scalarAsAttributes === true) { - $this->expectError('*'); - foreach ($array as $key => $value) { - if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { - unset($array[$key]); - $attributes[$this->options - [XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES].$key] = $value; - } - } - $this->popExpect(); - } elseif (is_array($scalarAsAttributes)) { - $this->expectError('*'); - foreach ($scalarAsAttributes as $key) { - if (!isset($array[$key])) { - continue; - } - $value = $array[$key]; - if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { - unset($array[$key]); - $attributes[$this->options - [XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES].$key] = $value; - } - } - $this->popExpect(); - } - - // check for empty array => create empty tag - if (empty($array)) { - $tag = array( - 'qname' => $tagName, - 'content' => $_content, - 'attributes' => $attributes - ); - } else { - $this->_tagDepth++; - $tmp = $_content . $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; - foreach ($array as $key => $value) { - // do indentation - if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null - && $this->_tagDepth>0 - ) { - $tmp .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], - $this->_tagDepth); - } - - // copy key - $origKey = $key; - $this->expectError('*'); - // key cannot be used as tagname => use default tag - $valid = XML_Util::isValidName($key); - $this->popExpect(); - if (PEAR::isError($valid)) { - if ($this->options[XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME] - && is_object($value) - ) { - $key = get_class($value); - } else { - $key = $this->_getDefaultTagname($tagName); - } - } - - // once we've established the true $key, is there a tagmap for it? - if (isset($this->options[XML_SERIALIZER_OPTION_TAGMAP][$key])) { - $key = $this->options[XML_SERIALIZER_OPTION_TAGMAP][$key]; - } - - $atts = array(); - if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { - $atts[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = - gettype($value); - if ($key !== $origKey) { - $atts[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_KEY]] = - (string)$origKey; - } - } - - $tmp .= $this->_createXMLTag(array( - 'qname' => $key, - 'attributes' => $atts, - 'content' => $value - )); - $tmp .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; - } - - $this->_tagDepth--; - if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null - && $this->_tagDepth>0 - ) { - $tmp .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], - $this->_tagDepth); - } - - if (trim($tmp) === '') { - $tmp = null; - } - - $tag = array( - 'qname' => $tagName, - 'content' => $tmp, - 'attributes' => $attributes - ); - } - if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { - if (!isset($tag['attributes'] - [$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]]) - ) { - $tag['attributes'] - [$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = 'array'; - } - } - - $string = ''; - if (!is_null($_comment)) { - $string .= XML_Util::createComment($_comment); - $string .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; - if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null - && $this->_tagDepth>0 - ) { - $string .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], - $this->_tagDepth); - } - } - $string .= $this->_createXMLTag($tag, false); - return $string; - } - - /** - * get the name of the default tag. - * - * The name of the parent tag needs to be passed as the - * default name can depend on the context. - * - * @param string $parent name of the parent tag - * - * @return string default tag name - */ - function _getDefaultTagname($parent) - { - if (is_string($this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG])) { - return $this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG]; - } - if (isset($this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG][$parent])) { - return $this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG][$parent]; - } elseif (isset($this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG] - ['#default']) - ) { - return $this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG]['#default']; - } elseif (isset($this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG] - ['__default']) - ) { - // keep this for BC - return $this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG]['__default']; - } - return 'XML_Serializer_Tag'; - } - - /** - * serialize an object - * - * @param object &$object object to serialize - * @param string $tagName tag name - * @param array $attributes attributes - * - * @return string $string serialized data - * @access private - */ - function _serializeObject(&$object, $tagName = null, $attributes = array()) - { - // check for magic function - if (method_exists($object, '__sleep')) { - $propNames = $object->__sleep(); - if (is_array($propNames)) { - $properties = array(); - foreach ($propNames as $propName) { - $properties[$propName] = $object->$propName; - } - } else { - $properties = get_object_vars($object); - } - } else { - $properties = get_object_vars($object); - } - - if (empty($tagName)) { - $tagName = get_class($object); - } - - // typehints activated? - if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { - $attributes[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = - 'object'; - $attributes[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS]] = - get_class($object); - } - $string = $this->_serializeArray($properties, $tagName, $attributes); - return $string; - } - - /** - * create a tag from an array - * this method awaits an array in the following format - * array( - * 'qname' => $tagName, - * 'attributes' => array(), - * 'content' => $content, // optional - * 'namespace' => $namespace // optional - * 'namespaceUri' => $namespaceUri // optional - * ) - * - * @param array $tag tag definition - * @param boolean $firstCall whether or not this is the first call - * - * @return string $string XML tag - * @access private - */ - function _createXMLTag($tag, $firstCall = true) - { - // build fully qualified tag name - if ($this->options[XML_SERIALIZER_OPTION_NAMESPACE] !== null) { - if (is_array($this->options[XML_SERIALIZER_OPTION_NAMESPACE])) { - $tag['qname'] = $this->options[XML_SERIALIZER_OPTION_NAMESPACE][0] - . ':' . $tag['qname']; - } else { - $tag['qname'] = $this->options[XML_SERIALIZER_OPTION_NAMESPACE] - . ':' . $tag['qname']; - } - } - - // attribute indentation - if ($this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES] !== false) { - $multiline = true; - $indent = str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], - $this->_tagDepth); - - if ($this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES] == '_auto') { - $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); - - } else { - $indent .= $this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES]; - } - } else { - $multiline = false; - $indent = false; - } - - if (is_array($tag['content'])) { - if (empty($tag['content'])) { - $tag['content'] = ''; - } -} elseif (XML_SERIALIZER_OPTION_FALSE_AS_STRING && $tag['content'] === false) { -$tag['content'] = '0'; - } elseif (is_scalar($tag['content']) && (string)$tag['content'] == '') { - $tag['content'] = ''; - } - - // replace XML entities - if ($firstCall === true) { - if ($this->options[XML_SERIALIZER_OPTION_CDATA_SECTIONS] === true) { - $replaceEntities = XML_UTIL_CDATA_SECTION; - } else { - $replaceEntities = $this->options[XML_SERIALIZER_OPTION_ENTITIES]; - } - } else { - // this is a nested call, so value is already encoded - // and must not be encoded again - $replaceEntities = XML_SERIALIZER_ENTITIES_NONE; - // but attributes need to be encoded anyways - // (done here because the rest of the code assumes the same encoding - // can be used both for attributes and content) - foreach ($tag['attributes'] as $k => $v) { - $v = XML_Util::replaceEntities($v, - $this->options[XML_SERIALIZER_OPTION_ENTITIES]); - - $tag['attributes'][$k] = $v; - } - } - if (is_scalar($tag['content']) || is_null($tag['content'])) { - if ($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC]) { - if ($firstCall === true) { - $tag['content'] = call_user_func($this-> - options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['content']); - } - $tag['attributes'] = array_map($this-> - options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['attributes']); - } - $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, - $indent, $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]); - } elseif (is_array($tag['content'])) { - $tag = $this->_serializeArray($tag['content'], $tag['qname'], - $tag['attributes']); - } elseif (is_object($tag['content'])) { - $tag = $this->_serializeObject($tag['content'], $tag['qname'], - $tag['attributes']); - } elseif (is_resource($tag['content'])) { - settype($tag['content'], 'string'); - if ($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC]) { - if ($replaceEntities === true) { - $tag['content'] = call_user_func($this-> - options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['content']); - } - $tag['attributes'] = array_map($this-> - options[XML_SERIALIZER_OPTION_ENCODE_FUNC], - $tag['attributes']); - } - $tag = XML_Util::createTagFromArray($tag, $replaceEntities); - } - return $tag; - } -} -?> diff --git a/data/module/XML/Unserializer.php b/data/module/XML/Unserializer.php deleted file mode 100644 index 56ef8fe704..0000000000 --- a/data/module/XML/Unserializer.php +++ /dev/null @@ -1,983 +0,0 @@ - - * 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. - * * The name of the author 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 XML - * @package XML_Serializer - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Unserializer.php 303099 2010-09-06 16:23:06Z clockwerx $ - * @link http://pear.php.net/package/XML_Serializer - * @see XML_Unserializer - */ - -/** - * uses PEAR error managemt - */ -require_once 'PEAR.php'; - -/** - * uses XML_Parser to unserialize document - */ -require_once 'XML/Parser.php'; - -/** - * option: Convert nested tags to array or object - * - * Possible values: - * - array - * - object - * - associative array to define this option per tag name - */ -define('XML_UNSERIALIZER_OPTION_COMPLEXTYPE', 'complexType'); - -/** - * option: Name of the attribute that stores the original key - * - * Possible values: - * - any string - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY', 'keyAttribute'); - -/** - * option: Name of the attribute that stores the type - * - * Possible values: - * - any string - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE', 'typeAttribute'); - -/** - * option: Name of the attribute that stores the class name - * - * Possible values: - * - any string - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS', 'classAttribute'); - -/** - * option: Whether to use the tag name as a class name - * - * Possible values: - * - true or false - */ -define('XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME', 'tagAsClass'); - -/** - * option: Name of the default class - * - * Possible values: - * - any string - */ -define('XML_UNSERIALIZER_OPTION_DEFAULT_CLASS', 'defaultClass'); - -/** - * option: Whether to parse attributes - * - * Possible values: - * - true or false - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE', 'parseAttributes'); - -/** - * option: Key of the array to store attributes (if any) - * - * Possible values: - * - any string - * - false (disabled) - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY', 'attributesArray'); - -/** - * option: string to prepend attribute name (if any) - * - * Possible values: - * - any string - * - false (disabled) - */ -define('XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND', 'prependAttributes'); - -/** - * option: key to store the content, - * if XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE is used - * - * Possible values: - * - any string - */ -define('XML_UNSERIALIZER_OPTION_CONTENT_KEY', 'contentName'); - -/** - * option: map tag names - * - * Possible values: - * - associative array - */ -define('XML_UNSERIALIZER_OPTION_TAG_MAP', 'tagMap'); - -/** - * option: list of tags that will always be enumerated - * - * Possible values: - * - indexed array - */ -define('XML_UNSERIALIZER_OPTION_FORCE_ENUM', 'forceEnum'); - -/** - * option: Encoding of the XML document - * - * Possible values: - * - UTF-8 - * - ISO-8859-1 - */ -define('XML_UNSERIALIZER_OPTION_ENCODING_SOURCE', 'encoding'); - -/** - * option: Desired target encoding of the data - * - * Possible values: - * - UTF-8 - * - ISO-8859-1 - */ -define('XML_UNSERIALIZER_OPTION_ENCODING_TARGET', 'targetEncoding'); - -/** - * option: Callback that will be applied to textual data - * - * Possible values: - * - any valid PHP callback - */ -define('XML_UNSERIALIZER_OPTION_DECODE_FUNC', 'decodeFunction'); - -/** - * option: whether to return the result of the unserialization from unserialize() - * - * Possible values: - * - true - * - false (default) - */ -define('XML_UNSERIALIZER_OPTION_RETURN_RESULT', 'returnResult'); - -/** - * option: set the whitespace behaviour - * - * Possible values: - * - XML_UNSERIALIZER_WHITESPACE_KEEP - * - XML_UNSERIALIZER_WHITESPACE_TRIM - * - XML_UNSERIALIZER_WHITESPACE_NORMALIZE - */ -define('XML_UNSERIALIZER_OPTION_WHITESPACE', 'whitespace'); - -/** - * Keep all whitespace - */ -define('XML_UNSERIALIZER_WHITESPACE_KEEP', 'keep'); - -/** - * remove whitespace from start and end of the data - */ -define('XML_UNSERIALIZER_WHITESPACE_TRIM', 'trim'); - -/** - * normalize whitespace - */ -define('XML_UNSERIALIZER_WHITESPACE_NORMALIZE', 'normalize'); - -/** - * option: whether to ovverride all options that have been set before - * - * Possible values: - * - true - * - false (default) - */ -define('XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS', 'overrideOptions'); - -/** - * option: list of tags, that will not be used as keys - */ -define('XML_UNSERIALIZER_OPTION_IGNORE_KEYS', 'ignoreKeys'); - -/** - * option: whether to use type guessing for scalar values - */ -define('XML_UNSERIALIZER_OPTION_GUESS_TYPES', 'guessTypes'); - -/** - * error code for no serialization done - */ -define('XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION', 151); - -/** - * XML_Unserializer - * - * class to unserialize XML documents that have been created with - * XML_Serializer. To unserialize an XML document you have to add - * type hints to the XML_Serializer options. - * - * If no type hints are available, XML_Unserializer will guess how - * the tags should be treated, that means complex structures will be - * arrays and tags with only CData in them will be strings. - * - * - * require_once 'XML/Unserializer.php'; - * - * // be careful to always use the ampersand in front of the new operator - * $unserializer = &new XML_Unserializer(); - * - * $unserializer->unserialize($xml); - * - * $data = $unserializer->getUnserializedData(); - * - * - * @category XML - * @package XML_Serializer - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/XML_Serializer - * @see XML_Serializer - */ -class XML_Unserializer extends PEAR -{ - /** - * list of all available options - * - * @access private - * @var array - */ - var $_knownOptions = array( - XML_UNSERIALIZER_OPTION_COMPLEXTYPE, - XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY, - XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE, - XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS, - XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME, - XML_UNSERIALIZER_OPTION_DEFAULT_CLASS, - XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE, - XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY, - XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND, - XML_UNSERIALIZER_OPTION_CONTENT_KEY, - XML_UNSERIALIZER_OPTION_TAG_MAP, - XML_UNSERIALIZER_OPTION_FORCE_ENUM, - XML_UNSERIALIZER_OPTION_ENCODING_SOURCE, - XML_UNSERIALIZER_OPTION_ENCODING_TARGET, - XML_UNSERIALIZER_OPTION_DECODE_FUNC, - XML_UNSERIALIZER_OPTION_RETURN_RESULT, - XML_UNSERIALIZER_OPTION_WHITESPACE, - XML_UNSERIALIZER_OPTION_IGNORE_KEYS, - XML_UNSERIALIZER_OPTION_GUESS_TYPES - ); - /** - * default options for the serialization - * - * @access private - * @var array - */ - var $_defaultOptions = array( - // complex types will be converted to arrays, if no type hint is given - XML_UNSERIALIZER_OPTION_COMPLEXTYPE => 'array', - - // get array key/property name from this attribute - XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY => '_originalKey', - - // get type from this attribute - XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE => '_type', - - // get class from this attribute (if not given, use tag name) - XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS => '_class', - - // use the tagname as the classname - XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME => true, - - // name of the class that is used to create objects - XML_UNSERIALIZER_OPTION_DEFAULT_CLASS => 'stdClass', - - // parse the attributes of the tag into an array - XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE => false, - - // parse them into sperate array (specify name of array here) - XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY => false, - - // prepend attribute names with this string - XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND => '', - - // put cdata found in a tag that has been converted - // to a complex type in this key - XML_UNSERIALIZER_OPTION_CONTENT_KEY => '_content', - - // use this to map tagnames - XML_UNSERIALIZER_OPTION_TAG_MAP => array(), - - // these tags will always be an indexed array - XML_UNSERIALIZER_OPTION_FORCE_ENUM => array(), - - // specify the encoding character of the document to parse - XML_UNSERIALIZER_OPTION_ENCODING_SOURCE => null, - - // specify the target encoding - XML_UNSERIALIZER_OPTION_ENCODING_TARGET => null, - - // function used to decode data - XML_UNSERIALIZER_OPTION_DECODE_FUNC => null, - - // unserialize() returns the result of the unserialization instead of true - XML_UNSERIALIZER_OPTION_RETURN_RESULT => false, - - // remove whitespace around data - XML_UNSERIALIZER_OPTION_WHITESPACE => XML_UNSERIALIZER_WHITESPACE_TRIM, - - // List of tags that will automatically be added to the parent, - // instead of adding a new key - XML_UNSERIALIZER_OPTION_IGNORE_KEYS => array(), - - // Whether to use type guessing - XML_UNSERIALIZER_OPTION_GUESS_TYPES => false - ); - - /** - * current options for the serialization - * - * @access public - * @var array - */ - var $options = array(); - - /** - * unserialized data - * - * @access private - * @var string - */ - var $_unserializedData = null; - - /** - * name of the root tag - * - * @access private - * @var string - */ - var $_root = null; - - /** - * stack for all data that is found - * - * @access private - * @var array - */ - var $_dataStack = array(); - - /** - * stack for all values that are generated - * - * @access private - * @var array - */ - var $_valStack = array(); - - /** - * current tag depth - * - * @access private - * @var int - */ - var $_depth = 0; - - /** - * XML_Parser instance - * - * @access private - * @var object XML_Parser - */ - var $_parser = null; - - /** - * constructor - * - * @param mixed $options array containing options for the unserialization - * - * @access public - */ - function XML_Unserializer($options = null) - { - if (is_array($options)) { - $this->options = array_merge($this->_defaultOptions, $options); - } else { - $this->options = $this->_defaultOptions; - } - } - - /** - * return API version - * - * @access public - * @return string $version API version - * @static - */ - function apiVersion() - { - return '@package_version@'; - } - - /** - * reset all options to default options - * - * @return void - * @access public - * @see setOption(), XML_Unserializer(), setOptions() - */ - function resetOptions() - { - $this->options = $this->_defaultOptions; - } - - /** - * set an option - * - * You can use this method if you do not want - * to set all options in the constructor - * - * @param string $name name of option - * @param mixed $value value of option - * - * @return void - * @access public - * @see resetOption(), XML_Unserializer(), setOptions() - */ - function setOption($name, $value) - { - $this->options[$name] = $value; - } - - /** - * sets several options at once - * - * You can use this method if you do not want - * to set all options in the constructor - * - * @param array $options options array - * - * @return void - * @access public - * @see resetOption(), XML_Unserializer(), setOption() - */ - function setOptions($options) - { - $this->options = array_merge($this->options, $options); - } - - /** - * unserialize data - * - * @param mixed $data data to unserialize (string, filename or resource) - * @param boolean $isFile data should be treated as a file - * @param array $options options that will override - * the global options for this call - * - * @return boolean $success - * @access public - */ - function unserialize($data, $isFile = false, $options = null) - { - $this->_unserializedData = null; - $this->_root = null; - - // if options have been specified, use them instead - // of the previously defined ones - if (is_array($options)) { - $optionsBak = $this->options; - if (isset($options[XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS]) - && $options[XML_UNSERIALIZER_OPTION_OVERRIDE_OPTIONS] == true - ) { - $this->options = array_merge($this->_defaultOptions, $options); - } else { - $this->options = array_merge($this->options, $options); - } - } else { - $optionsBak = null; - } - - $this->_valStack = array(); - $this->_dataStack = array(); - $this->_depth = 0; - - $this->_createParser(); - - if (is_string($data)) { - if ($isFile) { - $result = $this->_parser->setInputFile($data); - if (PEAR::isError($result)) { - return $result; - } - $result = $this->_parser->parse(); - } else { - $result = $this->_parser->parseString($data, true); - } - } else { - $this->_parser->setInput($data); - $result = $this->_parser->parse(); - } - - if ($this->options[XML_UNSERIALIZER_OPTION_RETURN_RESULT] === true) { - $return = $this->_unserializedData; - } else { - $return = true; - } - - if ($optionsBak !== null) { - $this->options = $optionsBak; - } - - if (PEAR::isError($result)) { - return $result; - } - - return $return; - } - - /** - * get the result of the serialization - * - * @access public - * @return string $serializedData - */ - function getUnserializedData() - { - if ($this->_root === null) { - return $this->raiseError('No unserialized data available. ' - . 'Use XML_Unserializer::unserialize() first.', - XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION); - } - return $this->_unserializedData; - } - - /** - * get the name of the root tag - * - * @access public - * @return string $rootName - */ - function getRootName() - { - if ($this->_root === null) { - return $this->raiseError('No unserialized data available. ' - . 'Use XML_Unserializer::unserialize() first.', - XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION); - } - return $this->_root; - } - - /** - * Start element handler for XML parser - * - * @param object $parser XML parser object - * @param string $element XML element - * @param array $attribs attributes of XML tag - * - * @return void - * @access private - */ - function startHandler($parser, $element, $attribs) - { - if (isset($attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE]]) - ) { - $type = $attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_TYPE]]; - - $guessType = false; - } else { - $type = 'string'; - if ($this->options[XML_UNSERIALIZER_OPTION_GUESS_TYPES] === true) { - $guessType = true; - } else { - $guessType = false; - } - } - - if ($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC] !== null) { - $attribs = array_map($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC], - $attribs); - } - - $this->_depth++; - $this->_dataStack[$this->_depth] = null; - - if (is_array($this->options[XML_UNSERIALIZER_OPTION_TAG_MAP]) - && isset($this->options[XML_UNSERIALIZER_OPTION_TAG_MAP][$element]) - ) { - $element = $this->options[XML_UNSERIALIZER_OPTION_TAG_MAP][$element]; - } - - $val = array( - 'name' => $element, - 'value' => null, - 'type' => $type, - 'guessType' => $guessType, - 'childrenKeys' => array(), - 'aggregKeys' => array() - ); - - if ($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE] == true - && (count($attribs) > 0) - ) { - $val['children'] = array(); - $val['type'] = $this->_getComplexType($element); - $val['class'] = $element; - - if ($this->options[XML_UNSERIALIZER_OPTION_GUESS_TYPES] === true) { - $attribs = $this->_guessAndSetTypes($attribs); - } - if ($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY] != false - ) { - $val['children'][$this-> - options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY]] = $attribs; - } else { - foreach ($attribs as $attrib => $value) { - $val['children'][$this-> - options[XML_UNSERIALIZER_OPTION_ATTRIBUTES_PREPEND] - . $attrib] = $value; - } - } - } - - $keyAttr = false; - - if (is_string($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY])) { - $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY]; - } elseif (is_array($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY])) { - if (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY] - [$element]) - ) { - $keyAttr = - $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY][$element]; - } elseif (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY] - ['#default']) - ) { - $keyAttr = $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY] - ['#default']; - } elseif (isset($this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY] - ['__default']) - ) { - // keep this for BC - $keyAttr = - $this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_KEY] - ['__default']; - } - } - - if ($keyAttr !== false && isset($attribs[$keyAttr])) { - $val['name'] = $attribs[$keyAttr]; - } - - if (isset($attribs[$this-> - options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS]]) - ) { - $val['class'] = - $attribs[$this->options[XML_UNSERIALIZER_OPTION_ATTRIBUTE_CLASS]]; - } - - array_push($this->_valStack, $val); - } - - /** - * Try to guess the type of several values and - * set them accordingly - * - * @param array $array array containing the values - * - * @return array array, containing the values with their correct types - * @access private - */ - function _guessAndSetTypes($array) - { - foreach ($array as $key => $value) { - $array[$key] = $this->_guessAndSetType($value); - } - return $array; - } - - /** - * Try to guess the type of a value and - * set it accordingly - * - * @param string $value character data - * - * @return mixed value with the best matching type - * @access private - */ - function _guessAndSetType($value) - { - if ($value === 'true') { - return true; - } - if ($value === 'false') { - return false; - } - if ($value === 'NULL') { - return null; - } - if (preg_match('/^[-+]?[0-9]{1,}\\z/', $value)) { - return intval($value); - } - if (preg_match('/^[-+]?[0-9]{1,}\.[0-9]{1,}\\z/', $value)) { - return doubleval($value); - } - return (string)$value; - } - - /** - * End element handler for XML parser - * - * @param object $parser XML parser object - * @param string $element element - * - * @return void - * @access private - */ - function endHandler($parser, $element) - { - $value = array_pop($this->_valStack); - switch ($this->options[XML_UNSERIALIZER_OPTION_WHITESPACE]) { - case XML_UNSERIALIZER_WHITESPACE_KEEP: - $data = $this->_dataStack[$this->_depth]; - break; - case XML_UNSERIALIZER_WHITESPACE_NORMALIZE: - $data = trim(preg_replace('/\s\s+/m', ' ', - $this->_dataStack[$this->_depth])); - break; - case XML_UNSERIALIZER_WHITESPACE_TRIM: - default: - $data = trim($this->_dataStack[$this->_depth]); - break; - } - - // adjust type of the value - switch(strtolower($value['type'])) { - - // unserialize an object - case 'object': - if (isset($value['class'])) { - $classname = $value['class']; - } else { - $classname = ''; - } - // instantiate the class - if ($this->options[XML_UNSERIALIZER_OPTION_TAG_AS_CLASSNAME] === true - && class_exists($classname) - ) { - $value['value'] = new $classname; - } else { - $value['value'] = - new $this->options[XML_UNSERIALIZER_OPTION_DEFAULT_CLASS]; - } - if (trim($data) !== '') { - if ($value['guessType'] === true) { - $data = $this->_guessAndSetType($data); - } - $value['children'][$this-> - options[XML_UNSERIALIZER_OPTION_CONTENT_KEY]] = $data; - } - - // set properties - foreach ($value['children'] as $prop => $propVal) { - // check whether there is a special method to set this property - $setMethod = 'set'.$prop; - if (method_exists($value['value'], $setMethod)) { - call_user_func(array(&$value['value'], $setMethod), $propVal); - } else { - $value['value']->$prop = $propVal; - } - } - // check for magic function - if (method_exists($value['value'], '__wakeup')) { - $value['value']->__wakeup(); - } - break; - - // unserialize an array - case 'array': - if (trim($data) !== '') { - if ($value['guessType'] === true) { - $data = $this->_guessAndSetType($data); - } - $value['children'][$this-> - options[XML_UNSERIALIZER_OPTION_CONTENT_KEY]] = $data; - } - if (isset($value['children'])) { - $value['value'] = $value['children']; - } else { - $value['value'] = array(); - } - break; - - // unserialize a null value - case 'null': - $data = null; - break; - - // unserialize a resource => this is not possible :-( - case 'resource': - $value['value'] = $data; - break; - - // unserialize any scalar value - default: - if ($value['guessType'] === true) { - $data = $this->_guessAndSetType($data); - } else { - settype($data, $value['type']); - } - - $value['value'] = $data; - break; - } - $parent = array_pop($this->_valStack); - if ($parent === null) { - $this->_unserializedData = &$value['value']; - $this->_root = &$value['name']; - return true; - } else { - // parent has to be an array - if (!isset($parent['children']) || !is_array($parent['children'])) { - $parent['children'] = array(); - if (!in_array($parent['type'], array('array', 'object'))) { - $parent['type'] = $this->_getComplexType($parent['name']); - if ($parent['type'] == 'object') { - $parent['class'] = $parent['name']; - } - } - } - - if (in_array($element, - $this->options[XML_UNSERIALIZER_OPTION_IGNORE_KEYS]) - ) { - $ignoreKey = true; - } else { - $ignoreKey = false; - } - - if (!empty($value['name']) && $ignoreKey === false) { - // there already has been a tag with this name - if (in_array($value['name'], $parent['childrenKeys']) - || in_array($value['name'], - $this->options[XML_UNSERIALIZER_OPTION_FORCE_ENUM]) - ) { - // no aggregate has been created for this tag - if (!in_array($value['name'], $parent['aggregKeys'])) { - if (isset($parent['children'][$value['name']])) { - $parent['children'][$value['name']] = - array($parent['children'][$value['name']]); - } else { - $parent['children'][$value['name']] = array(); - } - array_push($parent['aggregKeys'], $value['name']); - } - array_push($parent['children'][$value['name']], $value['value']); - } else { - $parent['children'][$value['name']] = &$value['value']; - array_push($parent['childrenKeys'], $value['name']); - } - } else { - array_push($parent['children'], $value['value']); - } - array_push($this->_valStack, $parent); - } - - $this->_depth--; - } - - /** - * Handler for character data - * - * @param object $parser XML parser object - * @param string $cdata CDATA - * - * @return void - * @access private - */ - function cdataHandler($parser, $cdata) - { - if ($this->options[XML_UNSERIALIZER_OPTION_DECODE_FUNC] !== null) { - $cdata = call_user_func($this-> - options[XML_UNSERIALIZER_OPTION_DECODE_FUNC], $cdata); - } - $this->_dataStack[$this->_depth] .= $cdata; - } - - /** - * get the complex type, that should be used for a specified tag - * - * @param string $tagname name of the tag - * - * @return string complex type ('array' or 'object') - * @access private - */ - function _getComplexType($tagname) - { - if (is_string($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE])) { - return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE]; - } - if (isset($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE][$tagname])) { - return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE][$tagname]; - } - if (isset($this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE]['#default'])) { - return $this->options[XML_UNSERIALIZER_OPTION_COMPLEXTYPE]['#default']; - } - return 'array'; - } - - /** - * create the XML_Parser instance - * - * @return boolean - * @access private - */ - function _createParser() - { - if (is_object($this->_parser)) { - $this->_parser->free(); - unset($this->_parser); - } - $this->_parser = new XML_Parser($this-> - options[XML_UNSERIALIZER_OPTION_ENCODING_SOURCE], - 'event', $this->options[XML_UNSERIALIZER_OPTION_ENCODING_TARGET]); - - $this->_parser->folding = false; - $this->_parser->setHandlerObj($this); - return true; - } -} -?> diff --git a/data/module/XML/Util.php b/data/module/XML/Util.php deleted file mode 100644 index 6895e10147..0000000000 --- a/data/module/XML/Util.php +++ /dev/null @@ -1,911 +0,0 @@ - - * 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. - * * The name of the author 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 XML - * @package XML_Util - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/XML_Util - */ - -/** - * error code for invalid chars in XML name - */ -define('XML_UTIL_ERROR_INVALID_CHARS', 51); - -/** - * error code for invalid chars in XML name - */ -define('XML_UTIL_ERROR_INVALID_START', 52); - -/** - * error code for non-scalar tag content - */ -define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60); - -/** - * error code for missing tag name - */ -define('XML_UTIL_ERROR_NO_TAG_NAME', 61); - -/** - * replace XML entities - */ -define('XML_UTIL_REPLACE_ENTITIES', 1); - -/** - * embedd content in a CData Section - */ -define('XML_UTIL_CDATA_SECTION', 5); - -/** - * do not replace entitites - */ -define('XML_UTIL_ENTITIES_NONE', 0); - -/** - * replace all XML entitites - * This setting will replace <, >, ", ' and & - */ -define('XML_UTIL_ENTITIES_XML', 1); - -/** - * replace only required XML entitites - * This setting will replace <, " and & - */ -define('XML_UTIL_ENTITIES_XML_REQUIRED', 2); - -/** - * replace HTML entitites - * @link http://www.php.net/htmlentities - */ -define('XML_UTIL_ENTITIES_HTML', 3); - -/** - * Collapse all empty tags. - */ -define('XML_UTIL_COLLAPSE_ALL', 1); - -/** - * Collapse only empty XHTML tags that have no end tag. - */ -define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2); - -/** - * utility class for working with XML documents - * - - * @category XML - * @package XML_Util - * @author Stephan Schmidt - * @copyright 2003-2008 Stephan Schmidt - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: 1.2.3 - * @link http://pear.php.net/package/XML_Util - */ -class XML_Util -{ - /** - * return API version - * - * @return string $version API version - * @access public - * @static - */ - function apiVersion() - { - return '1.1'; - } - - /** - * replace XML entities - * - * With the optional second parameter, you may select, which - * entities should be replaced. - * - * - * require_once 'XML/Util.php'; - * - * // replace XML entites: - * $string = XML_Util::replaceEntities('This string contains < & >.'); - * - * - * With the optional third parameter, you may pass the character encoding - * - * require_once 'XML/Util.php'; - * - * // replace XML entites in UTF-8: - * $string = XML_Util::replaceEntities( - * 'This string contains < & > as well as ä, ö, ß, à and ê', - * XML_UTIL_ENTITIES_HTML, - * 'UTF-8' - * ); - * - * - * @param string $string string where XML special chars - * should be replaced - * @param int $replaceEntities setting for entities in attribute values - * (one of XML_UTIL_ENTITIES_XML, - * XML_UTIL_ENTITIES_XML_REQUIRED, - * XML_UTIL_ENTITIES_HTML) - * @param string $encoding encoding value (if any)... - * must be a valid encoding as determined - * by the htmlentities() function - * - * @return string string with replaced chars - * @access public - * @static - * @see reverseEntities() - */ - function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML, - $encoding = 'ISO-8859-1') - { - switch ($replaceEntities) { - case XML_UTIL_ENTITIES_XML: - return strtr($string, array( - '&' => '&', - '>' => '>', - '<' => '<', - '"' => '"', - '\'' => ''' )); - break; - case XML_UTIL_ENTITIES_XML_REQUIRED: - return strtr($string, array( - '&' => '&', - '<' => '<', - '"' => '"' )); - break; - case XML_UTIL_ENTITIES_HTML: - return htmlentities($string, ENT_COMPAT, $encoding); - break; - } - return $string; - } - - /** - * reverse XML entities - * - * With the optional second parameter, you may select, which - * entities should be reversed. - * - * - * require_once 'XML/Util.php'; - * - * // reverse XML entites: - * $string = XML_Util::reverseEntities('This string contains < & >.'); - * - * - * With the optional third parameter, you may pass the character encoding - * - * require_once 'XML/Util.php'; - * - * // reverse XML entites in UTF-8: - * $string = XML_Util::reverseEntities( - * 'This string contains < & > as well as' - * . ' ä, ö, ß, à and ê', - * XML_UTIL_ENTITIES_HTML, - * 'UTF-8' - * ); - * - * - * @param string $string string where XML special chars - * should be replaced - * @param int $replaceEntities setting for entities in attribute values - * (one of XML_UTIL_ENTITIES_XML, - * XML_UTIL_ENTITIES_XML_REQUIRED, - * XML_UTIL_ENTITIES_HTML) - * @param string $encoding encoding value (if any)... - * must be a valid encoding as determined - * by the html_entity_decode() function - * - * @return string string with replaced chars - * @access public - * @static - * @see replaceEntities() - */ - function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML, - $encoding = 'ISO-8859-1') - { - switch ($replaceEntities) { - case XML_UTIL_ENTITIES_XML: - return strtr($string, array( - '&' => '&', - '>' => '>', - '<' => '<', - '"' => '"', - ''' => '\'' )); - break; - case XML_UTIL_ENTITIES_XML_REQUIRED: - return strtr($string, array( - '&' => '&', - '<' => '<', - '"' => '"' )); - break; - case XML_UTIL_ENTITIES_HTML: - return html_entity_decode($string, ENT_COMPAT, $encoding); - break; - } - return $string; - } - - /** - * build an xml declaration - * - * - * require_once 'XML/Util.php'; - * - * // get an XML declaration: - * $xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true); - * - * - * @param string $version xml version - * @param string $encoding character encoding - * @param bool $standalone document is standalone (or not) - * - * @return string xml declaration - * @access public - * @static - * @uses attributesToString() to serialize the attributes of the XML declaration - */ - function getXMLDeclaration($version = '1.0', $encoding = null, - $standalone = null) - { - $attributes = array( - 'version' => $version, - ); - // add encoding - if ($encoding !== null) { - $attributes['encoding'] = $encoding; - } - // add standalone, if specified - if ($standalone !== null) { - $attributes['standalone'] = $standalone ? 'yes' : 'no'; - } - - return sprintf('', - XML_Util::attributesToString($attributes, false)); - } - - /** - * build a document type declaration - * - * - * require_once 'XML/Util.php'; - * - * // get a doctype declaration: - * $xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd'); - * - * - * @param string $root name of the root tag - * @param string $uri uri of the doctype definition - * (or array with uri and public id) - * @param string $internalDtd internal dtd entries - * - * @return string doctype declaration - * @access public - * @static - * @since 0.2 - */ - function getDocTypeDeclaration($root, $uri = null, $internalDtd = null) - { - if (is_array($uri)) { - $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']); - } elseif (!empty($uri)) { - $ref = sprintf(' SYSTEM "%s"', $uri); - } else { - $ref = ''; - } - - if (empty($internalDtd)) { - return sprintf('', $root, $ref); - } else { - return sprintf("", $root, $ref, $internalDtd); - } - } - - /** - * create string representation of an attribute list - * - * - * require_once 'XML/Util.php'; - * - * // build an attribute string - * $att = array( - * 'foo' => 'bar', - * 'argh' => 'tomato' - * ); - * - * $attList = XML_Util::attributesToString($att); - * - * - * @param array $attributes attribute array - * @param bool|array $sort sort attribute list alphabetically, - * may also be an assoc array containing - * the keys 'sort', 'multiline', 'indent', - * 'linebreak' and 'entities' - * @param bool $multiline use linebreaks, if more than - * one attribute is given - * @param string $indent string used for indentation of - * multiline attributes - * @param string $linebreak string used for linebreaks of - * multiline attributes - * @param int $entities setting for entities in attribute values - * (one of XML_UTIL_ENTITIES_NONE, - * XML_UTIL_ENTITIES_XML, - * XML_UTIL_ENTITIES_XML_REQUIRED, - * XML_UTIL_ENTITIES_HTML) - * - * @return string string representation of the attributes - * @access public - * @static - * @uses replaceEntities() to replace XML entities in attribute values - * @todo allow sort also to be an options array - */ - function attributesToString($attributes, $sort = true, $multiline = false, - $indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML) - { - /* - * second parameter may be an array - */ - if (is_array($sort)) { - if (isset($sort['multiline'])) { - $multiline = $sort['multiline']; - } - if (isset($sort['indent'])) { - $indent = $sort['indent']; - } - if (isset($sort['linebreak'])) { - $multiline = $sort['linebreak']; - } - if (isset($sort['entities'])) { - $entities = $sort['entities']; - } - if (isset($sort['sort'])) { - $sort = $sort['sort']; - } else { - $sort = true; - } - } - $string = ''; - if (is_array($attributes) && !empty($attributes)) { - if ($sort) { - ksort($attributes); - } - if ( !$multiline || count($attributes) == 1) { - foreach ($attributes as $key => $value) { - if ($entities != XML_UTIL_ENTITIES_NONE) { - if ($entities === XML_UTIL_CDATA_SECTION) { - $entities = XML_UTIL_ENTITIES_XML; - } - $value = XML_Util::replaceEntities($value, $entities); - } - $string .= ' ' . $key . '="' . $value . '"'; - } - } else { - $first = true; - foreach ($attributes as $key => $value) { - if ($entities != XML_UTIL_ENTITIES_NONE) { - $value = XML_Util::replaceEntities($value, $entities); - } - if ($first) { - $string .= ' ' . $key . '="' . $value . '"'; - $first = false; - } else { - $string .= $linebreak . $indent . $key . '="' . $value . '"'; - } - } - } - } - return $string; - } - - /** - * Collapses empty tags. - * - * @param string $xml XML - * @param int $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL) - * or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones. - * - * @return string XML - * @access public - * @static - * @todo PEAR CS - unable to avoid "space after open parens" error - * in the IF branch - */ - function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL) - { - if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) { - return preg_replace( - '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|' - . 'param)([^>]*)><\/\\1>/s', - '<\\1\\2 />', - $xml); - } else { - return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml); - } - } - - /** - * create a tag - * - * This method will call XML_Util::createTagFromArray(), which - * is more flexible. - * - * - * require_once 'XML/Util.php'; - * - * // create an XML tag: - * $tag = XML_Util::createTag('myNs:myTag', - * array('foo' => 'bar'), - * 'This is inside the tag', - * 'http://www.w3c.org/myNs#'); - * - * - * @param string $qname qualified tagname (including namespace) - * @param array $attributes array containg attributes - * @param mixed $content the content - * @param string $namespaceUri URI of the namespace - * @param int $replaceEntities whether to replace XML special chars in - * content, embedd it in a CData section - * or none of both - * @param bool $multiline whether to create a multiline tag where - * each attribute gets written to a single line - * @param string $indent string used to indent attributes - * (_auto indents attributes so they start - * at the same column) - * @param string $linebreak string used for linebreaks - * @param bool $sortAttributes Whether to sort the attributes or not - * - * @return string XML tag - * @access public - * @static - * @see createTagFromArray() - * @uses createTagFromArray() to create the tag - */ - function createTag($qname, $attributes = array(), $content = null, - $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, - $multiline = false, $indent = '_auto', $linebreak = "\n", - $sortAttributes = true) - { - $tag = array( - 'qname' => $qname, - 'attributes' => $attributes - ); - - // add tag content - if ($content !== null) { - $tag['content'] = $content; - } - - // add namespace Uri - if ($namespaceUri !== null) { - $tag['namespaceUri'] = $namespaceUri; - } - - return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, - $indent, $linebreak, $sortAttributes); - } - - /** - * create a tag from an array - * this method awaits an array in the following format - *
-     * array(
-     *     // qualified name of the tag
-     *     'qname' => $qname
-     *
-     *     // namespace prefix (optional, if qname is specified or no namespace)
-     *     'namespace' => $namespace
-     *
-     *     // local part of the tagname (optional, if qname is specified)
-     *     'localpart' => $localpart,
-     *
-     *     // array containing all attributes (optional)
-     *     'attributes' => array(),
-     *
-     *     // tag content (optional)
-     *     'content' => $content,
-     *
-     *     // namespaceUri for the given namespace (optional)
-     *     'namespaceUri' => $namespaceUri
-     * )
-     * 
- * - * - * require_once 'XML/Util.php'; - * - * $tag = array( - * 'qname' => 'foo:bar', - * 'namespaceUri' => 'http://foo.com', - * 'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'), - * 'content' => 'I\'m inside the tag', - * ); - * // creating a tag with qualified name and namespaceUri - * $string = XML_Util::createTagFromArray($tag); - * - * - * @param array $tag tag definition - * @param int $replaceEntities whether to replace XML special chars in - * content, embedd it in a CData section - * or none of both - * @param bool $multiline whether to create a multiline tag where each - * attribute gets written to a single line - * @param string $indent string used to indent attributes - * (_auto indents attributes so they start - * at the same column) - * @param string $linebreak string used for linebreaks - * @param bool $sortAttributes Whether to sort the attributes or not - * - * @return string XML tag - * @access public - * @static - * @see createTag() - * @uses attributesToString() to serialize the attributes of the tag - * @uses splitQualifiedName() to get local part and namespace of a qualified name - * @uses createCDataSection() - * @uses raiseError() - */ - function createTagFromArray($tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, - $multiline = false, $indent = '_auto', $linebreak = "\n", - $sortAttributes = true) - { - if (isset($tag['content']) && !is_scalar($tag['content'])) { - return XML_Util::raiseError('Supplied non-scalar value as tag content', - XML_UTIL_ERROR_NON_SCALAR_CONTENT); - } - - if (!isset($tag['qname']) && !isset($tag['localPart'])) { - return XML_Util::raiseError('You must either supply a qualified name ' - . '(qname) or local tag name (localPart).', - XML_UTIL_ERROR_NO_TAG_NAME); - } - - // if no attributes hav been set, use empty attributes - if (!isset($tag['attributes']) || !is_array($tag['attributes'])) { - $tag['attributes'] = array(); - } - - if (isset($tag['namespaces'])) { - foreach ($tag['namespaces'] as $ns => $uri) { - $tag['attributes']['xmlns:' . $ns] = $uri; - } - } - - if (!isset($tag['qname'])) { - // qualified name is not given - - // check for namespace - if (isset($tag['namespace']) && !empty($tag['namespace'])) { - $tag['qname'] = $tag['namespace'] . ':' . $tag['localPart']; - } else { - $tag['qname'] = $tag['localPart']; - } - } elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) { - // namespace URI is set, but no namespace - - $parts = XML_Util::splitQualifiedName($tag['qname']); - - $tag['localPart'] = $parts['localPart']; - if (isset($parts['namespace'])) { - $tag['namespace'] = $parts['namespace']; - } - } - - if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) { - // is a namespace given - if (isset($tag['namespace']) && !empty($tag['namespace'])) { - $tag['attributes']['xmlns:' . $tag['namespace']] = - $tag['namespaceUri']; - } else { - // define this Uri as the default namespace - $tag['attributes']['xmlns'] = $tag['namespaceUri']; - } - } - - // check for multiline attributes - if ($multiline === true) { - if ($indent === '_auto') { - $indent = str_repeat(' ', (strlen($tag['qname'])+2)); - } - } - - // create attribute list - $attList = XML_Util::attributesToString($tag['attributes'], - $sortAttributes, $multiline, $indent, $linebreak); - if (!isset($tag['content']) || (string)$tag['content'] == '') { - $tag = sprintf('<%s%s />', $tag['qname'], $attList); - } else { - switch ($replaceEntities) { - case XML_UTIL_ENTITIES_NONE: - break; - case XML_UTIL_CDATA_SECTION: - $tag['content'] = XML_Util::createCDataSection($tag['content']); - break; - default: - $tag['content'] = XML_Util::replaceEntities($tag['content'], - $replaceEntities); - break; - } - $tag = sprintf('<%s%s>%s', $tag['qname'], $attList, $tag['content'], - $tag['qname']); - } - return $tag; - } - - /** - * create a start element - * - * - * require_once 'XML/Util.php'; - * - * // create an XML start element: - * $tag = XML_Util::createStartElement('myNs:myTag', - * array('foo' => 'bar') ,'http://www.w3c.org/myNs#'); - * - * - * @param string $qname qualified tagname (including namespace) - * @param array $attributes array containg attributes - * @param string $namespaceUri URI of the namespace - * @param bool $multiline whether to create a multiline tag where each - * attribute gets written to a single line - * @param string $indent string used to indent attributes (_auto indents - * attributes so they start at the same column) - * @param string $linebreak string used for linebreaks - * @param bool $sortAttributes Whether to sort the attributes or not - * - * @return string XML start element - * @access public - * @static - * @see createEndElement(), createTag() - */ - function createStartElement($qname, $attributes = array(), $namespaceUri = null, - $multiline = false, $indent = '_auto', $linebreak = "\n", - $sortAttributes = true) - { - // if no attributes hav been set, use empty attributes - if (!isset($attributes) || !is_array($attributes)) { - $attributes = array(); - } - - if ($namespaceUri != null) { - $parts = XML_Util::splitQualifiedName($qname); - } - - // check for multiline attributes - if ($multiline === true) { - if ($indent === '_auto') { - $indent = str_repeat(' ', (strlen($qname)+2)); - } - } - - if ($namespaceUri != null) { - // is a namespace given - if (isset($parts['namespace']) && !empty($parts['namespace'])) { - $attributes['xmlns:' . $parts['namespace']] = $namespaceUri; - } else { - // define this Uri as the default namespace - $attributes['xmlns'] = $namespaceUri; - } - } - - // create attribute list - $attList = XML_Util::attributesToString($attributes, $sortAttributes, - $multiline, $indent, $linebreak); - $element = sprintf('<%s%s>', $qname, $attList); - return $element; - } - - /** - * create an end element - * - * - * require_once 'XML/Util.php'; - * - * // create an XML start element: - * $tag = XML_Util::createEndElement('myNs:myTag'); - * - * - * @param string $qname qualified tagname (including namespace) - * - * @return string XML end element - * @access public - * @static - * @see createStartElement(), createTag() - */ - function createEndElement($qname) - { - $element = sprintf('', $qname); - return $element; - } - - /** - * create an XML comment - * - * - * require_once 'XML/Util.php'; - * - * // create an XML start element: - * $tag = XML_Util::createComment('I am a comment'); - * - * - * @param string $content content of the comment - * - * @return string XML comment - * @access public - * @static - */ - function createComment($content) - { - $comment = sprintf('', $content); - return $comment; - } - - /** - * create a CData section - * - * - * require_once 'XML/Util.php'; - * - * // create a CData section - * $tag = XML_Util::createCDataSection('I am content.'); - * - * - * @param string $data data of the CData section - * - * @return string CData section with content - * @access public - * @static - */ - function createCDataSection($data) - { - return sprintf('', - preg_replace('/\]\]>/', ']]]]>', strval($data))); - - } - - /** - * split qualified name and return namespace and local part - * - * - * require_once 'XML/Util.php'; - * - * // split qualified tag - * $parts = XML_Util::splitQualifiedName('xslt:stylesheet'); - * - * the returned array will contain two elements: - *
-     * array(
-     *     'namespace' => 'xslt',
-     *     'localPart' => 'stylesheet'
-     * );
-     * 
- * - * @param string $qname qualified tag name - * @param string $defaultNs default namespace (optional) - * - * @return array array containing namespace and local part - * @access public - * @static - */ - function splitQualifiedName($qname, $defaultNs = null) - { - if (strstr($qname, ':')) { - $tmp = explode(':', $qname); - return array( - 'namespace' => $tmp[0], - 'localPart' => $tmp[1] - ); - } - return array( - 'namespace' => $defaultNs, - 'localPart' => $qname - ); - } - - /** - * check, whether string is valid XML name - * - *

XML names are used for tagname, attribute names and various - * other, lesser known entities.

- *

An XML name may only consist of alphanumeric characters, - * dashes, undescores and periods, and has to start with a letter - * or an underscore.

- * - * - * require_once 'XML/Util.php'; - * - * // verify tag name - * $result = XML_Util::isValidName('invalidTag?'); - * if (is_a($result, 'PEAR_Error')) { - * print 'Invalid XML name: ' . $result->getMessage(); - * } - * - * - * @param string $string string that should be checked - * - * @return mixed true, if string is a valid XML name, PEAR error otherwise - * @access public - * @static - * @todo support for other charsets - * @todo PEAR CS - unable to avoid 85-char limit on second preg_match - */ - function isValidName($string) - { - // check for invalid chars - if (!preg_match('/^[[:alpha:]_]\\z/', $string{0})) { - return XML_Util::raiseError('XML names may only start with letter ' - . 'or underscore', XML_UTIL_ERROR_INVALID_START); - } - - // check for invalid chars - if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/', - $string) - ) { - return XML_Util::raiseError('XML names may only contain alphanumeric ' - . 'chars, period, hyphen, colon and underscores', - XML_UTIL_ERROR_INVALID_CHARS); - } - // XML name is valid - return true; - } - - /** - * replacement for XML_Util::raiseError - * - * Avoids the necessity to always require - * PEAR.php - * - * @param string $msg error message - * @param int $code error code - * - * @return PEAR_Error - * @access public - * @static - * @todo PEAR CS - should this use include_once instead? - */ - function raiseError($msg, $code) - { - require_once 'PEAR.php'; - return PEAR::raiseError($msg, $code); - } -} -?> diff --git a/eccube_install.sh b/eccube_install.sh index d09618e85e..5213223c8b 100755 --- a/eccube_install.sh +++ b/eccube_install.sh @@ -226,7 +226,7 @@ case "${DBTYPE}" in echo "dropdb..." ${DROPDB} ${DBNAME} echo "createdb..." - ${CREATEDB} -U ${DBUSER} ${DBNAME} + ${CREATEDB} -U ${DBUSER} ${DBNAME} echo "create table..." ${PSQL} -U ${DBUSER} -f ${SQL_DIR}/create_table_pgsql.sql ${DBNAME} echo "insert data..." @@ -262,7 +262,7 @@ case "${DBTYPE}" in echo "dropdb..." ${MYSQL} -u ${ROOTUSER} ${PASSOPT} -e "drop database \`${DBNAME}\`" echo "createdb..." - ${MYSQL} -u ${ROOTUSER} ${PASSOPT} -e "create database \`${DBNAME}\`" + ${MYSQL} -u ${ROOTUSER} ${PASSOPT} -e "create database \`${DBNAME}\` DEFAULT COLLATE=utf8_general_ci;" #echo "grant user..." #${MYSQL} -u ${ROOTUSER} ${PASSOPT} -e "GRANT ALL ON \`${DBNAME}\`.* TO '${DBUSER}'@'%' IDENTIFIED BY '${DBPASS}'" echo "create table..." diff --git a/html/admin/require.php b/html/admin/require.php index 1daa5b0b89..95e82ff0d8 100644 --- a/html/admin/require.php +++ b/html/admin/require.php @@ -20,7 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -require __DIR__.'/../../vendor/autoload.php'; // rtrim は PHP バージョン依存対策 $GLOBALS['_realdir'] = rtrim(realpath(rtrim(realpath(dirname(__FILE__)), '/\\') . '/../'), '/\\') . '/'; $GLOBALS['_realdir'] = str_replace('\\', '/', $GLOBALS['_realdir']); diff --git a/html/define.php b/html/define.php index df59e8a1d4..2d52e33ef6 100644 --- a/html/define.php +++ b/html/define.php @@ -12,6 +12,7 @@ * ※ IIS は、POST 時にファイル名を使用しないと不具合が発生する。(http://support.microsoft.com/kb/247536/ja) */ define('USE_FILENAME_DIR_INDEX', null); +require_once HTML_REALDIR . HTML2DATA_DIR . 'vendor/autoload.php'; // bufferを初期化する while (ob_get_level() > 0 && ob_get_level() > 0) { diff --git a/html/install/index.php b/html/install/index.php index 621a7af679..3591dd9c0b 100644 --- a/html/install/index.php +++ b/html/install/index.php @@ -20,7 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -require __DIR__.'/../../vendor/autoload.php'; // ▼require.php 相当 // rtrim は PHP バージョン依存対策 $GLOBALS['_realdir'] = rtrim(realpath(rtrim(realpath(dirname(__FILE__)), '/\\') . '/../'), '/\\') . '/'; @@ -851,8 +850,12 @@ function lfExecuteSQL($filepath, $arrDsn, $disp_err = true) // MySQL 用の初期化 // XXX SC_Query を使うようにすれば、この処理は不要となる - if ($arrDsn['phptype'] === 'mysql') { - $objDB->exec('SET SESSION storage_engine = InnoDB'); + if ($arrDsn['phptype'] === 'mysqli') { + if ($objDB->getConnection()->server_version >= 50705) { + $objDB->exec('SET SESSION defaut_storage_engine = InnoDB'); + } else { + $objDB->exec('SET SESSION storage_engine = InnoDB'); + } $objDB->exec("SET SESSION sql_mode = 'ANSI'"); } @@ -860,6 +863,11 @@ function lfExecuteSQL($filepath, $arrDsn, $disp_err = true) foreach ($sql_split as $key => $val) { SC_Utils::sfFlush(true); if (trim($val) != '') { + if ($arrDsn['phptype'] === 'mysqli') { + // rank は予約語なので MySQL8 から引用符をつけないとエラーになる + $dbFactory = SC_DB_DBFactory_Ex::getInstance($arrDsn['phptype']); + $val = $dbFactory->sfChangeReservedWords($val); + } $ret = $objDB->query($val); if (PEAR::isError($ret) && $disp_err) { $arrErr['all'] = '>> ' . $ret->message . '
'; diff --git a/html/install/sql/create_table_mysqli.sql b/html/install/sql/create_table_mysqli.sql index 8eebbec462..3795005099 100644 --- a/html/install/sql/create_table_mysqli.sql +++ b/html/install/sql/create_table_mysqli.sql @@ -643,7 +643,7 @@ CREATE TABLE dtb_order_temp ( memo08 text, memo09 text, memo10 text, - session text, + session longtext, PRIMARY KEY (order_temp_id(64)) ); @@ -1137,7 +1137,7 @@ CREATE TABLE dtb_module ( CREATE TABLE dtb_session ( sess_id text NOT NULL, - sess_data text, + sess_data longtext, create_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, update_date timestamp NOT NULL, PRIMARY KEY (sess_id(255)) diff --git a/html/require.php b/html/require.php index e23c65663c..fecb9d18be 100644 --- a/html/require.php +++ b/html/require.php @@ -21,7 +21,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -require __DIR__.'/../vendor/autoload.php'; // rtrim は PHP バージョン依存対策 $GLOBALS['_realdir'] = rtrim(realpath(rtrim(realpath(dirname(__FILE__)), '/\\') . '/'), '/\\') . '/'; $GLOBALS['_realdir'] = str_replace('\\', '/', $GLOBALS['_realdir']); diff --git a/tests/class/module/Cache_Lite/NestedOutputTest.php b/tests/class/module/Cache_Lite/NestedOutputTest.php new file mode 100644 index 0000000000..00499aa3f8 --- /dev/null +++ b/tests/class/module/Cache_Lite/NestedOutputTest.php @@ -0,0 +1,65 @@ + + */ + +//require_once __DIR__ . '/../Cache/Lite/NestedOutput.php'; + +class NestedOutputTest extends Common_TestCase +{ + /** + * "Test" used for documenting the nested output buffering feature of php + */ + public function testPhpObNesting() + { + $outsideText = "This is the outside"; + $insideText = "This is the inside"; + ob_start(); + echo $outsideText; + ob_start(); + echo $insideText; + $innerContents = ob_get_contents(); + ob_end_clean(); + $outerContents = ob_get_contents(); + ob_end_clean(); + + $this->assertEquals( $insideText, $innerContents ); + $this->assertEquals( $outsideText, $outerContents ); + } + + /** + * Test for Cache_Lite_NestedOutput + */ + public function testCacheLiteOutputNesting() + { + $outsideText = "This is the outside"; + $insideText = "This is the inside"; + + $options = array( + 'caching' => true, + 'cacheDir' => '/tmp/', + 'lifeTime' => 10 + ); + $cache = new Cache_Lite_NestedOutput($options); + $this->assertFalse($cache->start('foo', 'a')); + echo $outsideText; + $this->assertFalse($cache->start('bar', 'b')); + echo $insideText; + $inside = $cache->end(); + $outside = $cache->end(); + $this->assertEquals($outsideText, $outside, 'Validate outside'); + $this->assertEquals($insideText, $inside, 'Validate inside'); + + $cache = new Cache_Lite_NestedOutput($options); + $this->assertEquals($outsideText, $cache->start('foo', 'a'), 'Validate outside'); + $this->assertEquals($insideText, $cache->start('bar', 'b'), 'Validate inside'); + } +} diff --git a/tests/class/module/Calendar/CalendarTest.php b/tests/class/module/Calendar/CalendarTest.php new file mode 100644 index 0000000000..f55a669116 --- /dev/null +++ b/tests/class/module/Calendar/CalendarTest.php @@ -0,0 +1,91 @@ + + * @license + */ +class Calendar_Test extends Common_TestCase +{ + public function TestOfMonthWeekdays() + { + $this->UnitTestCase('Test of Month Weekdays'); + } + public function setUp() + { + $this->cal = new Calendar_Month_Weekdays(2003,10); + } + public function tearDown() + { + } + public function testPrevDay() + { + $this->assertSame(30,$this->cal->prevDay()); + } + public function testPrevDay_Array() + { + $this->assertSame( + array( + 'year' => 2003, + 'month' => 9, + 'day' => 30, + 'hour' => 0, + 'minute' => 0, + 'second' => 0), + $this->cal->prevDay('array')); + } + public function testThisDay() + { + $this->assertSame(1,$this->cal->thisDay()); + } + public function testNextDay() + { + $this->assertSame(2,$this->cal->nextDay()); + } + public function testPrevHour() + { + $this->assertSame(23,$this->cal->prevHour()); + } + public function testThisHour() + { + $this->assertSame(0,$this->cal->thisHour()); + } + public function testNextHour() + { + $this->assertSame(1,$this->cal->nextHour()); + } + public function testPrevMinute() + { + $this->assertSame(59,$this->cal->prevMinute()); + } + public function testThisMinute() + { + $this->assertSame(0,$this->cal->thisMinute()); + } + public function testNextMinute() + { + $this->assertSame(1,$this->cal->nextMinute()); + } + public function testPrevSecond() + { + $this->assertSame(59,$this->cal->prevSecond()); + } + public function testThisSecond() + { + $this->assertSame(0,$this->cal->thisSecond()); + } + public function testNextSecond() + { + $this->assertSame(1,$this->cal->nextSecond()); + } + public function testGetTimeStamp() + { + $stamp = mktime(0,0,0,10,1,2003); + $this->assertSame($stamp,$this->cal->getTimeStamp()); + } +} diff --git a/tests/class/module/HTTP/RequestTest.php b/tests/class/module/HTTP/RequestTest.php new file mode 100644 index 0000000000..b0960c5c5c --- /dev/null +++ b/tests/class/module/HTTP/RequestTest.php @@ -0,0 +1,25 @@ + + * @license + */ +class HTTP_RequestTest extends Common_TestCase +{ + public function testConstructorSetsDefaults() + { + $url = 'http://www.example.com/foo'; + $req = new HTTP_Request($url); + //$req->setMethod(HTTP_REQUEST_METHOD_POST); + //$req->addPostData('Foo', 'bar'); + + $this->assertSame($url, $req->getUrl()); + //$this->assertEquals(HTTP_REQUEST_METHOD_POST, $req->getMethod()); + } + +} diff --git a/tests/class/module/Net_UserAgent_Mobile/Net_UserAgent_MobileTest.php b/tests/class/module/Net_UserAgent_Mobile/Net_UserAgent_MobileTest.php new file mode 100644 index 0000000000..52178167f2 --- /dev/null +++ b/tests/class/module/Net_UserAgent_Mobile/Net_UserAgent_MobileTest.php @@ -0,0 +1,32 @@ + + * @license + */ +class Net_UserAgent_MobileTest extends Common_TestCase +{ + public function testConstructorSetsDefaults() + { + $nu = new Net_UserAgent_Mobile(); + $this->assertEquals(false, $nu->isMobile()); + } + + public function testMobile() + { + $ua = $_SERVER['HTTP_USER_AGENT']; + $_SERVER['HTTP_USER_AGENT'] = 'DoCoMo/2.0 F901iC(c100;TB;W23H12)'; + + $nu = new Net_UserAgent_Mobile(); + $this->assertEquals(true, $nu->isMobile()); + $this->assertEquals(true, $nu->isDocomo()); + + // 念のため戻す + $_SERVER['HTTP_USER_AGENT'] = $ua; + } +} diff --git a/tests/class/module/Text/Text_Password_Test.php b/tests/class/module/Text/Text_Password_Test.php new file mode 100644 index 0000000000..152ae20411 --- /dev/null +++ b/tests/class/module/Text/Text_Password_Test.php @@ -0,0 +1,200 @@ + + * @copyright 2004-2016 Martin Jansen, Michael Gauthier + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version CVS: $Id$ + * @link http://pear.php.net/package/Text_Password + */ + +require_once 'Text/Password.php'; + +/** + * Unit test suite for the Text_Password package + * + * @author Martin Jansen + * @extends PHPUnit_TestCase + * @version $Id$ + */ +class Text_Password_Test extends Common_TestCase +{ + public function testCreate() + { + $password = Text_Password::create(); + $this->assertTrue(strlen($password) == 10); + } + + public function testCreateWithLength() + { + $password = Text_Password::create(15); + $this->assertTrue(strlen($password) == 15); + } + + public function testCreateMultiple() + { + $passwords = Text_Password::createMultiple(3); + $this->_testCreateMultiple($passwords, 3, 10); + } + + public function testCreateMultipleWithLength() + { + $passwords = Text_Password::createMultiple(3, 15); + $this->_testCreateMultiple($passwords, 3, 15); + } + + public function testCreateNumericWithLength() + { + $password = Text_Password::create(8, 'unpronounceable', 'numeric'); + + $this->assertRegExp("/^[0-9]{8}$/", $password); + } + + public function testCreateFromABCWithLength() + { + $password = Text_Password::create(8, 'unpronounceable', 'a,b,c'); + $this->assertRegExp("/^[abc]{8}$/i", $password); + } + + public function testCreateAlphabeticWithLength() + { + $password = Text_Password::create(8, 'unpronounceable', 'alphabetic'); + + $this->assertRegExp("/^[a-z]{8}$/i", $password); + } + + public function testCreateUnpronouncableWithAllClasses() + { + $password = Text_Password::create(8, 'unpronounceable', ''); + $this->assertRegExp('/^[a-z0-9_#@%&]{8}$/i', $password); + + // Make sure all character classes are used at least once. + $this->assertRegExp('/[a-z]/', $password); + $this->assertRegExp('/[A-Z]/', $password); + $this->assertRegExp('/[0-9]/', $password); + $this->assertRegExp('/[_#@%&]/', $password); + } + + /** + * Ensures short password generation, where the length is less than the + * number of character classes, works properly + */ + public function testCreateUnpronouncableShortWithAllClasses() + { + $password = Text_Password::create(2, 'unpronounceable', ''); + $this->assertRegExp('/^[a-z0-9_#@%&]{2}$/i', $password); + } + + // {{{ Test cases for creating passwords based on a given login string + + public function testCreateFromLoginReverse() + { + $this->assertEquals("eoj", Text_Password::createFromLogin("joe", "reverse")); + } + + public function testCreateFromLoginShuffle() + { + $this->assertTrue(strlen(Text_Password::createFromLogin("hello world", "shuffle")) == strlen("hello world")); + } + + public function testCreateFromLoginRotX() + { + $this->assertEquals("tyo", Text_Password::createFromLogin("joe", "rotx", 10)); + } + + public function testCreateFromLoginRot13() + { + $this->assertEquals("wbr", Text_Password::createFromLogin("joe", "rot13")); + } + + public function testCreateFromLoginRotXplusplus() + { + $this->assertEquals("syp", Text_Password::createFromLogin("joe", "rotx++", 9)); + } + + public function testCreateFromLoginRotXminusminus() + { + $this->assertEquals("swl", Text_Password::createFromLogin("joe", "rotx--", 9)); + } + + public function testCreateFromLoginXOR() + { + $this->assertEquals("oj`", Text_Password::createFromLogin("joe", "xor", 5)); + } + + public function testCreateFromLoginASCIIRotX() + { + $this->assertEquals("otj", Text_Password::createFromLogin("joe", "ascii_rotx", 5)); + } + + public function testCreateFromLoginASCIIRotXplusplus() + { + $this->assertEquals("oul", Text_Password::createFromLogin("joe", "ascii_rotx++", 5)); + } + + public function testCreateFromLoginASCIIRotXminusminus() + { + $this->assertEquals("uyn", Text_Password::createFromLogin("joe", "ascii_rotx--", 11)); + } + + // }}} + + /** + * Unit test for bug #2605 + * + * Actually this method does not implement a real unit test, but + * instead it is there to make sure that no warning is produced + * by PHP. + * + * @link http://pear.php.net/bugs/bug.php?id=2605 + */ + public function testBugReport2605() + { + $password = Text_Password::create(7, 'unpronounceable', '1,3,a,Q,~,[,f'); + $this->assertTrue(strlen($password) == 7); + } + + // {{{ private helper methods + + protected function _testCreateMultiple($passwords, $count, $length) + { + $this->assertInternalType("array", $passwords); + $this->assertTrue(count($passwords) == $count); + + foreach ($passwords as $password) { + $this->assertTrue(strlen($password) == $length); + } + } + + // }}} +} diff --git a/tests/class/module/XML/Serializer_ObjectsTest.php b/tests/class/module/XML/Serializer_ObjectsTest.php new file mode 100644 index 0000000000..78aedab1b2 --- /dev/null +++ b/tests/class/module/XML/Serializer_ObjectsTest.php @@ -0,0 +1,96 @@ + + * @author Chuck Burgess + */ + +require_once 'XML/Serializer.php'; + +/** + * Unit Tests for serializing arrays + * + * @package XML_Serializer + * @subpackage tests + * @author Stephan Schmidt + * @author Chuck Burgess + */ +class XML_Serializer_Objects_TestCase extends Common_TestCase +{ + private $options = array( + XML_SERIALIZER_OPTION_INDENT => '', + XML_SERIALIZER_OPTION_LINEBREAKS => '', + ); + + /** + * Test serializing an object without any properties + */ + public function testEmptyObject() + { + $s = new XML_Serializer($this->options); + $s->serialize(new stdClass()); + $this->assertEquals('', $s->getSerializedData()); + } + + /** + * Test serializing a simple object + */ + public function testSimpleObject() + { + $obj = new stdClass(); + $obj->foo = 'bar'; + $s = new XML_Serializer($this->options); + $s->serialize($obj); + $this->assertEquals('bar', $s->getSerializedData()); + } + + /** + * Test serializing a nested object + */ + public function testNestedObject() + { + $obj = new stdClass(); + $obj->foo = new stdClass(); + $obj->foo->bar = 'nested'; + $s = new XML_Serializer($this->options); + $s->serialize($obj); + $this->assertEquals('nested', $s->getSerializedData()); + } + + /** + * Test serializing an object, that supports __sleep + */ + public function testSleep() + { + $obj = new MyClass('foo', 'bar'); + $s = new XML_Serializer($this->options); + $s->serialize($obj); + $this->assertEquals('foo', $s->getSerializedData()); + } + +} + +class MyClass +{ + public $foo; + public $bar; + + public function __construct($foo, $bar) + { + $this->foo = $foo; + $this->bar = $bar; + } + + public function __sleep() + { + return array('foo'); + } +}