Merge branch 'develop' into rewrites/coding-convention-split2-1-2

This commit is contained in:
Roland Häder 2017-04-08 18:45:59 +02:00 committed by GitHub
commit 3d1626781d
234 changed files with 55777 additions and 1662 deletions

View file

@ -646,12 +646,12 @@ class App {
startup(); startup();
set_include_path( set_include_path(
'include' . PATH_SEPARATOR get_include_path() . PATH_SEPARATOR
. 'include' . PATH_SEPARATOR
. 'library' . PATH_SEPARATOR . 'library' . PATH_SEPARATOR
. 'library/langdet' . PATH_SEPARATOR . 'library/langdet' . PATH_SEPARATOR
. '.' ); . '.' );
$this->scheme = 'http'; $this->scheme = 'http';
if ((x($_SERVER, 'HTTPS') && $_SERVER['HTTPS']) || if ((x($_SERVER, 'HTTPS') && $_SERVER['HTTPS']) ||
@ -2472,7 +2472,7 @@ function get_temppath() {
// Check if it is usable // Check if it is usable
if (($temppath != "") AND App::directory_usable($temppath)) { if (($temppath != "") AND App::directory_usable($temppath)) {
// To avoid any interferences with other systems we create our own directory // To avoid any interferences with other systems we create our own directory
$new_temppath .= "/".$a->get_hostname(); $new_temppath = $temppath."/".$a->get_hostname();
if (!is_dir($new_temppath)) { if (!is_dir($new_temppath)) {
/// @TODO There is a mkdir()+chmod() upwards, maybe generalize this (+ configurable) into a function/method? /// @TODO There is a mkdir()+chmod() upwards, maybe generalize this (+ configurable) into a function/method?
mkdir($new_temppath); mkdir($new_temppath);

View file

@ -14,8 +14,16 @@
}, },
"require": { "require": {
"ezyang/htmlpurifier": "~4.7.0", "ezyang/htmlpurifier": "~4.7.0",
"mobiledetect/mobiledetectlib": "2.8.*" "mobiledetect/mobiledetectlib": "2.8.*",
"league/html-to-markdown": "~4.4.1",
"pear-pear.php.net/Text_Highlighter": "*"
}, },
"repositories": [
{
"type": "pear",
"url": "https://pear.php.net"
}
],
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Friendica\\": "src/" "Friendica\\": "src/"

284
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "49b00f1ed3192e5173bd5577a3b91ba2", "content-hash": "802372ddf124ef949e80dd8dc1d38797",
"packages": [ "packages": [
{ {
"name": "ezyang/htmlpurifier", "name": "ezyang/htmlpurifier",
@ -50,6 +50,70 @@
], ],
"time": "2015-08-05T01:03:42+00:00" "time": "2015-08-05T01:03:42+00:00"
}, },
{
"name": "league/html-to-markdown",
"version": "4.4.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/html-to-markdown.git",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/82ea375b5b2b1da1da222644c0565c695bf88186",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xml": "*",
"php": ">=5.3.3"
},
"require-dev": {
"mikehaertl/php-shellcommand": "~1.1.0",
"phpunit/phpunit": "4.*",
"scrutinizer/ocular": "~1.1"
},
"bin": [
"bin/html-to-markdown"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.5-dev"
}
},
"autoload": {
"psr-4": {
"League\\HTMLToMarkdown\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"role": "Lead Developer"
},
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net",
"role": "Original Author"
}
],
"description": "An HTML-to-markdown conversion helper for PHP",
"homepage": "https://github.com/thephpleague/html-to-markdown",
"keywords": [
"html",
"markdown"
],
"time": "2017-03-16T00:45:59+00:00"
},
{ {
"name": "mobiledetect/mobiledetectlib", "name": "mobiledetect/mobiledetectlib",
"version": "2.8.25", "version": "2.8.25",
@ -101,6 +165,224 @@
"php mobile detect" "php mobile detect"
], ],
"time": "2017-03-29T13:59:30+00:00" "time": "2017-03-29T13:59:30+00:00"
},
{
"name": "pear-pear.php.net/Archive_Tar",
"version": "1.4.2",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Archive_Tar-1.4.2.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.2.0.0"
},
"replace": {
"pear-pear/archive_tar": "== 1.4.2.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"New BSD License"
],
"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/Console_Getopt",
"version": "1.4.1",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Console_Getopt-1.4.1.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/console_getopt": "== 1.4.1.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD-2-Clause"
],
"description": "This is a PHP implementation of \"getopt\" supporting both\nshort and long options."
},
{
"name": "pear-pear.php.net/PEAR",
"version": "1.10.3",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/PEAR-1.10.3.tgz",
"reference": null,
"shasum": null
},
"require": {
"ext-pcre": "*",
"ext-xml": "*",
"pear-pear.php.net/archive_tar": ">=1.4.0.0",
"pear-pear.php.net/console_getopt": ">=1.4.1.0",
"pear-pear.php.net/structures_graph": ">=1.1.0.0",
"pear-pear.php.net/xml_util": ">=1.3.0.0",
"php": ">=5.4.0.0"
},
"conflict": {
"pear-pear.php.net/pear_frontend_gtk": "<0.4.0.0",
"pear-pear.php.net/pear_frontend_web": "<=0.4.0.0"
},
"replace": {
"pear-pear/pear": "== 1.10.3.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"New BSD License"
],
"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/Structures_Graph",
"version": "1.1.1",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Structures_Graph-1.1.1.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.3.0.0"
},
"replace": {
"pear-pear/structures_graph": "== 1.1.1.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"LGPL-3.0+"
],
"description": "Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed\nand undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing\nas well as for characteristic extraction from the graph topology."
},
{
"name": "pear-pear.php.net/Text_Highlighter",
"version": "0.8.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Text_Highlighter-0.8.0.tgz",
"reference": null,
"shasum": null
},
"require": {
"pear-pear.php.net/console_getopt": ">=1.4.1.0",
"pear-pear.php.net/pear": ">=1.10.3.0",
"pear-pear.php.net/xml_parser": ">=1.3.7.0",
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/text_highlighter": "== 0.8.0.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"PHP License"
],
"description": "Text_Highlighter is a package for syntax highlighting.\n\nIt provides a base class provining all the functionality,\nand a descendent classes geneator class.\n\nThe main idea is to simplify creation of subclasses\nimplementing syntax highlighting for particular language.\nSubclasses do not implement any new functioanality,\nthey just provide syntax highlighting rules.\nThe rules sources are in XML format.\n\nTo create a highlighter for a language, there is no need\nto code a new class manually. Simply describe the rules\nin XML file and use Text_Highlighter_Generator to create\na new class."
},
{
"name": "pear-pear.php.net/XML_Parser",
"version": "1.3.7",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/XML_Parser-1.3.7.tgz",
"reference": null,
"shasum": null
},
"require": {
"pear-pear.php.net/pear": "*",
"php": ">=4.2.0.0"
},
"replace": {
"pear-pear/xml_parser": "== 1.3.7.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD License"
],
"description": "This is an XML parser based on PHPs built-in xml extension.\nIt supports two basic modes of operation: \"func\" and \"event\". In \"func\" mode, it will look for a function named after each element (xmltag_ELEMENT for start tags and xmltag_ELEMENT_ for end tags), and in \"event\" mode it uses a set of generic callbacks.\n\nSince version 1.2.0 there's a new XML_Parser_Simple class that makes parsing of most XML documents easier, by automatically providing a stack for the elements.\nFurthermore its now possible to split the parser from the handler object, so you do not have to extend XML_Parser anymore in order to parse a document with it."
},
{
"name": "pear-pear.php.net/XML_Util",
"version": "1.4.2",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/XML_Util-1.4.2.tgz",
"reference": null,
"shasum": null
},
"require": {
"ext-pcre": "*",
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/xml_util": "== 1.4.2.0"
},
"type": "pear-library",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD License"
],
"description": "Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more."
} }
], ],
"packages-dev": [], "packages-dev": [],

View file

@ -96,3 +96,20 @@ If a package needs to be updated, whether to the next minor version or to the ne
Then you should run `util/composer.phar update` to update it in your local `vendor` folder and update the `composer.lock` file that specifies the current versions of the dependencies. Then you should run `util/composer.phar update` to update it in your local `vendor` folder and update the `composer.lock` file that specifies the current versions of the dependencies.
Please note that you should commit both `composer.json` and `composer.lock` with your work every time you make a change to the former. Please note that you should commit both `composer.json` and `composer.lock` with your work every time you make a change to the former.
## Composer FAQ
### I used the `composer` command and got a warning about not to run it as root.
See [https://getcomposer.org/root]().
Composer should be run as the web server user, usually `www-data` with Apache or `http` with nginx.
If you can't switch to the web server user using `su - [web user]`, you can directly run the Composer command with `sudo -u [web user]`.
### Running Composer with `sudo` complains about not being able to create the composer cache directory in `/root/.composer`
This is because `sudo` doesn't always change the `HOME` environment variable, which means that the command is run as the web server user but the system still uses `root` home directory.
However, you can temporarily change environment variable for the execution of a single command.
For Composer, this would be:
````
$> COMPOSER_HOME=/var/tmp/composer sudo -u [web user] util/composer.phar [mode]
````

View file

@ -1,11 +1,12 @@
<?php <?php
require_once 'include/oembed.php'; use League\HTMLToMarkdown\HtmlConverter;
require_once 'include/event.php';
require_once 'library/markdown.php'; require_once "include/oembed.php";
require_once 'include/html2bbcode.php'; require_once "include/event.php";
require_once 'include/bbcode.php'; require_once "library/markdown.php";
require_once 'library/html-to-markdown/HTML_To_Markdown.php'; require_once "include/html2bbcode.php";
require_once "include/bbcode.php";
/** /**
* @brief Callback function to replace a Diaspora style mention in a mention for Friendica * @brief Callback function to replace a Diaspora style mention in a mention for Friendica
@ -105,8 +106,18 @@ function diaspora_mentions($match) {
return $mention; return $mention;
} }
/**
* @brief Converts a BBCode text into Markdown
*
* This function converts a BBCode item body to be sent to Markdown-enabled
* systems like Diaspora and Libertree
*
* @param string $Text
* @param bool $preserve_nl Effects unclear, unused in Friendica
* @param bool $fordiaspora Diaspora requires more changes than Libertree
* @return string
*/
function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) { function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$a = get_app(); $a = get_app();
$OriginalText = $Text; $OriginalText = $Text;
@ -120,13 +131,27 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
* Transform #tags, strip off the [url] and replace spaces with underscore * Transform #tags, strip off the [url] and replace spaces with underscore
*/ */
$URLSearchString = "^\[\]"; $URLSearchString = "^\[\]";
$Text = preg_replace_callback("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i", create_function('$match', $Text = preg_replace_callback("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i",
'return \'#\'. str_replace(\' \', \'_\', $match[2]);' function ($matches) {
), $Text); return '#' . str_replace(' ', '_', $matches[2]);
}
, $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it. // Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text); $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
// Extracting multi-line code blocks before the whitespace processing/code highlighter in bbcode()
$codeblocks = [];
$Text = preg_replace_callback('#\[code(?:=([^\]]*))?\](?=\n)(.*?)\[\/code\]#is',
function ($matches) use (&$codeblocks) {
$return = '#codeblock-' . count($codeblocks) . '#';
$prefix = '````' . $matches[1] . PHP_EOL;
$codeblocks[] = $prefix . trim($matches[2]) . PHP_EOL . '````';
return $return;
}
, $Text);
// Convert it to HTML - don't try oembed // Convert it to HTML - don't try oembed
if ($fordiaspora) { if ($fordiaspora) {
$Text = bbcode($Text, $preserve_nl, false, 3); $Text = bbcode($Text, $preserve_nl, false, 3);
@ -136,19 +161,18 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$tagline = ""; $tagline = "";
foreach ($tags[2] as $tag) { foreach ($tags[2] as $tag) {
$tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8'); $tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), "#" . $tag)) { if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) {
$tagline .= "#" . $tag . " "; $tagline .= '#' . $tag . ' ';
} }
} }
$Text = $Text." ".$tagline; $Text = $Text." ".$tagline;
} }
} else { } else {
$Text = bbcode($Text, $preserve_nl, false, 4); $Text = bbcode($Text, $preserve_nl, false, 4);
} }
// mask some special HTML chars from conversation to markdown // mask some special HTML chars from conversation to markdown
$Text = str_replace(array('&lt;','&gt;','&amp;'),array('&_lt_;','&_gt_;','&_amp_;'),$Text); $Text = str_replace(array('&lt;', '&gt;', '&amp;'), array('&_lt_;', '&_gt_;', '&_amp_;'), $Text);
// If a link is followed by a quote then there should be a newline before it // If a link is followed by a quote then there should be a newline before it
// Maybe we should make this newline at every time before a quote. // Maybe we should make this newline at every time before a quote.
@ -157,10 +181,11 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$stamp1 = microtime(true); $stamp1 = microtime(true);
// Now convert HTML to Markdown // Now convert HTML to Markdown
$Text = new HTML_To_Markdown($Text); $converter = new HtmlConverter();
$Text = $converter->convert($Text);
// unmask the special chars back to HTML // unmask the special chars back to HTML
$Text = str_replace(array('&_lt_;','&_gt_;','&_amp_;'),array('&lt;','&gt;','&amp;'),$Text); $Text = str_replace(array('&_lt_;', '&_gt_;', '&_amp_;'), array('&lt;', '&gt;', '&amp;'), $Text);
$a->save_timestamp($stamp1, "parser"); $a->save_timestamp($stamp1, "parser");
@ -176,14 +201,25 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$Text = preg_replace_callback("/([@]\[(.*?)\])\(([$URLSearchString]*?)\)/ism", 'diaspora_mentions', $Text); $Text = preg_replace_callback("/([@]\[(.*?)\])\(([$URLSearchString]*?)\)/ism", 'diaspora_mentions', $Text);
} }
// Restore code blocks
$Text = preg_replace_callback('/#codeblock-([0-9]+)#/iU',
function ($matches) use ($codeblocks) {
$return = '';
if (isset($codeblocks[intval($matches[1])])) {
$return = $codeblocks[$matches[1]];
}
return $return;
}
, $Text);
call_hooks('bb2diaspora',$Text); call_hooks('bb2diaspora',$Text);
return $Text; return $Text;
} }
function unescape_underscores_in_links($m) { function unescape_underscores_in_links($m) {
$y = str_replace('\\_','_', $m[2]); $y = str_replace('\\_', '_', $m[2]);
return '[' . $m[1] . '](' . $y . ')'; return('[' . $m[1] . '](' . $y . ')');
} }
function format_event_diaspora($ev) { function format_event_diaspora($ev) {

View file

@ -1,12 +1,12 @@
<?php <?php
use \Friendica\Core\Config; use \Friendica\Core\Config;
require_once("include/oembed.php"); require_once 'include/oembed.php';
require_once('include/event.php'); require_once 'include/event.php';
require_once('include/map.php'); require_once 'include/map.php';
require_once('mod/proxy.php'); require_once 'mod/proxy.php';
require_once('include/Contact.php'); require_once 'include/Contact.php';
require_once('include/plaintext.php'); require_once 'include/plaintext.php';
function bb_PictureCacheExt($matches) { function bb_PictureCacheExt($matches) {
if (strpos($matches[3], "data:image/") === 0) { if (strpos($matches[3], "data:image/") === 0) {
@ -172,14 +172,7 @@ function stripcode_br_cb($s) {
return '[code]' . str_replace('<br />', '', $s[1]) . '[/code]'; return '[code]' . str_replace('<br />', '', $s[1]) . '[/code]';
} }
function bb_onelinecode_cb($match) { function tryoembed($match) {
if (strpos($match[1], "<br>") === false) {
return "<key>" . $match[1] . "</key>";
}
return "<code>" . $match[1] . "</code>";
}
function tryoembed($match){
$url = $match[1]; $url = $match[1];
// Always embed the SSL version // Always embed the SSL version
@ -203,7 +196,6 @@ function tryoembed($match){
$html = oembed_format_object($o); $html = oembed_format_object($o);
return $html; return $html;
} }
// [noparse][i]italic[/i][/noparse] turns into // [noparse][i]italic[/i][/noparse] turns into
@ -230,14 +222,13 @@ function bb_unspacefy_and_trim($st) {
} }
function bb_find_open_close($s, $open, $close, $occurence = 1) { function bb_find_open_close($s, $open, $close, $occurence = 1) {
if ($occurence < 1) { if ($occurence < 1) {
$occurence = 1; $occurence = 1;
} }
$start_pos = -1; $start_pos = -1;
for ($i = 1; $i <= $occurence; $i++) { for ($i = 1; $i <= $occurence; $i++) {
if ($start_pos !== false) { if ( $start_pos !== false) {
$start_pos = strpos($s, $open, $start_pos + 1); $start_pos = strpos($s, $open, $start_pos + 1);
} }
} }
@ -258,14 +249,13 @@ function bb_find_open_close($s, $open, $close, $occurence = 1) {
} }
function get_bb_tag_pos($s, $name, $occurence = 1) { function get_bb_tag_pos($s, $name, $occurence = 1) {
if ($occurence < 1) { if ($occurence < 1) {
$occurence = 1; $occurence = 1;
} }
$start_open = -1; $start_open = -1;
for ($i = 1; $i <= $occurence; $i++) { for ($i = 1; $i <= $occurence; $i++) {
if ($start_open !== false) { if ( $start_open !== false) {
$start_open = strpos($s, '[' . $name, $start_open + 1); // allow [name= type tags $start_open = strpos($s, '[' . $name, $start_open + 1); // allow [name= type tags
} }
} }
@ -314,7 +304,6 @@ function bb_tag_preg_replace($pattern, $replace, $name, $s) {
$occurence = 1; $occurence = 1;
$pos = get_bb_tag_pos($string, $name, $occurence); $pos = get_bb_tag_pos($string, $name, $occurence);
while ($pos !== false && $occurence < 1000) { while ($pos !== false && $occurence < 1000) {
$start = substr($string, 0, $pos['start']['open']); $start = substr($string, 0, $pos['start']['open']);
$subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']); $subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']);
$end = substr($string, $pos['end']['close']); $end = substr($string, $pos['end']['close']);
@ -766,19 +755,41 @@ function bb_highlight($match) {
return $match[0]; return $match[0];
} }
// BBcode 2 HTML was written by WAY2WEB.net /**
// extended to work with Mistpark/Friendica - Mike Macgirvin * @brief Converts a BBCode message to HTML message
*
function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = false, $forplaintext = false) { * BBcode 2 HTML was written by WAY2WEB.net
* extended to work with Mistpark/Friendica - Mike Macgirvin
*
* Simple HTML values meaning:
* - 0: Friendica display
* - 1: Unused
* - 2: Used for Facebook, Google+, Windows Phone push, Friendica API
* - 3: Used before converting to Markdown in bb2diaspora.php
* - 4: Used for WordPress, Libertree (before Markdown), pump.io and tumblr
* - 5: Unused
* - 6: Used for Appnet
* - 7: Used for dfrn, OStatus
* - 8: Used for WP backlink text setting
*
* @staticvar array $allowed_src_protocols
* @param string $Text
* @param bool $preserve_nl
* @param bool $tryoembed
* @param int $simplehtml
* @param bool $forplaintext
* @return string
*/
function bbcode($Text, $preserve_nl = false, $tryoembed = true, $simplehtml = false, $forplaintext = false) {
$a = get_app(); $a = get_app();
// Hide all [noparse] contained bbtags by spacefying them // Hide all [noparse] contained bbtags by spacefying them
// POSSIBLE BUG --> Will the 'preg' functions crash if there's an embedded image? // POSSIBLE BUG --> Will the 'preg' functions crash if there's an embedded image?
$Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text); $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy', $Text);
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text); $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy', $Text);
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy', $Text);
// Remove the abstract element. It is a non visible element. // Remove the abstract element. It is a non visible element.
$Text = remove_abstract($Text); $Text = remove_abstract($Text);
@ -808,19 +819,20 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = str_replace(">", "&gt;", $Text); $Text = str_replace(">", "&gt;", $Text);
// remove some newlines before the general conversion // remove some newlines before the general conversion
$Text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","[share$1]$2[/share]",$Text); $Text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "[share$1]$2[/share]", $Text);
$Text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism","[quote$1]$2[/quote]",$Text); $Text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism", "[quote$1]$2[/quote]", $Text);
$Text = preg_replace("/\n\[code\]/ism", "[code]", $Text); $Text = preg_replace("/\n\[code\]/ism", "[code]", $Text);
$Text = preg_replace("/\[\/code\]\n/ism", "[/code]", $Text); $Text = preg_replace("/\[\/code\]\n/ism", "[/code]", $Text);
// when the content is meant exporting to other systems then remove the avatar picture since this doesn't really look good on these systems // when the content is meant exporting to other systems then remove the avatar picture since this doesn't really look good on these systems
if (!$tryoembed) if (!$tryoembed) {
$Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","\n[share$1$2]$3[/share]",$Text); $Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "\n[share$1$2]$3[/share]", $Text);
}
// Check for [code] text here, before the linefeeds are messed with. // Check for [code] text here, before the linefeeds are messed with.
// The highlighter will unescape and re-escape the content. // The highlighter will unescape and re-escape the content.
if (strpos($Text,'[code=') !== false) { if (strpos($Text, '[code=') !== false) {
$Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text); $Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
} }
// Convert new line chars to html <br /> tags // Convert new line chars to html <br /> tags
@ -831,7 +843,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// We'll emulate it. // We'll emulate it.
$Text = trim($Text); $Text = trim($Text);
$Text = str_replace("\r\n","\n", $Text); $Text = str_replace("\r\n", "\n", $Text);
// removing multiplicated newlines // removing multiplicated newlines
if (get_config("system", "remove_multiplicated_lines")) { if (get_config("system", "remove_multiplicated_lines")) {
@ -850,8 +862,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = str_replace(array("\r","\n"), array('<br />','<br />'), $Text); $Text = str_replace(array("\r","\n"), array('<br />','<br />'), $Text);
if ($preserve_nl) if ($preserve_nl) {
$Text = str_replace(array("\n","\r"), array('',''),$Text); $Text = str_replace(array("\n", "\r"), array('', ''), $Text);
}
// Set up the parameters for a URL search string // Set up the parameters for a URL search string
$URLSearchString = "^\[\]"; $URLSearchString = "^\[\]";
@ -859,20 +872,21 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$MAILSearchString = $URLSearchString; $MAILSearchString = $URLSearchString;
// Remove all hashtag addresses // Remove all hashtag addresses
if ((!$tryoembed OR $simplehtml) AND !in_array($simplehtml, array(3, 7))) if ((!$tryoembed OR $simplehtml) AND !in_array($simplehtml, array(3, 7))) {
$Text = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $Text); $Text = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $Text);
elseif ($simplehtml == 3) } elseif ($simplehtml == 3) {
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<a href="$2">$3</a>', '$1<a href="$2">$3</a>',
$Text); $Text);
elseif ($simplehtml == 7) } elseif ($simplehtml == 7) {
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<span class="vcard"><a href="$2" class="url" title="$3"><span class="fn nickname mention">$3</span></a></span>', '$1<span class="vcard"><a href="$2" class="url" title="$3"><span class="fn nickname mention">$3</span></a></span>',
$Text); $Text);
elseif (!$simplehtml) } elseif (!$simplehtml) {
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<a href="$2" class="userinfo mention" title="$3">$3</a>', '$1<a href="$2" class="userinfo mention" title="$3">$3</a>',
$Text); $Text);
}
// Bookmarks in red - will be converted to bookmarks in friendica // Bookmarks in red - will be converted to bookmarks in friendica
$Text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $Text); $Text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $Text);
@ -881,38 +895,42 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
"[bookmark=$1]$2[/bookmark]", $Text); "[bookmark=$1]$2[/bookmark]", $Text);
if (in_array($simplehtml, array(2, 6, 7, 8, 9))) { if (in_array($simplehtml, array(2, 6, 7, 8, 9))) {
$Text = preg_replace_callback("/([^#@])\[url\=([^\]]*)\](.*?)\[\/url\]/ism","bb_expand_links",$Text); $Text = preg_replace_callback("/([^#@])\[url\=([^\]]*)\](.*?)\[\/url\]/ism", "bb_expand_links", $Text);
//$Text = preg_replace("/[^#@]\[url\=([^\]]*)\](.*?)\[\/url\]/ism",' $2 [url]$1[/url]',$Text); //$Text = preg_replace("/[^#@]\[url\=([^\]]*)\](.*?)\[\/url\]/ism", ' $2 [url]$1[/url]', $Text);
$Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",' $2 [url]$1[/url]',$Text); $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", ' $2 [url]$1[/url]',$Text);
} }
if ($simplehtml == 5) if ($simplehtml == 5) {
$Text = preg_replace("/[^#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[url]$1[/url]', $Text); $Text = preg_replace("/[^#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[url]$1[/url]', $Text);
}
// Perform URL Search // Perform URL Search
if ($tryoembed) if ($tryoembed) {
$Text = preg_replace_callback("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'tryoembed',$Text); $Text = preg_replace_callback("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", 'tryoembed', $Text);
}
if ($simplehtml == 5) if ($simplehtml == 5) {
$Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url]$1[/url]',$Text); $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url]$1[/url]', $Text);
else } else {
$Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url=$1]$2[/url]',$Text); $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url=$1]$2[/url]', $Text);
}
// Handle Diaspora posts // Handle Diaspora posts
$Text = preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi", 'bb_DiasporaLinks', $Text); $Text = preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi", 'bb_DiasporaLinks', $Text);
// if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text // if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
// if ($simplehtml != 7) { // if ($simplehtml != 7) {
if (!$forplaintext) if (!$forplaintext) {
$Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text); $Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text);
else { } else {
$Text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism"," $1 ",$Text); $Text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism", " $1 ", $Text);
$Text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_RemovePictureLinks', $Text); $Text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_RemovePictureLinks', $Text);
} }
// } // }
if ($tryoembed) if ($tryoembed) {
$Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text); $Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text);
}
$Text = preg_replace("/([#])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $Text = preg_replace("/([#])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<a href="$2" class="tag" title="$3">$3</a>', $Text); '$1<a href="$2" class="tag" title="$3">$3</a>', $Text);
@ -928,7 +946,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// we may need to restrict this further if it picks up too many strays // we may need to restrict this further if it picks up too many strays
// link acct:user@host to a webfinger profile redirector // link acct:user@host to a webfinger profile redirector
$Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', '<a href="' . App::get_baseurl() . '/acctlink?addr=$1@$2" target="extlink">acct:$1@$2</a>',$Text); $Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', '<a href="' . App::get_baseurl() . '/acctlink?addr=$1@$2" target="extlink">acct:$1@$2</a>', $Text);
// Perform MAIL Search // Perform MAIL Search
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text); $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
@ -937,61 +955,61 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// leave open the posibility of [map=something] // leave open the posibility of [map=something]
// this is replaced in prepare_body() which has knowledge of the item location // this is replaced in prepare_body() which has knowledge of the item location
if (strpos($Text,'[/map]') !== false) { if (strpos($Text, '[/map]') !== false) {
$Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text); $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text);
} }
if (strpos($Text,'[map=') !== false) { if (strpos($Text, '[map=') !== false) {
$Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text); $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text);
} }
if (strpos($Text,'[map]') !== false) { if (strpos($Text, '[map]') !== false) {
$Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text); $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text);
} }
// Check for headers // Check for headers
$Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text); $Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism", '<h1>$1</h1>', $Text);
$Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text); $Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism", '<h2>$1</h2>', $Text);
$Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text); $Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism", '<h3>$1</h3>', $Text);
$Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text); $Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism", '<h4>$1</h4>', $Text);
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text); $Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism", '<h5>$1</h5>', $Text);
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text); $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism", '<h6>$1</h6>', $Text);
// Check for paragraph // Check for paragraph
$Text = preg_replace("(\[p\](.*?)\[\/p\])ism",'<p>$1</p>',$Text); $Text = preg_replace("(\[p\](.*?)\[\/p\])ism", '<p>$1</p>', $Text);
// Check for bold text // Check for bold text
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text); $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $Text);
// Check for Italics text // Check for Italics text
$Text = preg_replace("(\[i\](.*?)\[\/i\])ism",'<em>$1</em>',$Text); $Text = preg_replace("(\[i\](.*?)\[\/i\])ism", '<em>$1</em>', $Text);
// Check for Underline text // Check for Underline text
$Text = preg_replace("(\[u\](.*?)\[\/u\])ism",'<u>$1</u>',$Text); $Text = preg_replace("(\[u\](.*?)\[\/u\])ism", '<u>$1</u>', $Text);
// Check for strike-through text // Check for strike-through text
$Text = preg_replace("(\[s\](.*?)\[\/s\])ism",'<strike>$1</strike>',$Text); $Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<strike>$1</strike>', $Text);
// Check for over-line text // Check for over-line text
$Text = preg_replace("(\[o\](.*?)\[\/o\])ism",'<span class="overline">$1</span>',$Text); $Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span class="overline">$1</span>', $Text);
// Check for colored text // Check for colored text
$Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","<span style=\"color: $1;\">$2</span>",$Text); $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $Text);
// Check for sized text // Check for sized text
// [size=50] --> font-size: 50px (with the unit). // [size=50] --> font-size: 50px (with the unit).
$Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1px; line-height: initial;\">$2</span>",$Text); $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px; line-height: initial;\">$2</span>", $Text);
$Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1; line-height: initial;\">$2</span>",$Text); $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1; line-height: initial;\">$2</span>", $Text);
// Check for centered text // Check for centered text
$Text = preg_replace("(\[center\](.*?)\[\/center\])ism","<div style=\"text-align:center;\">$1</div>",$Text); $Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
// Check for list text // Check for list text
$Text = str_replace("[*]", "<li>", $Text); $Text = str_replace("[*]", "<li>", $Text);
// Check for style sheet commands // Check for style sheet commands
$Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism","bb_cleanstyle",$Text); $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_cleanstyle", $Text);
// Check for CSS classes // Check for CSS classes
$Text = preg_replace_callback("(\[class=(.*?)\](.*?)\[\/class\])ism","bb_cleanclass",$Text); $Text = preg_replace_callback("(\[class=(.*?)\](.*?)\[\/class\])ism", "bb_cleanclass", $Text);
// handle nested lists // handle nested lists
$endlessloop = 0; $endlessloop = 0;
@ -1000,42 +1018,42 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) || ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) || ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) { ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
$Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text); $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>', $Text);
$Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $Text);
$Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism", '<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>' ,$Text); $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $Text);
$Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text); $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>', $Text);
$Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text); $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
$Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>' ,$Text); $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $Text);
} }
$Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>' ,$Text); $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $Text);
$Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text); $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>', $Text);
$Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text); $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>', $Text);
$Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>' ,$Text); $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $Text);
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>' ,$Text); $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>', $Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>' ,$Text); $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>', $Text);
$Text = str_replace('[hr]','<hr />', $Text); $Text = str_replace('[hr]', '<hr />', $Text);
// This is actually executed in prepare_body() // This is actually executed in prepare_body()
$Text = str_replace('[nosmile]','',$Text); $Text = str_replace('[nosmile]', '', $Text);
// Check for font change text // Check for font change text
$Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm","<span style=\"font-family: $1;\">$2</span>",$Text); $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $Text);
// Declare the format for [code] layout // Declare the format for [code] layout
// $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism",'stripcode_br_cb',$Text); // $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'stripcode_br_cb', $Text);
$CodeLayout = '<code>$1</code>'; $CodeLayout = '<code>$1</code>';
// Check for [code] text // Check for [code] text
$Text = preg_replace("/\[code\](.*?)\[\/code\]/ism","$CodeLayout", $Text); $Text = preg_replace("/\[code\](.*?)\[\/code\]/ism", "$CodeLayout", $Text);
// Declare the format for [spoiler] layout // Declare the format for [spoiler] layout
$SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>'; $SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>';
@ -1043,8 +1061,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// Check for [spoiler] text // Check for [spoiler] text
// handle nested quotes // handle nested quotes
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/spoiler]") !== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) while ((strpos($Text, "[/spoiler]") !== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
$Text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism","$SpoilerLayout", $Text); $Text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism", "$SpoilerLayout", $Text);
}
// Check for [spoiler=Author] text // Check for [spoiler=Author] text
@ -1052,10 +1071,11 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// handle nested quotes // handle nested quotes
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) {
$Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism", $Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
"<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>", "<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
$Text); $Text);
}
// Declare the format for [quote] layout // Declare the format for [quote] layout
$QuoteLayout = '<blockquote>$1</blockquote>'; $QuoteLayout = '<blockquote>$1</blockquote>';
@ -1063,8 +1083,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// Check for [quote] text // Check for [quote] text
// handle nested quotes // handle nested quotes
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20)) while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20)) {
$Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text); $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text);
}
// Check for [quote=Author] text // Check for [quote=Author] text
@ -1072,10 +1093,11 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// handle nested quotes // handle nested quotes
$endlessloop = 0; $endlessloop = 0;
while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20)) while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20)) {
$Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>", "<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
$Text); $Text);
}
// [img=widthxheight]image source[/img] // [img=widthxheight]image source[/img]
@ -1095,11 +1117,11 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism", $Text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism",
function ($match) use ($simplehtml){ function ($match) use ($simplehtml){
return(bb_ShareAttributes($match, $simplehtml)); return(bb_ShareAttributes($match, $simplehtml));
},$Text); }, $Text);
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br />', $Text); $Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism", '<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br />', $Text);
$Text = preg_replace("/\[crypt(.*?)\](.*?)\[\/crypt\]/ism",'<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text); $Text = preg_replace("/\[crypt(.*?)\](.*?)\[\/crypt\]/ism", '<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text);
//$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism",'<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text); //$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism", '<br/><img src="' .App::get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text);
// Try to Oembed // Try to Oembed
@ -1119,41 +1141,44 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// html5 video and audio // html5 video and audio
if ($tryoembed) if ($tryoembed) {
$Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<iframe src="$1" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="$1">$1</a></iframe>', $Text); $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<iframe src="$1" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="$1">$1</a></iframe>', $Text);
else } else {
$Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text); $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text);
}
// Youtube extensions // Youtube extensions
if ($tryoembed) { if ($tryoembed) {
$Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text); $Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text); $Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism",'tryoembed',$Text); $Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
} }
$Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
$Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
$Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
if ($tryoembed)
$Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
else
$Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
'<a href="https://www.youtube.com/watch?v=$1" target="_blank">https://www.youtube.com/watch?v=$1</a>', $Text);
if ($tryoembed) { if ($tryoembed) {
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text); $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text); } else {
$Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
'<a href="https://www.youtube.com/watch?v=$1" target="_blank">https://www.youtube.com/watch?v=$1</a>', $Text);
} }
$Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text); if ($tryoembed) {
$Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text); $Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
}
if ($tryoembed) $Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
$Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
if ($tryoembed) {
$Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text); $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
else } else {
$Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism",
'<a href="https://vimeo.com/$1" target="_blank">https://vimeo.com/$1</a>', $Text); '<a href="https://vimeo.com/$1" target="_blank">https://vimeo.com/$1</a>', $Text);
}
// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text); // $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
@ -1168,33 +1193,42 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// Summary (e.g. title) is required, earlier revisions only required description (in addition to // Summary (e.g. title) is required, earlier revisions only required description (in addition to
// start which is always required). Allow desc with a missing summary for compatibility. // start which is always required). Allow desc with a missing summary for compatibility.
if ((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) { if((x($ev, 'desc') || x($ev, 'summary')) && x($ev, 'start')) {
$sub = format_event_html($ev, $simplehtml); $sub = format_event_html($ev, $simplehtml);
$Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text); $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism", '', $Text);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text); $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism", '', $Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text); $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism", $sub, $Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text); $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism", '', $Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text); $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism", '', $Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text); $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism", '', $Text);
$Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text); $Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism", '', $Text);
} }
//replace oneliner <code> with <key> // Replace inline code blocks
$Text = preg_replace_callback("|(?!<br[^>]*>)<code>([^<]*)</code>(?!<br[^>]*>)|ism", 'bb_onelinecode_cb', $Text); $Text = preg_replace_callback("|(?!<br[^>]*>)<code>([^<]*)</code>(?!<br[^>]*>)|ism",
function ($match) use ($simplehtml) {
$return = '<key>' . $match[1] . '</key>';
// Use <code> for Diaspora inline code blocks
if ($simplehtml === 3) {
$return = '<code>' . $match[1] . '</code>';
}
return $return;
}
, $Text);
// Unhide all [noparse] contained bbtags unspacefying them // Unhide all [noparse] contained bbtags unspacefying them
// and triming the [noparse] tag. // and triming the [noparse] tag.
$Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim',$Text); $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text);
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text); $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text);
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text); $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text);
$Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/','&$1;',$Text); $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
$Text = preg_replace('/\&\#039\;/','\'',$Text); $Text = preg_replace('/\&\#039\;/', '\'', $Text);
$Text = preg_replace('/\&quot\;/','"',$Text); $Text = preg_replace('/\&quot\;/', '"', $Text);
// fix any escaped ampersands that may have been converted into links // fix any escaped ampersands that may have been converted into links
$Text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism', '<$1$2=$3&$4>', $Text); $Text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism', '<$1$2=$3&$4>', $Text);
@ -1234,19 +1268,19 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = $doc->saveHTML(); $Text = $doc->saveHTML();
$Text = str_replace(array("<html><body>", "</body></html>", $doctype, $encoding), array("", "", "", ""), $Text); $Text = str_replace(array("<html><body>", "</body></html>", $doctype, $encoding), array("", "", "", ""), $Text);
$Text = str_replace('<br></li>','</li>', $Text); $Text = str_replace('<br></li>', '</li>', $Text);
//$Text = mb_convert_encoding($Text, "UTF-8", 'HTML-ENTITIES'); //$Text = mb_convert_encoding($Text, "UTF-8", 'HTML-ENTITIES');
} }
// Clean up some useless linebreaks in lists // Clean up some useless linebreaks in lists
//$Text = str_replace('<br /><ul','<ul ', $Text); //$Text = str_replace('<br /><ul', '<ul ', $Text);
//$Text = str_replace('</ul><br />','</ul>', $Text); //$Text = str_replace('</ul><br />', '</ul>', $Text);
//$Text = str_replace('</li><br />','</li>', $Text); //$Text = str_replace('</li><br />', '</li>', $Text);
//$Text = str_replace('<br /><li>','<li>', $Text); //$Text = str_replace('<br /><li>', '<li>', $Text);
// $Text = str_replace('<br /><ul','<ul ', $Text); //$Text = str_replace('<br /><ul', '<ul ', $Text);
call_hooks('bbcode',$Text); call_hooks('bbcode', $Text);
return trim($Text); return trim($Text);
} }
@ -1289,4 +1323,3 @@ function fetch_abstract($text, $addon = "") {
return $abstract; return $abstract;
} }
?>

View file

@ -200,7 +200,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
if ($item["plink"] == "") { if ($item["plink"] == "") {
$item["plink"] = $xpath->evaluate('rss:link/text()', $entry)->item(0)->nodeValue; $item["plink"] = $xpath->evaluate('rss:link/text()', $entry)->item(0)->nodeValue;
} }
$item["plink"] = original_url($item["plink"]);
$item["uri"] = $xpath->evaluate('atom:id/text()', $entry)->item(0)->nodeValue; $item["uri"] = $xpath->evaluate('atom:id/text()', $entry)->item(0)->nodeValue;
@ -210,12 +209,17 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
if ($item["uri"] == "") { if ($item["uri"] == "") {
$item["uri"] = $item["plink"]; $item["uri"] = $item["plink"];
} }
$orig_plink = $item["plink"];
$item["plink"] = original_url($item["plink"]);
$item["parent-uri"] = $item["uri"]; $item["parent-uri"] = $item["uri"];
if (!$simulate) { if (!$simulate) {
$r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `network` IN ('%s', '%s')", $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `network` IN ('%s', '%s')",
intval($importer["uid"]), dbesc($item["uri"]), dbesc(NETWORK_FEED), dbesc(NETWORK_DFRN)); intval($importer["uid"]), dbesc($item["uri"]), dbesc(NETWORK_FEED), dbesc(NETWORK_DFRN));
if ($r) { if (dbm::is_result($r)) {
logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG); logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG);
continue; continue;
} }
@ -340,6 +344,7 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
// Distributed items should have a well formatted URI. // Distributed items should have a well formatted URI.
// Additionally we have to avoid conflicts with identical URI between imported feeds and these items. // Additionally we have to avoid conflicts with identical URI between imported feeds and these items.
if ($notify) { if ($notify) {
$item['guid'] = uri_to_guid($orig_plink, $a->get_hostname());
unset($item['uri']); unset($item['uri']);
unset($item['parent-uri']); unset($item['parent-uri']);
} }

View file

@ -407,12 +407,14 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
// We have to avoid duplicates. So we create the GUID in form of a hash of the plink or uri. // We have to avoid duplicates. So we create the GUID in form of a hash of the plink or uri.
// In difference to the call to "uri_to_guid" several lines below we add the hash of our own host. // In difference to the call to "uri_to_guid" several lines below we add the hash of our own host.
// This is done because our host is the original creator of the post. // This is done because our host is the original creator of the post.
if (!isset($arr['guid'])) {
if (isset($arr['plink'])) { if (isset($arr['plink'])) {
$arr['guid'] = uri_to_guid($arr['plink'], $a->get_hostname()); $arr['guid'] = uri_to_guid($arr['plink'], $a->get_hostname());
} elseif (isset($arr['uri'])) { } elseif (isset($arr['uri'])) {
$arr['guid'] = uri_to_guid($arr['uri'], $a->get_hostname()); $arr['guid'] = uri_to_guid($arr['uri'], $a->get_hostname());
} }
} }
}
// If a Diaspora signature structure was passed in, pull it out of the // If a Diaspora signature structure was passed in, pull it out of the
// item array and set it aside for later storage. // item array and set it aside for later storage.

View file

@ -2125,47 +2125,48 @@ function format_network_name($network, $url = 0) {
* @param string $lang Programming language * @param string $lang Programming language
* @return string Formated html * @return string Formated html
*/ */
function text_highlight($s,$lang) { function text_highlight($s, $lang) {
if($lang === 'js') if ($lang === 'js') {
$lang = 'javascript'; $lang = 'javascript';
if(! strpos('Text_Highlighter',get_include_path())) {
set_include_path(get_include_path() . PATH_SEPARATOR . 'library/Text_Highlighter');
} }
require_once('library/Text_Highlighter/Text/Highlighter.php'); // @TODO: Replace Text_Highlighter_Renderer_Html by scrivo/highlight.php
require_once('library/Text_Highlighter/Text/Highlighter/Renderer/Html.php');
// Autoload the library to make constants available
class_exists('Text_Highlighter_Renderer_Html');
$options = array( $options = array(
'numbers' => HL_NUMBERS_LI, 'numbers' => HL_NUMBERS_LI,
'tabsize' => 4, 'tabsize' => 4,
); );
$tag_added = false; $tag_added = false;
$s = trim(html_entity_decode($s,ENT_COMPAT)); $s = trim(html_entity_decode($s, ENT_COMPAT));
$s = str_replace(" ","\t",$s); $s = str_replace(' ', "\t", $s);
// The highlighter library insists on an opening php tag for php code blocks. If // The highlighter library insists on an opening php tag for php code blocks. If
// it isn't present, nothing is highlighted. So we're going to see if it's present. // it isn't present, nothing is highlighted. So we're going to see if it's present.
// If not, we'll add it, and then quietly remove it after we get the processed output back. // If not, we'll add it, and then quietly remove it after we get the processed output back.
if($lang === 'php') { if ($lang === 'php') {
if(strpos('<?php',$s) !== 0) { if (strpos($s, '<?php') !== 0) {
$s = '<?php' . "\n" . $s; $s = '<?php' . "\n" . $s;
$tag_added = true; $tag_added = true;
} }
} }
$renderer = new Text_Highlighter_Renderer_HTML($options); $renderer = new Text_Highlighter_Renderer_Html($options);
$hl = Text_Highlighter::factory($lang); $hl = Text_Highlighter::factory($lang);
$hl->setRenderer($renderer); $hl->setRenderer($renderer);
$o = $hl->highlight($s); $o = $hl->highlight($s);
$o = str_replace([" ","\n"],["&nbsp;&nbsp;&nbsp;&nbsp;",''],$o); $o = str_replace("\n", '', $o);
if($tag_added) {
$b = substr($o,0,strpos($o,'<li>')); if ($tag_added) {
$e = substr($o,strpos($o,'</li>')); $b = substr($o, 0, strpos($o, '<li>'));
$e = substr($o, strpos($o, '</li>'));
$o = $b . $e; $o = $b . $e;
} }
return('<code>' . $o . '</code>'); return '<code>' . $o . '</code>';
} }

View file

@ -21,7 +21,7 @@ function update_gcontact_run(&$argv, &$argc) {
$r = q("SELECT * FROM `gcontact` WHERE `id` = %d", intval($contact_id)); $r = q("SELECT * FROM `gcontact` WHERE `id` = %d", intval($contact_id));
if (!dbm::_is_result($r)) { if (!dbm::is_result($r)) {
return; return;
} }

View file

@ -1,455 +0,0 @@
# $Id$
Introduction
============
Text_Highlighter is a class for syntax highlighting. The main idea is to
simplify creation of subclasses implementing syntax highlighting for
particular language. Subclasses do not implement any new functioanality, they
just provide syntax highlighting rules. The rules sources are in XML format.
To create a highlighter for a language, there is no need to code a new class
manually. Simply describe the rules in XML file and use Text_Highlighter_Generator
to create a new class.
This document does not contain a formal description of API - it is very
simple, and I believe providing some examples of code is sufficient.
Highlighter XML source
======================
Basics
------
Creating a new syntax highlighter begins with describing the highlighting
rules. There are two basic elements: block and region. A block is just a
portion of text matching a regular expression and highlighted with a single
color. Keyword is an example of a block. A region is defined by two regular
expressions: one for start of region, and another for the end. The main
difference from a block is that a region can contain blocks and regions
(including same-named regions). An example of a region is a group of
statements enclosed in curly brackets (this is used in many languages, for
example PHP and C). Also, characters matching start and end of a region may be
highlighted with their own color, and region contents with another.
Blocks and regions may be declared as contained. Contained blocks and regions
can only appear inside regions. If a region or a block is not declared as
contained, it can appear both on top level and inside regions. Block or region
declared as not-contained can only appear on top level.
For any region, a list of blocks and regions that can appear inside this
region can be specified.
In this document, the term "color group" is used. Chunks of text assigned to
same color group will be highlighted with same color. Note that in versions
prior 0.5.0 color goups were refered as CSS classes, but since 0.5.0 not only
HTML output is supported, so "color group" is more appropriate term.
Elements
--------
The toplevel element is <highlight>. Attribute lang is required and denotes
the name of the language. Its value is used as a part of generated class name,
and must only contain letters, digits and underscores. Optional attribute
case, when given value yes, makes the language case sensitive (default is case
insensitive). Allowed subelements are:
* <authors>: Information about the authors of the file.
<author>: Information about a single author of the file. (May be used
multiple times, one per author.)
- name="...": Author's name. Required.
- email="...": Author's email address. Optional.
* <default>: Default color group.
- innerGroup="...": color group name. Required.
* <region>: Region definition
- name="...": Region name. Required.
- innerGroup="...": Default color group of region contents. Required.
- delimGroup="...": color group of start and end of region. Optional,
defaults to value of innerGroup attribute.
- start="...", end="...": Regular expression matching start and end
of region. Required. Regular expression delimiters are optional, but
if you need to specify delimiter, use /. The only case when the
delimiters are needed, is specifying regular expression modifiers,
such as m or U. Examples: \/\* or /$/m.
- contained="yes": Marks region as contained.
- never-contained="yes": Marks region as not-contained.
- <contains>: Elements allowed inside this region.
- all="yes" Region can contain any other region or block
(except not-contained). May be used multiple times.
- <but> Do not allow certain regions or blocks.
- region="..." Name of region not allowed within
current region.
- block="..." Name of block not allowed within
current region.
- region="..." Name of region allowed within current region.
- block="..." Name of block allowed within current region.
- <onlyin> Only allow this region within certain regions. May be
used multiple times.
- block="..." Name of parent region
* <block>: Block definition
- name="...": Block name. Required.
- innerGroup="...": color group of block contents. Optional. If not
specified, color group of parent region or default color group will be
used. One would only want to omit this attribute if there are
keyword groups (see below) inherited from this block, and no special
highlighting should apply when the block does not match the keyword.
- match="..." Regular expression matching the block. Required.
Regular expression delimiters are optional, but if you need to
specify delimiter, use /. The only case when the delimiters are
needed, is specifying regular expression modifiers, such as m or U.
Examples: #|\/\/ or /$/m.
- contained="yes": Marks block as contained.
- never-contained="yes": Marks block as not-contained.
- <onlyin> Only allow this block within certain regions. May be used
multiple times.
- block="..." Name of parent region
- multiline="yes": Marks block as multi-line. By default, whole
blocks are assumed to reside in a single line. This make the things
faster. If you need to declare a multi-line block, use this
attribute.
- <partgroup>: Assigns another color group to a part of the block that
matched a subpattern.
- index="n": Subpattern index. Required.
- innerGroup="...": color group name. Required.
This is an example from CSS highlighter: the measure is matched as
a whole, but the measurement units are highlighted with different
color.
<block name="measure" match="\d*\.?\d+(\%|em|ex|pc|pt|px|in|mm|cm)"
innerGroup="number" contained="yes">
<onlyin region="property"/>
<partGroup index="1" innerGroup="string" />
</block>
* <keywords>: Keyword group definition. Keyword groups are useful when you
want to highlight some words that match a condition for a block with a
different color. Keywords are defined with literal match, not regular
expressions. For example, you have a block named identifier matching a
general identifier, and want to highlight reserved words (which match
this block as well) with different color. You inherit a keyword group
"reserved" from "identifier" block.
- name="...": Keyword group. Required.
- ifdef="...", ifndef="..." : Conditional declaration. See
"Conditions" below.
- inherits="...": Inherited block name. Required.
- innerGroup="...": color group of keyword group. Required.
- case="yes|no": Overrides case-sensitivity of the language.
Optional, defaults to global value.
- <keyword>: Single keyword definition.
- match="..." The keyword. Note: this is not a regular
expression, but literal match (possibly case insensitive).
Note that for BC reasons element partClass is alias for partGroup, and
attributes innerClass and delimClass are aliases of innerGroup and
delimGroup, respectively.
Conditions
----------
Conditional declarations allow enabling or disabling certain highlighting
rules at runtime. For example, Java highlighter has a very big list of
keywords matching Java standard classes. Finding a match in this list can take
much time. For that reason, corresponding keyword group is declared with
"ifdef" attribute :
<keywords name="builtin" inherits="identifier" innerClass="builtin"
case="yes" ifdef="java.builtins">
<keyword match="AbstractAction" />
<keyword match="AbstractBorder" />
<keyword match="AbstractButton" />
...
...
<keyword match="_Remote_Stub" />
<keyword match="_ServantActivatorStub" />
<keyword match="_ServantLocatorStub" />
</keywords>
This keyword group will be only enabled when "java.builtins" is passed as an
element of "defines" option:
$options = array(
'defines' => array(
'java.builtins',
),
'numbers' => HL_NUMBERS_TABLE,
);
$highlighter = Text_Highlighter::factory('java', $options);
"ifndef" attribute has reverse meaning.
Currently, "ifdef" and "ifndef" attributes are only supported for <keywords>
tag.
Class generation
================
Creating XML description of highlighting rules is the most complicated part of
the process. To generate the class, you need just few lines of code:
<?php
require_once 'Text/Highlighter/Generator.php';
$generator = new Text_Highlighter_Generator('php.xml');
$generator->generate();
$generator->saveCode('PHP.php');
?>
Command-line class generation tool
==================================
Example from previous section looks pretty simple, but it does not handle any
errors which may occur during parsing of XML source. The package provides a
command-line script to make generation of classes even more simple, and takes
care of possible errors. It is called generate (on Unix/Linux) or generate.bat
(on Windows). This script is able to process multiple files in one run, and
also to process XML from standard input and write generated code to standard
output.
Usage:
generate options
Options:
-x filename, --xml=filename
source XML file. Multiple input files can be specified, in which
case each -x option must be followed by -p unless -d is specified
Defaults to stdin
-p filename, --php=filename
destination PHP file. Defaults to stdout. If specied multiple times,
each -p must follow -x
-d dirname, --dir=dirname
Default destination directory. File names will be taken from XML input
("lang" attribute of <highlight> tag)
-h, --help
This help
Examples
Read from php.xml, write to PHP.php
generate -x php.xml -p PHP.php
Read from php.xml, write to standard output
generate -x php.xml
Read from php.xml, write to PHP.php, read from xml.xml, write to XML.php
generate -x php.xml -p PHP.php -x xml.xml -p XML.php
Read from php.xml, write to /some/dir/PHP.php, read from xml.xml, write to
/some/dir/XML.php (assuming that xml.xml contains <highlight lang="xml">, and
php.xml contains <highlight lang="php">)
generate -x php.xml -x xml.xml -d /some/dir/
Renderers
=========
Introduction
------------
Text_Highlighter supports renderes. Using renderers, you can get output in
different formats. Two renderers are included in the package:
- HTML renderer. Generates HTML output. A style sheet should be linked to
the document to display colored text
- Console renderer. Can be used to output highlighted text to
color-capable terminals, either directly or trough less -r
Renderers API
-------------
Renderers are subclasses of Text_Highlighter_Renderer. Renderer should
override at least two methods - acceptToken and getOutput. Overriding other
methods is optional, depending on the nature of renderer's output and details
of implementation.
string reset()
resets renderer state. This method is called every time before a new
source file is highlighted.
string preprocess(string $code)
preprocesses code. Can be used, for example, to normalize whitespace
before highlighting. Returns preprocessed string.
void acceptToken(string $group, string $content)
the core method of the renderer. Highlighter passes chunks of text to
this method in $content, and color group in $group
void finalize()
signals the renderer that no more tokens are available.
mixed getOutput()
returns generated output.
Setting renderer options
--------------------------------
Renderers accept an optional argument to their constructor - options array.
Elements of this array are renderer-specific.
HTML renderer
-------------
HTML renderer produces HTML output with optional line numbering. The renderer
itself does not provide information about actual colors of highlighted text.
Instead, <span class="hl-XXX"> is used, where XXX is replaced with color group
name (hl-var, hl-string, etc.). It is up to you to create a CSS stylesheet.
If 'use_language' option with value evaluating to true was passed, class names
will be formatted as "LANG-hl-XXX", where LANG is language name as defined in
highlighter XML source ("lang" attribute of <highlight> tag) in lower case.
There are 3 special CSS classes:
hl-main - this class applies to whole output or right table column,
depending on 'numbers' option
hl-gutter - applies to left column in table
hl-table - applies to whole table
HTML renderer accepts following options (each being optional):
* numbers - line numbering style.
0 - no numbering (default)
HL_NUMBERS_LI - use <ol></ol> for line numbering
HL_NUMBERS_TABLE - create a 2-column table, with line numbers in left
column and highlighted text in right column
* tabsize - tabulation size. Defaults to 4
Example:
require_once 'Text/Highlighter/Renderer/Html.php';
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 8,
);
$renderer = new Text_Highlighter_Renderer_HTML($options);
Console renderer
----------------
Console renderer produces output for displaying on a color-capable terminal,
either directly or through less -r, using ANSI escape sequences. By default,
this renderer only highlights most common color groups. Additional colors
can be specified using 'colors' option. This renderer also accepts 'numbers'
option - a boolean value, and 'tabsize' option.
Example :
require_once 'Text/Highlighter/Renderer/Console.php';
$colors = array(
'prepro' => "\033[35m",
'types' => "\033[32m",
);
$options = array(
'numbers' => true,
'tabsize' => 8,
'colors' => $colors,
);
$renderer = new Text_Highlighter_Renderer_Console($options);
ANSI color escape sequences have the following format:
ESC[#;#;....;#m
where ESC is character with ASCII code 27 (033 octal, 0x1B hexadecimal). # is
one of the following:
0 for normal display
1 for bold on
4 underline (mono only)
5 blink on
7 reverse video on
8 nondisplayed (invisible)
30 black foreground
31 red foreground
32 green foreground
33 yellow foreground
34 blue foreground
35 magenta foreground
36 cyan foreground
37 white foreground
40 black background
41 red background
42 green background
43 yellow background
44 blue background
45 magenta background
46 cyan background
47 white background
How to use Text_Highlighter class
=================================
Creating a highlighter object
-----------------------------
To create a highlighter for a certain language, use Text_Highlighter::factory()
static method:
require_once 'Text/Highlighter.php';
$hl = Text_Highlighter::factory('php');
Setting a renderer
------------------
Actual output is produced by a renderer.
require_once 'Text/Highlighter.php';
require_once 'Text/Highlighter/Renderer/Html.php';
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 8,
);
$renderer = new Text_Highlighter_Renderer_HTML($options);
$hl = Text_Highlighter::factory('php');
$hl->setRenderer($renderer);
Note that for BC reasons, it is possible to use highlighter without setting a
renderer. If no renderer is set, HTML renderer will be used by default. In
this case, you should pass options as second parameter to factory method. The
following example works exactly as previous one:
require_once 'Text/Highlighter.php';
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 8,
);
$hl = Text_Highlighter::factory('php', $options);
Getting output
--------------
And finally, do the highlighting and get the output:
require_once 'Text/Highlighter.php';
require_once 'Text/Highlighter/Renderer/Html.php';
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 8,
);
$renderer = new Text_Highlighter_Renderer_HTML($options);
$hl = Text_Highlighter::factory('php');
$hl->setRenderer($renderer);
$html = $hl->highlight(file_get_contents('example.php'));
# vim: set autoindent tabstop=4 shiftwidth=4 softtabstop=4 tw=78: */

View file

@ -1,3 +0,0 @@
~*
vendor
composer.lock

View file

@ -1,6 +0,0 @@
language: php
php:
- "5.5"
- "5.4"
- "5.3"
script: phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View file

@ -1,598 +0,0 @@
<?php
/**
* Class HTML_To_Markdown
*
* A helper class to convert HTML to Markdown.
*
* @version 2.2.1
* @author Nick Cernis <nick@cern.is>
* @link https://github.com/nickcernis/html2markdown/ Latest version on GitHub.
* @link http://twitter.com/nickcernis Nick on twitter.
* @license http://www.opensource.org/licenses/mit-license.php MIT
*/
class HTML_To_Markdown
{
/**
* @var DOMDocument The root of the document tree that holds our HTML.
*/
private $document;
/**
* @var string|boolean The Markdown version of the original HTML, or false if conversion failed
*/
private $output;
/**
* @var array Class-wide options users can override.
*/
private $options = array(
'header_style' => 'setext', // Set to "atx" to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // Set to '__' if you prefer the underlined style
'italic_style' => '*', // Set to '_' if you prefer the underlined style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: "meta style script"
);
/**
* Constructor
*
* Set up a new DOMDocument from the supplied HTML, convert it to Markdown, and store it in $this->$output.
*
* @param string $html The HTML to convert to Markdown.
* @param array $overrides [optional] List of style and error display overrides.
*/
public function __construct($html = null, $overrides = null)
{
if ($overrides)
$this->options = array_merge($this->options, $overrides);
if ($html)
$this->convert($html);
}
/**
* Setter for conversion options
*
* @param $name
* @param $value
*/
public function set_option($name, $value)
{
$this->options[$name] = $value;
}
/**
* Convert
*
* Loads HTML and passes to get_markdown()
*
* @param $html
* @return string The Markdown version of the html
*/
public function convert($html)
{
$html = preg_replace('~>\s+<~', '><', $html); // Strip white space between tags to prevent creation of empty #text nodes
$this->document = new DOMDocument();
if ($this->options['suppress_errors'])
libxml_use_internal_errors(true); // Suppress conversion errors (from http://bit.ly/pCCRSX )
$this->document->loadHTML('<?xml encoding="UTF-8">' . $html); // Hack to load utf-8 HTML (from http://bit.ly/pVDyCt )
$this->document->encoding = 'UTF-8';
if ($this->options['suppress_errors'])
libxml_clear_errors();
return $this->get_markdown($html);
}
/**
* Is Child Of?
*
* Is the node a child of the given parent tag?
*
* @param $parent_name string|array The name of the parent node(s) to search for e.g. 'code' or array('pre', 'code')
* @param $node
* @return bool
*/
private static function is_child_of($parent_name, $node)
{
for ($p = $node->parentNode; $p != false; $p = $p->parentNode) {
if (is_null($p))
return false;
if ( is_array($parent_name) && in_array($p->nodeName, $parent_name) )
return true;
if ($p->nodeName == $parent_name)
return true;
}
return false;
}
/**
* Convert Children
*
* Recursive function to drill into the DOM and convert each node into Markdown from the inside out.
*
* Finds children of each node and convert those to #text nodes containing their Markdown equivalent,
* starting with the innermost element and working up to the outermost element.
*
* @param $node
*/
private function convert_children($node)
{
// Don't convert HTML code inside <code> and <pre> blocks to Markdown - that should stay as HTML
if (self::is_child_of(array('pre', 'code'), $node))
return;
// If the node has children, convert those to Markdown first
if ($node->hasChildNodes()) {
$length = $node->childNodes->length;
for ($i = 0; $i < $length; $i++) {
$child = $node->childNodes->item($i);
$this->convert_children($child);
}
}
// Now that child nodes have been converted, convert the original node
$markdown = $this->convert_to_markdown($node);
// Create a DOM text node containing the Markdown equivalent of the original node
$markdown_node = $this->document->createTextNode($markdown);
// Replace the old $node e.g. "<h3>Title</h3>" with the new $markdown_node e.g. "### Title"
$node->parentNode->replaceChild($markdown_node, $node);
}
/**
* Get Markdown
*
* Sends the body node to convert_children() to change inner nodes to Markdown #text nodes, then saves and
* returns the resulting converted document as a string in Markdown format.
*
* @return string|boolean The converted HTML as Markdown, or false if conversion failed
*/
private function get_markdown()
{
// Work on the entire DOM tree (including head and body)
$input = $this->document->getElementsByTagName("html")->item(0);
if (!$input)
return false;
// Convert all children of this root element. The DOMDocument stored in $this->doc will
// then consist of #text nodes, each containing a Markdown version of the original node
// that it replaced.
$this->convert_children($input);
// Sanitize and return the body contents as a string.
$markdown = $this->document->saveHTML(); // stores the DOMDocument as a string
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8'); // Double decode to cover cases like &amp;nbsp; http://www.php.net/manual/en/function.htmlentities.php#99984
$markdown = preg_replace("/<!DOCTYPE [^>]+>/", "", $markdown); // Strip doctype declaration
$unwanted = array('<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '<?xml encoding="UTF-8">', '&#xD;');
$markdown = str_replace($unwanted, '', $markdown); // Strip unwanted tags
$markdown = trim($markdown, "\n\r\0\x0B");
$this->output = $markdown;
return $markdown;
}
/**
* Convert to Markdown
*
* Converts an individual node into a #text node containing a string of its Markdown equivalent.
*
* Example: An <h3> node with text content of "Title" becomes a text node with content of "### Title"
*
* @param $node
* @return string The converted HTML as Markdown
*/
private function convert_to_markdown($node)
{
$tag = $node->nodeName; // the type of element, e.g. h1
$value = $node->nodeValue; // the value of that element, e.g. The Title
// Strip nodes named in remove_nodes
$tags_to_remove = explode(' ', $this->options['remove_nodes']);
if ( in_array($tag, $tags_to_remove) )
return false;
switch ($tag) {
case "p":
$markdown = (trim($value)) ? rtrim($value) . PHP_EOL . PHP_EOL : '';
break;
case "pre":
$markdown = PHP_EOL . $this->convert_code($node) . PHP_EOL;
break;
case "h1":
case "h2":
$markdown = $this->convert_header($tag, $node);
break;
case "h3":
$markdown = "### " . $value . PHP_EOL . PHP_EOL;
break;
case "h4":
$markdown = "#### " . $value . PHP_EOL . PHP_EOL;
break;
case "h5":
$markdown = "##### " . $value . PHP_EOL . PHP_EOL;
break;
case "h6":
$markdown = "###### " . $value . PHP_EOL . PHP_EOL;
break;
case "em":
case "i":
case "strong":
case "b":
$markdown = $this->convert_emphasis($tag, $value);
break;
case "hr":
$markdown = "- - - - - -" . PHP_EOL . PHP_EOL;
break;
case "br":
$markdown = " " . PHP_EOL;
break;
case "blockquote":
$markdown = $this->convert_blockquote($node);
break;
case "code":
$markdown = $this->convert_code($node);
break;
case "ol":
case "ul":
$markdown = $value . PHP_EOL;
break;
case "li":
$markdown = $this->convert_list($node);
break;
case "img":
$markdown = $this->convert_image($node);
break;
case "a":
$markdown = $this->convert_anchor($node);
break;
case "#text":
$markdown = preg_replace('~\s+~', ' ', $value);
$markdown = preg_replace('~^#~', '\\\\#', $markdown);
break;
case "#comment":
$markdown = '';
break;
case "div":
$markdown = ($this->options['strip_tags']) ? $value . PHP_EOL . PHP_EOL : html_entity_decode($node->C14N());
break;
default:
// If strip_tags is false (the default), preserve tags that don't have Markdown equivalents,
// such as <span> nodes on their own. C14N() canonicalizes the node to a string.
// See: http://www.php.net/manual/en/domnode.c14n.php
$markdown = ($this->options['strip_tags']) ? $value : html_entity_decode($node->C14N());
}
return $markdown;
}
/**
* Convert Header
*
* Converts h1 and h2 headers to Markdown-style headers in setext style,
* matching the number of underscores with the length of the title.
*
* e.g. Header 1 Header Two
* ======== ----------
*
* Returns atx headers instead if $this->options['header_style'] is "atx"
*
* e.g. # Header 1 ## Header Two
*
* @param string $level The header level, including the "h". e.g. h1
* @param string $node The node to convert.
* @return string The Markdown version of the header.
*/
private function convert_header($level, $node)
{
$content = $node->nodeValue;
if (!$this->is_child_of('blockquote', $node) && $this->options['header_style'] == "setext") {
$length = (function_exists('mb_strlen')) ? mb_strlen($content, 'utf-8') : strlen($content);
$underline = ($level == "h1") ? "=" : "-";
$markdown = $content . PHP_EOL . str_repeat($underline, $length) . PHP_EOL . PHP_EOL; // setext style
} else {
$prefix = ($level == "h1") ? "# " : "## ";
$markdown = $prefix . $content . PHP_EOL . PHP_EOL; // atx style
}
return $markdown;
}
/**
* Converts inline styles
* This function is used to render strong and em tags
*
* eg <strong>bold text</strong> becomes **bold text** or __bold text__
*
* @param string $tag
* @param string $value
* @return string
*/
private function convert_emphasis($tag, $value)
{
if ($tag == 'i' || $tag == 'em') {
$markdown = $this->options['italic_style'] . $value . $this->options['italic_style'];
} else {
$markdown = $this->options['bold_style'] . $value . $this->options['bold_style'];
}
return $markdown;
}
/**
* Convert Image
*
* Converts <img /> tags to Markdown.
*
* e.g. <img src="/path/img.jpg" alt="alt text" title="Title" />
* becomes ![alt text](/path/img.jpg "Title")
*
* @param $node
* @return string
*/
private function convert_image($node)
{
$src = $node->getAttribute('src');
$alt = $node->getAttribute('alt');
$title = $node->getAttribute('title');
if ($title != "") {
$markdown = '![' . $alt . '](' . $src . ' "' . $title . '")'; // No newlines added. <img> should be in a block-level element.
} else {
$markdown = '![' . $alt . '](' . $src . ')';
}
return $markdown;
}
/**
* Convert Anchor
*
* Converts <a> tags to Markdown.
*
* e.g. <a href="http://modernnerd.net" title="Title">Modern Nerd</a>
* becomes [Modern Nerd](http://modernnerd.net "Title")
*
* @param $node
* @return string
*/
private function convert_anchor($node)
{
$href = $node->getAttribute('href');
$title = $node->getAttribute('title');
$text = $node->nodeValue;
if ($title != "") {
$markdown = '[' . $text . '](' . $href . ' "' . $title . '")';
} else {
$markdown = '[' . $text . '](' . $href . ')';
}
if (! $href)
$markdown = html_entity_decode($node->C14N());
// Append a space if the node after this one is also an anchor
$next_node_name = $this->get_next_node_name($node);
if ($next_node_name == 'a')
$markdown = $markdown . ' ';
return $markdown;
}
/**
* Convert List
*
* Converts <ul> and <ol> lists to Markdown.
*
* @param $node
* @return string
*/
private function convert_list($node)
{
// If parent is an ol, use numbers, otherwise, use dashes
$list_type = $node->parentNode->nodeName;
$value = $node->nodeValue;
if ($list_type == "ul") {
$markdown = "- " . trim($value) . PHP_EOL;
} else {
$number = $this->get_position($node);
$markdown = $number . ". " . trim($value) . PHP_EOL;
}
return $markdown;
}
/**
* Convert Code
*
* Convert code tags by indenting blocks of code and wrapping single lines in backticks.
*
* @param DOMNode $node
* @return string
*/
private function convert_code($node)
{
// Store the content of the code block in an array, one entry for each line
$markdown = '';
$code_content = html_entity_decode($node->C14N());
$code_content = str_replace(array("<code>", "</code>"), "", $code_content);
$code_content = str_replace(array("<pre>", "</pre>"), "", $code_content);
$lines = preg_split('/\r\n|\r|\n/', $code_content);
$total = count($lines);
// If there's more than one line of code, prepend each line with four spaces and no backticks.
if ($total > 1 || $node->nodeName === 'pre') {
// Remove the first and last line if they're empty
$first_line = trim($lines[0]);
$last_line = trim($lines[$total - 1]);
$first_line = trim($first_line, "&#xD;"); //trim XML style carriage returns too
$last_line = trim($last_line, "&#xD;");
if (empty($first_line))
array_shift($lines);
if (empty($last_line))
array_pop($lines);
$count = 1;
foreach ($lines as $line) {
$line = str_replace('&#xD;', '', $line);
$markdown .= " " . $line;
// Add newlines, except final line of the code
if ($count != $total)
$markdown .= PHP_EOL;
$count++;
}
$markdown .= PHP_EOL;
} else { // There's only one line of code. It's a code span, not a block. Just wrap it with backticks.
$markdown .= "`" . $lines[0] . "`";
}
return $markdown;
}
/**
* Convert blockquote
*
* Prepend blockquotes with > chars.
*
* @param $node
* @return string
*/
private function convert_blockquote($node)
{
// Contents should have already been converted to Markdown by this point,
// so we just need to add ">" symbols to each line.
$markdown = '';
$quote_content = trim($node->nodeValue);
$lines = preg_split('/\r\n|\r|\n/', $quote_content);
$total_lines = count($lines);
foreach ($lines as $i => $line) {
$markdown .= "> " . $line . PHP_EOL;
if ($i + 1 == $total_lines)
$markdown .= PHP_EOL;
}
return $markdown;
}
/**
* Get Position
*
* Returns the numbered position of a node inside its parent
*
* @param $node
* @return int The numbered position of the node, starting at 1.
*/
private function get_position($node)
{
// Get all of the nodes inside the parent
$list_nodes = $node->parentNode->childNodes;
$total_nodes = $list_nodes->length;
$position = 1;
// Loop through all nodes and find the given $node
for ($a = 0; $a < $total_nodes; $a++) {
$current_node = $list_nodes->item($a);
if ($current_node->isSameNode($node))
$position = $a + 1;
}
return $position;
}
/**
* Get Next Node Name
*
* Return the name of the node immediately after the passed one.
*
* @param $node
* @return string|null The node name (e.g. 'h1') or null.
*/
private function get_next_node_name($node)
{
$next_node_name = null;
$current_position = $this->get_position($node);
$next_node = $node->parentNode->childNodes->item($current_position);
if ($next_node)
$next_node_name = $next_node->nodeName;
return $next_node_name;
}
/**
* To String
*
* Magic method to return Markdown output when HTML_To_Markdown instance is treated as a string.
*
* @return string
*/
public function __toString()
{
return $this->output();
}
/**
* Output
*
* Getter for the converted Markdown contents stored in $this->output
*
* @return string
*/
public function output()
{
if (!$this->output) {
return '';
} else {
return $this->output;
}
}
}

View file

@ -1,138 +0,0 @@
HTML To Markdown for PHP
========================
A helper class that converts HTML to [Markdown](http://daringfireball.net/projects/markdown/) for your sanity and convenience.
[![Build Status](https://travis-ci.org/nickcernis/html-to-markdown.png?branch=master)](https://travis-ci.org/nickcernis/html-to-markdown)
**Version**: 2.2.1
**Requires**: PHP 5.3+
**Author**: [@nickcernis](http://twitter.com/nickcernis)
**License**: [MIT](http://www.opensource.org/licenses/mit-license.php)
### Why convert HTML to Markdown?
*"What alchemy is this?"* you mutter. *"I can see why you'd convert [Markdown to HTML](http://michelf.com/projects/php-markdown/),"* you continue, already labouring the question somewhat, *"but why go the other way?"*
Typically you would convert HTML to Markdown if:
1. You have an existing HTML document that needs to be edited by people with good taste.
2. You want to store new content in HTML format but edit it as Markdown.
3. You want to convert HTML email to plain text email.
4. You know a guy who's been converting HTML to Markdown for years, and now he can speak Elvish. You'd quite like to be able to speak Elvish.
5. You just really like Markdown.
### How to use it
Either include HTML_To_Markdown.php directly:
require_once( dirname( __FILE__) . '/HTML_To_Markdown.php' );
Or, require the library in your composer.json:
{
"require": {
"nickcernis/html-to-markdown": "dev-master"
}
}
Then `composer install` and add `require 'vendor/autoload.php';` to the top of your script.
Next, create a new HTML_To_Markdown instance, passing in your valid HTML code:
$html = "<h3>Quick, to the Batpoles!</h3>";
$markdown = new HTML_To_Markdown($html);
The `$markdown` object now contains the Markdown version of your HTML. Use it like a string:
echo $markdown; // ==> ### Quick, to the Batpoles!
Or access the Markdown output directly:
$string = $markdown->output();
The included `demo` directory contains an HTML->Markdown conversion form to try out.
### Conversion options
By default, HTML To Markdown preserves HTML tags without Markdown equivalents, like `<span>` and `<div>`.
To strip HTML tags that don't have a Markdown equivalent while preserving the content inside them, set `strip_tags` to true, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown($html, array('strip_tags' => true)); // $markdown now contains "Turnips!"
Or more explicitly, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('strip_tags', true);
$markdown->convert($html); // $markdown now contains "Turnips!"
Note that only the tags themselves are stripped, not the content they hold.
To strip tags and their content, pass a space-separated list of tags in `remove_nodes`, like this:
$html = '<span>Turnips!</span><div>Monkeys!</div>';
$markdown = new HTML_To_Markdown($html, array('remove_nodes' => 'span div')); // $markdown now contains ""
### Style options
Bold and italic tags are converted using the asterisk syntax by default. Change this to the underlined syntax using the `bold_style` and `italic_style` options.
$html = '<em>Italic</em> and a <strong>bold</strong>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('italic_style', '_');
$markdown->set_option('bold_style', '__');
$markdown->convert($html); // $markdown now contains "_Italic_ and a __bold__"
### Limitations
- Markdown Extra, MultiMarkdown and other variants aren't supported just Markdown.
### Known issues
- Nested lists and lists containing multiple paragraphs aren't converted correctly.
- Lists inside blockquotes aren't converted correctly.
- Any reported [open issues here](https://github.com/nickcernis/html-to-markdown/issues?state=open).
[Report your issue or request a feature here.](https://github.com/nickcernis/html2markdown/issues/new) Issues with patches or failing tests are especially welcome.
### Style notes
- Setext (underlined) headers are the default for H1 and H2. If you prefer the ATX style for H1 and H2 (# Header 1 and ## Header 2), set `header_style` to 'atx' in the options array when you instantiate the object:
`$markdown = new HTML_To_Markdown( $html, array('header_style'=>'atx') );`
Headers of H3 priority and lower always use atx style.
- Links and images are referenced inline. Footnote references (where image src and anchor href attributes are listed in the footnotes) are not used.
- Blockquotes aren't line wrapped it makes the converted Markdown easier to edit.
### Dependencies
HTML To Markdown requires PHP's [xml](http://www.php.net/manual/en/xml.installation.php), [lib-xml](http://www.php.net/manual/en/libxml.installation.php), and [dom](http://www.php.net/manual/en/dom.installation.php) extensions, all of which are enabled by default on most distributions.
Errors such as "Fatal error: Class 'DOMDocument' not found" on distributions such as CentOS that disable PHP's xml extension can be resolved by installing php-xml.
### Architecture notes
HTML To Markdown is a single file that uses native DOM manipulation libraries (DOMDocument), not regex voodoo, to convert code.
### Contributors
Many thanks to all [contributors](https://github.com/nickcernis/html2markdown/graphs/contributors) so far. Further improvements and feature suggestions are very welcome.
### How it works
HTML To Markdown creates a DOMDocument from the supplied HTML, walks through the tree, and converts each node to a text node containing the equivalent markdown, starting from the most deeply nested node and working inwards towards the root node.
### To-do
- Support for nested lists and lists inside blockquotes.
- Offer an option to preserve tags as HTML if they contain attributes that can't be represented with Markdown (e.g. `style`).
### Trying to convert Markdown to HTML?
Use [PHP Markdown](http://michelf.com/projects/php-markdown/) from Michel Fortin. No guarantees about the Elvish, though.

View file

@ -1,4 +0,0 @@
test:
override:
- phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View file

@ -1,25 +0,0 @@
{
"name": "nickcernis/html-to-markdown",
"type": "library",
"description": "An HTML-to-markdown conversion helper for PHP",
"keywords": ["markdown", "html"],
"homepage": "https://github.com/nickcernis/html-to-markdown",
"license": "MIT",
"authors": [
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net"
}
],
"autoload": {
"classmap": [ "HTML_To_Markdown.php" ]
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"php": ">=5.3.3",
"phpunit/phpunit": "4.*"
}
}

View file

@ -1,17 +1,33 @@
<?php <?php
require_once('include/Photo.php'); /**
* @file mod/wall_upload.php
* @brief Module for uploading a picture to the profile wall
*
* By default the picture will be stored in the photo album with the name Wall Photos.
* You can specify a different album by adding an optional query string "album="
* to the url
*/
use \Friendica\Core\Config;
require_once 'include/Photo.php';
function wall_upload_post(App $a, $desktopmode = true) { function wall_upload_post(App $a, $desktopmode = true) {
logger("wall upload: starting new upload", LOGGER_DEBUG); logger("wall upload: starting new upload", LOGGER_DEBUG);
$r_json = (x($_GET,'response') && $_GET['response']=='json'); $r_json = (x($_GET, 'response') && $_GET['response'] == 'json');
$album = (x($_GET, 'album') ? notags(trim($_GET['album'])) : '');
if($a->argc > 1) { if ($a->argc > 1) {
if(! x($_FILES,'media')) { if (! x($_FILES, 'media')) {
$nick = $a->argv[1]; $nick = $a->argv[1];
$r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", $r = q("SELECT `user`.*, `contact`.`id` FROM `user`
INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0
AND `contact`.`self` = 1 LIMIT 1",
dbesc($nick) dbesc($nick)
); );
@ -24,7 +40,10 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
} else { } else {
$user_info = api_get_user($a); $user_info = api_get_user($a);
$r = q("SELECT `user`.*, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1", $r = q("SELECT `user`.*, `contact`.`id` FROM `user`
INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0
AND `contact`.`self` = 1 LIMIT 1",
dbesc($user_info['screen_name']) dbesc($user_info['screen_name'])
); );
} }
@ -36,6 +55,9 @@ function wall_upload_post(App $a, $desktopmode = true) {
return; return;
} }
/*
* Setup permissions structures
*/
$can_post = false; $can_post = false;
$visitor = 0; $visitor = 0;
@ -44,22 +66,24 @@ function wall_upload_post(App $a, $desktopmode = true) {
$page_owner_nick = $r[0]['nickname']; $page_owner_nick = $r[0]['nickname'];
$community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false); $community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
if((local_user()) && (local_user() == $page_owner_uid)) if ((local_user()) && (local_user() == $page_owner_uid)) {
$can_post = true; $can_post = true;
else { } else {
if($community_page && remote_user()) { if ($community_page && remote_user()) {
$contact_id = 0; $contact_id = 0;
if(is_array($_SESSION['remote'])) { if (is_array($_SESSION['remote'])) {
foreach($_SESSION['remote'] as $v) { foreach ($_SESSION['remote'] as $v) {
if($v['uid'] == $page_owner_uid) { if ($v['uid'] == $page_owner_uid) {
$contact_id = $v['cid']; $contact_id = $v['cid'];
break; break;
} }
} }
} }
if($contact_id) {
$r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", if ($contact_id) {
$r = q("SELECT `uid` FROM `contact`
WHERE `blocked` = 0 AND `pending` = 0
AND `id` = %d AND `uid` = %d LIMIT 1",
intval($contact_id), intval($contact_id),
intval($page_owner_uid) intval($page_owner_uid)
); );
@ -72,16 +96,16 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
if(! $can_post) { if (! $can_post) {
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>t('Permission denied.'))); echo json_encode(array('error'=>t('Permission denied.')));
killme(); killme();
} }
notice( t('Permission denied.') . EOL ); notice(t('Permission denied.') . EOL);
killme(); killme();
} }
if(! x($_FILES,'userfile') && ! x($_FILES,'media')){ if (! x($_FILES, 'userfile') && ! x($_FILES, 'media')) {
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>t('Invalid request.'))); echo json_encode(array('error'=>t('Invalid request.')));
} }
@ -89,33 +113,37 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
$src = ""; $src = "";
if(x($_FILES,'userfile')) { if (x($_FILES, 'userfile')) {
$src = $_FILES['userfile']['tmp_name']; $src = $_FILES['userfile']['tmp_name'];
$filename = basename($_FILES['userfile']['name']); $filename = basename($_FILES['userfile']['name']);
$filesize = intval($_FILES['userfile']['size']); $filesize = intval($_FILES['userfile']['size']);
$filetype = $_FILES['userfile']['type']; $filetype = $_FILES['userfile']['type'];
}
elseif(x($_FILES,'media')) { } elseif (x($_FILES, 'media')) {
if (is_array($_FILES['media']['tmp_name'])) if (is_array($_FILES['media']['tmp_name'])) {
$src = $_FILES['media']['tmp_name'][0]; $src = $_FILES['media']['tmp_name'][0];
else } else {
$src = $_FILES['media']['tmp_name']; $src = $_FILES['media']['tmp_name'];
}
if (is_array($_FILES['media']['name'])) if (is_array($_FILES['media']['name'])) {
$filename = basename($_FILES['media']['name'][0]); $filename = basename($_FILES['media']['name'][0]);
else } else {
$filename = basename($_FILES['media']['name']); $filename = basename($_FILES['media']['name']);
}
if (is_array($_FILES['media']['size'])) if (is_array($_FILES['media']['size'])) {
$filesize = intval($_FILES['media']['size'][0]); $filesize = intval($_FILES['media']['size'][0]);
else } else {
$filesize = intval($_FILES['media']['size']); $filesize = intval($_FILES['media']['size']);
}
if (is_array($_FILES['media']['type'])) if (is_array($_FILES['media']['type'])) {
$filetype = $_FILES['media']['type'][0]; $filetype = $_FILES['media']['type'][0];
else } else {
$filetype = $_FILES['media']['type']; $filetype = $_FILES['media']['type'];
} }
}
if ($src=="") { if ($src=="") {
if ($r_json) { if ($r_json) {
@ -127,28 +155,30 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
// This is a special treatment for picture upload from Twidere // This is a special treatment for picture upload from Twidere
if (($filename == "octet-stream") AND ($filetype != "")) { if (($filename == "octet-stream") && ($filetype != "")) {
$filename = $filetype; $filename = $filetype;
$filetype = ""; $filetype = "";
} }
if ($filetype=="") if ($filetype=="") {
$filetype=guess_image_type($filename); $filetype=guess_image_type($filename);
}
// If there is a temp name, then do a manual check // If there is a temp name, then do a manual check
// This is more reliable than the provided value // This is more reliable than the provided value
$imagedata = getimagesize($src); $imagedata = getimagesize($src);
if ($imagedata) if ($imagedata) {
$filetype = $imagedata['mime']; $filetype = $imagedata['mime'];
}
logger("File upload src: ".$src." - filename: ".$filename. logger("File upload src: " . $src . " - filename: " . $filename .
" - size: ".$filesize." - type: ".$filetype, LOGGER_DEBUG); " - size: " . $filesize . " - type: " . $filetype, LOGGER_DEBUG);
$maximagesize = get_config('system','maximagesize'); $maximagesize = Config::get('system', 'maximagesize');
if(($maximagesize) && ($filesize > $maximagesize)) { if (($maximagesize) && ($filesize > $maximagesize)) {
$msg = sprintf( t('Image exceeds size limit of %s'), formatBytes($maximagesize)); $msg = sprintf(t('Image exceeds size limit of %s'), formatBytes($maximagesize));
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>$msg)); echo json_encode(array('error'=>$msg));
} else { } else {
@ -159,10 +189,12 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
$limit = service_class_fetch($page_owner_uid,'photo_upload_limit'); $limit = service_class_fetch($page_owner_uid, 'photo_upload_limit');
if ($limit) { if ($limit) {
$r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", $r = q("SELECT SUM(OCTET_LENGTH(`data`)) AS `total` FROM `photo`
WHERE `uid` = %d AND `scale` = 0
AND `album` != 'Contact Photos' ",
intval($page_owner_uid) intval($page_owner_uid)
); );
$size = $r[0]['total']; $size = $r[0]['total'];
@ -182,7 +214,7 @@ function wall_upload_post(App $a, $desktopmode = true) {
$imagedata = @file_get_contents($src); $imagedata = @file_get_contents($src);
$ph = new Photo($imagedata, $filetype); $ph = new Photo($imagedata, $filetype);
if(! $ph->is_valid()) { if (! $ph->is_valid()) {
$msg = t('Unable to process image.'); $msg = t('Unable to process image.');
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>$msg)); echo json_encode(array('error'=>$msg));
@ -196,12 +228,13 @@ function wall_upload_post(App $a, $desktopmode = true) {
$ph->orient($src); $ph->orient($src);
@unlink($src); @unlink($src);
$max_length = get_config('system','max_image_length'); $max_length = Config::get('system', 'max_image_length');
if(! $max_length) if (! $max_length) {
$max_length = MAX_IMAGE_LENGTH; $max_length = MAX_IMAGE_LENGTH;
if($max_length > 0) { }
if ($max_length > 0) {
$ph->scaleImage($max_length); $ph->scaleImage($max_length);
logger("File upload: Scaling picture to new size ".$max_length, LOGGER_DEBUG); logger("File upload: Scaling picture to new size " . $max_length, LOGGER_DEBUG);
} }
$width = $ph->getWidth(); $width = $ph->getWidth();
@ -211,11 +244,16 @@ function wall_upload_post(App $a, $desktopmode = true) {
$smallest = 0; $smallest = 0;
// If we don't have an album name use the Wall Photos album
if (! strlen($album)) {
$album = t('Wall Photos');
}
$defperm = '<' . $default_cid . '>'; $defperm = '<' . $default_cid . '>';
$r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 0, 0, $defperm);
if(! $r) { if (! $r) {
$msg = t('Image upload failed.'); $msg = t('Image upload failed.');
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>$msg)); echo json_encode(array('error'=>$msg));
@ -225,26 +263,31 @@ function wall_upload_post(App $a, $desktopmode = true) {
killme(); killme();
} }
if($width > 640 || $height > 640) { if ($width > 640 || $height > 640) {
$ph->scaleImage(640); $ph->scaleImage(640);
$r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 1, 0, $defperm);
if($r) if ($r) {
$smallest = 1; $smallest = 1;
} }
}
if($width > 320 || $height > 320) { if ($width > 320 || $height > 320) {
$ph->scaleImage(320); $ph->scaleImage(320);
$r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 2, 0, $defperm);
if($r AND ($smallest == 0)) if ($r && ($smallest == 0)) {
$smallest = 2; $smallest = 2;
} }
}
$basename = basename($filename); $basename = basename($filename);
if (!$desktopmode) { if (!$desktopmode) {
$r = q("SELECT `id`, `datasize`, `width`, `height`, `type` FROM `photo`
$r = q("SELECT `id`, `datasize`, `width`, `height`, `type` FROM `photo` WHERE `resource-id` = '%s' ORDER BY `width` DESC LIMIT 1", $hash); WHERE `resource-id` = '%s'
if (!$r){ ORDER BY `width` DESC LIMIT 1",
$hash
);
if (!$r) {
if ($r_json) { if ($r_json) {
echo json_encode(array('error'=>'')); echo json_encode(array('error'=>''));
killme(); killme();
@ -258,9 +301,9 @@ function wall_upload_post(App $a, $desktopmode = true) {
$picture["width"] = $r[0]["width"]; $picture["width"] = $r[0]["width"];
$picture["height"] = $r[0]["height"]; $picture["height"] = $r[0]["height"];
$picture["type"] = $r[0]["type"]; $picture["type"] = $r[0]["type"];
$picture["albumpage"] = App::get_baseurl().'/photos/'.$page_owner_nick.'/image/'.$hash; $picture["albumpage"] = App::get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash;
$picture["picture"] = App::get_baseurl()."/photo/{$hash}-0.".$ph->getExt(); $picture["picture"] = App::get_baseurl() . "/photo/{$hash}-0." . $ph->getExt();
$picture["preview"] = App::get_baseurl()."/photo/{$hash}-{$smallest}.".$ph->getExt(); $picture["preview"] = App::get_baseurl() . "/photo/{$hash}-{$smallest}." . $ph->getExt();
if ($r_json) { if ($r_json) {
echo json_encode(array('picture'=>$picture)); echo json_encode(array('picture'=>$picture));
@ -276,7 +319,6 @@ function wall_upload_post(App $a, $desktopmode = true) {
} }
/* mod Waitman Gobble NO WARRANTY */ /* mod Waitman Gobble NO WARRANTY */
// if we get the signal then return the image url info in BBCODE // if we get the signal then return the image url info in BBCODE
if ($_REQUEST['hush']!='yeah') { if ($_REQUEST['hush']!='yeah') {
echo "\n\n" . '[url=' . App::get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . App::get_baseurl() . "/photo/{$hash}-{$smallest}.".$ph->getExt()."[/img][/url]\n\n"; echo "\n\n" . '[url=' . App::get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . App::get_baseurl() . "/photo/{$hash}-{$smallest}.".$ph->getExt()."[/img][/url]\n\n";

15
vendor/bin/composer-php vendored Normal file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env sh
SRC_DIR=`pwd`
BIN_DIR=`dirname $0`
VENDOR_DIR=$BIN_DIR/"../"
DIRS=""
for vendor in $VENDOR_DIR/*; do
if [ -d "$vendor" ]; then
for package in $vendor/*; do
if [ -d "$package" ]; then
DIRS="${DIRS}:${package}"
fi
done
fi
done
php -d include_path=".$DIRS" $@

11
vendor/bin/composer-php.bat vendored Normal file
View file

@ -0,0 +1,11 @@
@echo off
setlocal enabledelayedexpansion
set BIN_DIR=%~dp0
set VENDOR_DIR=%BIN_DIR%\../
set DIRS=.
FOR /D %%V IN (%VENDOR_DIR%\*) DO (
FOR /D %%P IN (%%V\*) DO (
set DIRS=!DIRS!;%%~fP
)
)
php.exe -d include_path=!DIRS! %*

17
vendor/bin/generate vendored Normal file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env sh
dir=$(d=${0%[/\\]*}; cd "$d"; cd "../pear-pear.php.net/Text_Highlighter/bin" && pwd)
# See if we are running in Cygwin by checking for cygpath program
if command -v 'cygpath' >/dev/null 2>&1; then
# Cygwin paths start with /cygdrive/ which will break windows PHP,
# so we need to translate the dir path to windows format. However
# we could be using cygwin PHP which does not require this, so we
# test if the path to PHP starts with /cygdrive/ rather than /usr/bin
if [[ $(which php) == /cygdrive/* ]]; then
dir=$(cygpath -m "$dir");
fi
fi
dir=$(echo $dir | sed 's/ /\ /g')
"${dir}/generate" "$@"

7
vendor/bin/generate.bat vendored Normal file
View file

@ -0,0 +1,7 @@
@echo off
pushd .
cd %~dp0
cd "../pear-pear.php.net/Text_Highlighter/bin"
set BIN_TARGET=%CD%\generate
popd
composer-php "%BIN_TARGET%" %*

17
vendor/bin/html-to-markdown vendored Normal file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env sh
dir=$(d=${0%[/\\]*}; cd "$d"; cd "../league/html-to-markdown/bin" && pwd)
# See if we are running in Cygwin by checking for cygpath program
if command -v 'cygpath' >/dev/null 2>&1; then
# Cygwin paths start with /cygdrive/ which will break windows PHP,
# so we need to translate the dir path to windows format. However
# we could be using cygwin PHP which does not require this, so we
# test if the path to PHP starts with /cygdrive/ rather than /usr/bin
if [[ $(which php) == /cygdrive/* ]]; then
dir=$(cygpath -m "$dir");
fi
fi
dir=$(echo $dir | sed 's/ /\ /g')
"${dir}/html-to-markdown" "$@"

4
vendor/bin/html-to-markdown.bat vendored Normal file
View file

@ -0,0 +1,4 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/../league/html-to-markdown/bin/html-to-markdown
php "%BIN_TARGET%" %*

7
vendor/bin/pear.bat vendored Normal file
View file

@ -0,0 +1,7 @@
@echo off
pushd .
cd %~dp0
cd "../pear-pear.php.net/PEAR/bin"
set BIN_TARGET=%CD%\pear.bat
popd
call "%BIN_TARGET%" %*

7
vendor/bin/peardev.bat vendored Normal file
View file

@ -0,0 +1,7 @@
@echo off
pushd .
cd %~dp0
cd "../pear-pear.php.net/PEAR/bin"
set BIN_TARGET=%CD%\peardev.bat
popd
call "%BIN_TARGET%" %*

7
vendor/bin/pecl.bat vendored Normal file
View file

@ -0,0 +1,7 @@
@echo off
pushd .
cd %~dp0
cd "../pear-pear.php.net/PEAR/bin"
set BIN_TARGET=%CD%\pecl.bat
popd
call "%BIN_TARGET%" %*

View file

@ -6,6 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Archive_Tar' => $vendorDir . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php',
'Console_Getopt' => $vendorDir . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php',
'Detection\\MobileDetect' => $vendorDir . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php', 'Detection\\MobileDetect' => $vendorDir . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php',
'Friendica\\Core\\Config' => $baseDir . '/src/Core/Config.php', 'Friendica\\Core\\Config' => $baseDir . '/src/Core/Config.php',
'Friendica\\Core\\PConfig' => $baseDir . '/src/Core/PConfig.php', 'Friendica\\Core\\PConfig' => $baseDir . '/src/Core/PConfig.php',
@ -239,5 +241,136 @@ return array(
'HTMLPurifier_VarParser_Flexible' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php', 'HTMLPurifier_VarParser_Flexible' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php',
'HTMLPurifier_VarParser_Native' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php', 'HTMLPurifier_VarParser_Native' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php',
'HTMLPurifier_Zipper' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php', 'HTMLPurifier_Zipper' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php',
'League\\HTMLToMarkdown\\Configuration' => $vendorDir . '/league/html-to-markdown/src/Configuration.php',
'League\\HTMLToMarkdown\\ConfigurationAwareInterface' => $vendorDir . '/league/html-to-markdown/src/ConfigurationAwareInterface.php',
'League\\HTMLToMarkdown\\Converter\\BlockquoteConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/BlockquoteConverter.php',
'League\\HTMLToMarkdown\\Converter\\CodeConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/CodeConverter.php',
'League\\HTMLToMarkdown\\Converter\\CommentConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/CommentConverter.php',
'League\\HTMLToMarkdown\\Converter\\ConverterInterface' => $vendorDir . '/league/html-to-markdown/src/Converter/ConverterInterface.php',
'League\\HTMLToMarkdown\\Converter\\DefaultConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/DefaultConverter.php',
'League\\HTMLToMarkdown\\Converter\\DivConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/DivConverter.php',
'League\\HTMLToMarkdown\\Converter\\EmphasisConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/EmphasisConverter.php',
'League\\HTMLToMarkdown\\Converter\\HardBreakConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/HardBreakConverter.php',
'League\\HTMLToMarkdown\\Converter\\HeaderConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/HeaderConverter.php',
'League\\HTMLToMarkdown\\Converter\\HorizontalRuleConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php',
'League\\HTMLToMarkdown\\Converter\\ImageConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ImageConverter.php',
'League\\HTMLToMarkdown\\Converter\\LinkConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/LinkConverter.php',
'League\\HTMLToMarkdown\\Converter\\ListBlockConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ListBlockConverter.php',
'League\\HTMLToMarkdown\\Converter\\ListItemConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ListItemConverter.php',
'League\\HTMLToMarkdown\\Converter\\ParagraphConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ParagraphConverter.php',
'League\\HTMLToMarkdown\\Converter\\PreformattedConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/PreformattedConverter.php',
'League\\HTMLToMarkdown\\Converter\\TextConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/TextConverter.php',
'League\\HTMLToMarkdown\\Element' => $vendorDir . '/league/html-to-markdown/src/Element.php',
'League\\HTMLToMarkdown\\ElementInterface' => $vendorDir . '/league/html-to-markdown/src/ElementInterface.php',
'League\\HTMLToMarkdown\\Environment' => $vendorDir . '/league/html-to-markdown/src/Environment.php',
'League\\HTMLToMarkdown\\HtmlConverter' => $vendorDir . '/league/html-to-markdown/src/HtmlConverter.php',
'Mobile_Detect' => $vendorDir . '/mobiledetect/mobiledetectlib/Mobile_Detect.php', 'Mobile_Detect' => $vendorDir . '/mobiledetect/mobiledetectlib/Mobile_Detect.php',
'OS_Guess' => $vendorDir . '/pear-pear.php.net/PEAR/OS/Guess.php',
'PEAR' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR.php',
'PEAR_Builder' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Builder.php',
'PEAR_ChannelFile' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ChannelFile.php',
'PEAR_ChannelFile_Parser' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php',
'PEAR_Command' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command.php',
'PEAR_Command_Auth' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Auth.php',
'PEAR_Command_Build' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Build.php',
'PEAR_Command_Channels' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Channels.php',
'PEAR_Command_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Common.php',
'PEAR_Command_Config' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Config.php',
'PEAR_Command_Install' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Install.php',
'PEAR_Command_Mirror' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php',
'PEAR_Command_Package' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Package.php',
'PEAR_Command_Pickle' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php',
'PEAR_Command_Registry' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Registry.php',
'PEAR_Command_Remote' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Remote.php',
'PEAR_Command_Test' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Command/Test.php',
'PEAR_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Common.php',
'PEAR_Config' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Config.php',
'PEAR_Dependency2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Dependency2.php',
'PEAR_DependencyDB' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/DependencyDB.php',
'PEAR_Downloader' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Downloader.php',
'PEAR_Downloader_Package' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php',
'PEAR_Error' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR.php',
'PEAR_ErrorStack' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/ErrorStack.php',
'PEAR_Exception' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Exception.php',
'PEAR_Frontend' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Frontend.php',
'PEAR_Frontend_CLI' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php',
'PEAR_Installer' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer.php',
'PEAR_Installer_Role' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role.php',
'PEAR_Installer_Role_Cfg' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php',
'PEAR_Installer_Role_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php',
'PEAR_Installer_Role_Data' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php',
'PEAR_Installer_Role_Doc' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php',
'PEAR_Installer_Role_Ext' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php',
'PEAR_Installer_Role_Man' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php',
'PEAR_Installer_Role_Php' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php',
'PEAR_Installer_Role_Script' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php',
'PEAR_Installer_Role_Src' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php',
'PEAR_Installer_Role_Test' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php',
'PEAR_Installer_Role_Www' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php',
'PEAR_PackageFile' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile.php',
'PEAR_PackageFile_Generator_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v1.php',
'PEAR_PackageFile_Generator_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php',
'PEAR_PackageFile_Parser_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php',
'PEAR_PackageFile_Parser_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php',
'PEAR_PackageFile_v1' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php',
'PEAR_PackageFile_v2' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php',
'PEAR_PackageFile_v2_Validator' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php',
'PEAR_PackageFile_v2_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php',
'PEAR_Packager' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Packager.php',
'PEAR_Proxy' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Proxy.php',
'PEAR_REST' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST.php',
'PEAR_REST_10' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/10.php',
'PEAR_REST_11' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/11.php',
'PEAR_REST_13' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/REST/13.php',
'PEAR_Registry' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Registry.php',
'PEAR_RunTest' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/RunTest.php',
'PEAR_Task_Common' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Common.php',
'PEAR_Task_Postinstallscript' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php',
'PEAR_Task_Postinstallscript_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php',
'PEAR_Task_Replace' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Replace.php',
'PEAR_Task_Replace_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php',
'PEAR_Task_Unixeol' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php',
'PEAR_Task_Unixeol_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php',
'PEAR_Task_Windowseol' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php',
'PEAR_Task_Windowseol_rw' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php',
'PEAR_Validate' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Validate.php',
'PEAR_Validator_PECL' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php',
'PEAR_XMLParser' => $vendorDir . '/pear-pear.php.net/PEAR/PEAR/XMLParser.php',
'Structures_Graph' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph.php',
'Structures_Graph_Manipulator_AcyclicTest' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php',
'Structures_Graph_Manipulator_TopologicalSorter' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php',
'Structures_Graph_Node' => $vendorDir . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php',
'System' => $vendorDir . '/pear-pear.php.net/PEAR/System.php',
'Text_Highlighter' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter.php',
'Text_Highlighter_ABAP' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/ABAP.php',
'Text_Highlighter_AVRC' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/AVRC.php',
'Text_Highlighter_CPP' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/CPP.php',
'Text_Highlighter_CSS' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/CSS.php',
'Text_Highlighter_DIFF' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/DIFF.php',
'Text_Highlighter_DTD' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/DTD.php',
'Text_Highlighter_Generator' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Generator.php',
'Text_Highlighter_HTML' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/HTML.php',
'Text_Highlighter_JAVA' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/JAVA.php',
'Text_Highlighter_JAVASCRIPT' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/JAVASCRIPT.php',
'Text_Highlighter_MYSQL' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/MYSQL.php',
'Text_Highlighter_PERL' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PERL.php',
'Text_Highlighter_PHP' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PHP.php',
'Text_Highlighter_PYTHON' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PYTHON.php',
'Text_Highlighter_RUBY' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/RUBY.php',
'Text_Highlighter_Renderer' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer.php',
'Text_Highlighter_Renderer_Array' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Array.php',
'Text_Highlighter_Renderer_BB' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/BB.php',
'Text_Highlighter_Renderer_Console' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Console.php',
'Text_Highlighter_Renderer_Html' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Html.php',
'Text_Highlighter_Renderer_HtmlTags' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/HtmlTags.php',
'Text_Highlighter_Renderer_JSON' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/JSON.php',
'Text_Highlighter_Renderer_XML' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/XML.php',
'Text_Highlighter_SH' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/SH.php',
'Text_Highlighter_SQL' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/SQL.php',
'Text_Highlighter_VBSCRIPT' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/VBSCRIPT.php',
'Text_Highlighter_XML' => $vendorDir . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/XML.php',
'XML_Parser' => $vendorDir . '/pear-pear.php.net/XML_Parser/XML/Parser.php',
'XML_Parser_Error' => $vendorDir . '/pear-pear.php.net/XML_Parser/XML/Parser.php',
'XML_Parser_Simple' => $vendorDir . '/pear-pear.php.net/XML_Parser/XML/Parser/Simple.php',
'XML_Util' => $vendorDir . '/pear-pear.php.net/XML_Util/XML/Util.php',
); );

View file

@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'League\\HTMLToMarkdown\\' => array($vendorDir . '/league/html-to-markdown/src'),
'Friendica\\' => array($baseDir . '/src'), 'Friendica\\' => array($baseDir . '/src'),
); );

View file

@ -23,6 +23,10 @@ class ComposerAutoloaderInitFriendica
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitFriendica', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInitFriendica', 'loadClassLoader'));
$includePaths = require __DIR__ . '/include_paths.php';
array_push($includePaths, get_include_path());
set_include_path(implode(PATH_SEPARATOR, $includePaths));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) { if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php'; require_once __DIR__ . '/autoload_static.php';

View file

@ -11,6 +11,10 @@ class ComposerStaticInitFriendica
); );
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
'L' =>
array (
'League\\HTMLToMarkdown\\' => 22,
),
'F' => 'F' =>
array ( array (
'Friendica\\' => 10, 'Friendica\\' => 10,
@ -18,6 +22,10 @@ class ComposerStaticInitFriendica
); );
public static $prefixDirsPsr4 = array ( public static $prefixDirsPsr4 = array (
'League\\HTMLToMarkdown\\' =>
array (
0 => __DIR__ . '/..' . '/league/html-to-markdown/src',
),
'Friendica\\' => 'Friendica\\' =>
array ( array (
0 => __DIR__ . '/../..' . '/src', 0 => __DIR__ . '/../..' . '/src',
@ -42,6 +50,8 @@ class ComposerStaticInitFriendica
); );
public static $classMap = array ( public static $classMap = array (
'Archive_Tar' => __DIR__ . '/..' . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php',
'Console_Getopt' => __DIR__ . '/..' . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php',
'Detection\\MobileDetect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php', 'Detection\\MobileDetect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php',
'Friendica\\Core\\Config' => __DIR__ . '/../..' . '/src/Core/Config.php', 'Friendica\\Core\\Config' => __DIR__ . '/../..' . '/src/Core/Config.php',
'Friendica\\Core\\PConfig' => __DIR__ . '/../..' . '/src/Core/PConfig.php', 'Friendica\\Core\\PConfig' => __DIR__ . '/../..' . '/src/Core/PConfig.php',
@ -275,7 +285,138 @@ class ComposerStaticInitFriendica
'HTMLPurifier_VarParser_Flexible' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php', 'HTMLPurifier_VarParser_Flexible' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php',
'HTMLPurifier_VarParser_Native' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php', 'HTMLPurifier_VarParser_Native' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php',
'HTMLPurifier_Zipper' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php', 'HTMLPurifier_Zipper' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php',
'League\\HTMLToMarkdown\\Configuration' => __DIR__ . '/..' . '/league/html-to-markdown/src/Configuration.php',
'League\\HTMLToMarkdown\\ConfigurationAwareInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/ConfigurationAwareInterface.php',
'League\\HTMLToMarkdown\\Converter\\BlockquoteConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/BlockquoteConverter.php',
'League\\HTMLToMarkdown\\Converter\\CodeConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/CodeConverter.php',
'League\\HTMLToMarkdown\\Converter\\CommentConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/CommentConverter.php',
'League\\HTMLToMarkdown\\Converter\\ConverterInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ConverterInterface.php',
'League\\HTMLToMarkdown\\Converter\\DefaultConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/DefaultConverter.php',
'League\\HTMLToMarkdown\\Converter\\DivConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/DivConverter.php',
'League\\HTMLToMarkdown\\Converter\\EmphasisConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/EmphasisConverter.php',
'League\\HTMLToMarkdown\\Converter\\HardBreakConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/HardBreakConverter.php',
'League\\HTMLToMarkdown\\Converter\\HeaderConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/HeaderConverter.php',
'League\\HTMLToMarkdown\\Converter\\HorizontalRuleConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php',
'League\\HTMLToMarkdown\\Converter\\ImageConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ImageConverter.php',
'League\\HTMLToMarkdown\\Converter\\LinkConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/LinkConverter.php',
'League\\HTMLToMarkdown\\Converter\\ListBlockConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ListBlockConverter.php',
'League\\HTMLToMarkdown\\Converter\\ListItemConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ListItemConverter.php',
'League\\HTMLToMarkdown\\Converter\\ParagraphConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ParagraphConverter.php',
'League\\HTMLToMarkdown\\Converter\\PreformattedConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/PreformattedConverter.php',
'League\\HTMLToMarkdown\\Converter\\TextConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/TextConverter.php',
'League\\HTMLToMarkdown\\Element' => __DIR__ . '/..' . '/league/html-to-markdown/src/Element.php',
'League\\HTMLToMarkdown\\ElementInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/ElementInterface.php',
'League\\HTMLToMarkdown\\Environment' => __DIR__ . '/..' . '/league/html-to-markdown/src/Environment.php',
'League\\HTMLToMarkdown\\HtmlConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/HtmlConverter.php',
'Mobile_Detect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/Mobile_Detect.php', 'Mobile_Detect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/Mobile_Detect.php',
'OS_Guess' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/OS/Guess.php',
'PEAR' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR.php',
'PEAR_Builder' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Builder.php',
'PEAR_ChannelFile' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ChannelFile.php',
'PEAR_ChannelFile_Parser' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ChannelFile/Parser.php',
'PEAR_Command' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command.php',
'PEAR_Command_Auth' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Auth.php',
'PEAR_Command_Build' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Build.php',
'PEAR_Command_Channels' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Channels.php',
'PEAR_Command_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Common.php',
'PEAR_Command_Config' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Config.php',
'PEAR_Command_Install' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Install.php',
'PEAR_Command_Mirror' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php',
'PEAR_Command_Package' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Package.php',
'PEAR_Command_Pickle' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php',
'PEAR_Command_Registry' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Registry.php',
'PEAR_Command_Remote' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Remote.php',
'PEAR_Command_Test' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Command/Test.php',
'PEAR_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Common.php',
'PEAR_Config' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Config.php',
'PEAR_Dependency2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Dependency2.php',
'PEAR_DependencyDB' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/DependencyDB.php',
'PEAR_Downloader' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Downloader.php',
'PEAR_Downloader_Package' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php',
'PEAR_Error' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR.php',
'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/ErrorStack.php',
'PEAR_Exception' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Exception.php',
'PEAR_Frontend' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Frontend.php',
'PEAR_Frontend_CLI' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Frontend/CLI.php',
'PEAR_Installer' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer.php',
'PEAR_Installer_Role' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role.php',
'PEAR_Installer_Role_Cfg' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Cfg.php',
'PEAR_Installer_Role_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Common.php',
'PEAR_Installer_Role_Data' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Data.php',
'PEAR_Installer_Role_Doc' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Doc.php',
'PEAR_Installer_Role_Ext' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Ext.php',
'PEAR_Installer_Role_Man' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Man.php',
'PEAR_Installer_Role_Php' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Php.php',
'PEAR_Installer_Role_Script' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Script.php',
'PEAR_Installer_Role_Src' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Src.php',
'PEAR_Installer_Role_Test' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Test.php',
'PEAR_Installer_Role_Www' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Installer/Role/Www.php',
'PEAR_PackageFile' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile.php',
'PEAR_PackageFile_Generator_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v1.php',
'PEAR_PackageFile_Generator_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Generator/v2.php',
'PEAR_PackageFile_Parser_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v1.php',
'PEAR_PackageFile_Parser_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/Parser/v2.php',
'PEAR_PackageFile_v1' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v1.php',
'PEAR_PackageFile_v2' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2.php',
'PEAR_PackageFile_v2_Validator' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/Validator.php',
'PEAR_PackageFile_v2_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/PackageFile/v2/rw.php',
'PEAR_Packager' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Packager.php',
'PEAR_Proxy' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Proxy.php',
'PEAR_REST' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST.php',
'PEAR_REST_10' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/10.php',
'PEAR_REST_11' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/11.php',
'PEAR_REST_13' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/REST/13.php',
'PEAR_Registry' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Registry.php',
'PEAR_RunTest' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/RunTest.php',
'PEAR_Task_Common' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Common.php',
'PEAR_Task_Postinstallscript' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript.php',
'PEAR_Task_Postinstallscript_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Postinstallscript/rw.php',
'PEAR_Task_Replace' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Replace.php',
'PEAR_Task_Replace_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Replace/rw.php',
'PEAR_Task_Unixeol' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol.php',
'PEAR_Task_Unixeol_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Unixeol/rw.php',
'PEAR_Task_Windowseol' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol.php',
'PEAR_Task_Windowseol_rw' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Task/Windowseol/rw.php',
'PEAR_Validate' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Validate.php',
'PEAR_Validator_PECL' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/Validator/PECL.php',
'PEAR_XMLParser' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/PEAR/XMLParser.php',
'Structures_Graph' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph.php',
'Structures_Graph_Manipulator_AcyclicTest' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/AcyclicTest.php',
'Structures_Graph_Manipulator_TopologicalSorter' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Manipulator/TopologicalSorter.php',
'Structures_Graph_Node' => __DIR__ . '/..' . '/pear-pear.php.net/Structures_Graph/Structures/Graph/Node.php',
'System' => __DIR__ . '/..' . '/pear-pear.php.net/PEAR/System.php',
'Text_Highlighter' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter.php',
'Text_Highlighter_ABAP' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/ABAP.php',
'Text_Highlighter_AVRC' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/AVRC.php',
'Text_Highlighter_CPP' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/CPP.php',
'Text_Highlighter_CSS' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/CSS.php',
'Text_Highlighter_DIFF' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/DIFF.php',
'Text_Highlighter_DTD' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/DTD.php',
'Text_Highlighter_Generator' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Generator.php',
'Text_Highlighter_HTML' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/HTML.php',
'Text_Highlighter_JAVA' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/JAVA.php',
'Text_Highlighter_JAVASCRIPT' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/JAVASCRIPT.php',
'Text_Highlighter_MYSQL' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/MYSQL.php',
'Text_Highlighter_PERL' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PERL.php',
'Text_Highlighter_PHP' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PHP.php',
'Text_Highlighter_PYTHON' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/PYTHON.php',
'Text_Highlighter_RUBY' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/RUBY.php',
'Text_Highlighter_Renderer' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer.php',
'Text_Highlighter_Renderer_Array' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Array.php',
'Text_Highlighter_Renderer_BB' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/BB.php',
'Text_Highlighter_Renderer_Console' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Console.php',
'Text_Highlighter_Renderer_Html' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/Html.php',
'Text_Highlighter_Renderer_HtmlTags' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/HtmlTags.php',
'Text_Highlighter_Renderer_JSON' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/JSON.php',
'Text_Highlighter_Renderer_XML' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/Renderer/XML.php',
'Text_Highlighter_SH' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/SH.php',
'Text_Highlighter_SQL' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/SQL.php',
'Text_Highlighter_VBSCRIPT' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/VBSCRIPT.php',
'Text_Highlighter_XML' => __DIR__ . '/..' . '/pear-pear.php.net/Text_Highlighter/Text/Highlighter/XML.php',
'XML_Parser' => __DIR__ . '/..' . '/pear-pear.php.net/XML_Parser/XML/Parser.php',
'XML_Parser_Error' => __DIR__ . '/..' . '/pear-pear.php.net/XML_Parser/XML/Parser.php',
'XML_Parser_Simple' => __DIR__ . '/..' . '/pear-pear.php.net/XML_Parser/XML/Parser/Simple.php',
'XML_Util' => __DIR__ . '/..' . '/pear-pear.php.net/XML_Util/XML/Util.php',
); );
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)

16
vendor/composer/include_paths.php vendored Normal file
View file

@ -0,0 +1,16 @@
<?php
// include_paths.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/pear-pear.php.net/Console_Getopt',
$vendorDir . '/pear-pear.php.net/Archive_Tar',
$vendorDir . '/pear-pear.php.net/Structures_Graph',
$vendorDir . '/pear-pear.php.net/XML_Util',
$vendorDir . '/pear-pear.php.net/XML_Parser',
$vendorDir . '/pear-pear.php.net/PEAR',
$vendorDir . '/pear-pear.php.net/Text_Highlighter',
);

View file

@ -98,5 +98,303 @@
"mobile detector", "mobile detector",
"php mobile detect" "php mobile detect"
] ]
},
{
"name": "pear-pear.php.net/Console_Getopt",
"version": "1.4.1",
"version_normalized": "1.4.1.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Console_Getopt-1.4.1.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/console_getopt": "== 1.4.1.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD-2-Clause"
],
"description": "This is a PHP implementation of \"getopt\" supporting both\nshort and long options."
},
{
"name": "pear-pear.php.net/Archive_Tar",
"version": "1.4.2",
"version_normalized": "1.4.2.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Archive_Tar-1.4.2.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.2.0.0"
},
"replace": {
"pear-pear/archive_tar": "== 1.4.2.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"New BSD License"
],
"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/Structures_Graph",
"version": "1.1.1",
"version_normalized": "1.1.1.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Structures_Graph-1.1.1.tgz",
"reference": null,
"shasum": null
},
"require": {
"php": ">=5.3.0.0"
},
"replace": {
"pear-pear/structures_graph": "== 1.1.1.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"LGPL-3.0+"
],
"description": "Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed\nand undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing\nas well as for characteristic extraction from the graph topology."
},
{
"name": "pear-pear.php.net/XML_Util",
"version": "1.4.2",
"version_normalized": "1.4.2.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/XML_Util-1.4.2.tgz",
"reference": null,
"shasum": null
},
"require": {
"ext-pcre": "*",
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/xml_util": "== 1.4.2.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD License"
],
"description": "Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more."
},
{
"name": "pear-pear.php.net/XML_Parser",
"version": "1.3.7",
"version_normalized": "1.3.7.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/XML_Parser-1.3.7.tgz",
"reference": null,
"shasum": null
},
"require": {
"pear-pear.php.net/pear": "*",
"php": ">=4.2.0.0"
},
"replace": {
"pear-pear/xml_parser": "== 1.3.7.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"BSD License"
],
"description": "This is an XML parser based on PHPs built-in xml extension.\nIt supports two basic modes of operation: \"func\" and \"event\". In \"func\" mode, it will look for a function named after each element (xmltag_ELEMENT for start tags and xmltag_ELEMENT_ for end tags), and in \"event\" mode it uses a set of generic callbacks.\n\nSince version 1.2.0 there's a new XML_Parser_Simple class that makes parsing of most XML documents easier, by automatically providing a stack for the elements.\nFurthermore its now possible to split the parser from the handler object, so you do not have to extend XML_Parser anymore in order to parse a document with it."
},
{
"name": "pear-pear.php.net/PEAR",
"version": "1.10.3",
"version_normalized": "1.10.3.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/PEAR-1.10.3.tgz",
"reference": null,
"shasum": null
},
"require": {
"ext-pcre": "*",
"ext-xml": "*",
"pear-pear.php.net/archive_tar": ">=1.4.0.0",
"pear-pear.php.net/console_getopt": ">=1.4.1.0",
"pear-pear.php.net/structures_graph": ">=1.1.0.0",
"pear-pear.php.net/xml_util": ">=1.3.0.0",
"php": ">=5.4.0.0"
},
"conflict": {
"pear-pear.php.net/pear_frontend_gtk": "<0.4.0.0",
"pear-pear.php.net/pear_frontend_web": "<=0.4.0.0"
},
"replace": {
"pear-pear/pear": "== 1.10.3.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"New BSD License"
],
"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/Text_Highlighter",
"version": "0.8.0",
"version_normalized": "0.8.0.0",
"dist": {
"type": "file",
"url": "https://pear.php.net/get/Text_Highlighter-0.8.0.tgz",
"reference": null,
"shasum": null
},
"require": {
"pear-pear.php.net/console_getopt": ">=1.4.1.0",
"pear-pear.php.net/pear": ">=1.10.3.0",
"pear-pear.php.net/xml_parser": ">=1.3.7.0",
"php": ">=5.4.0.0"
},
"replace": {
"pear-pear/text_highlighter": "== 0.8.0.0"
},
"type": "pear-library",
"installation-source": "dist",
"autoload": {
"classmap": [
""
]
},
"include-path": [
"/"
],
"license": [
"PHP License"
],
"description": "Text_Highlighter is a package for syntax highlighting.\n\nIt provides a base class provining all the functionality,\nand a descendent classes geneator class.\n\nThe main idea is to simplify creation of subclasses\nimplementing syntax highlighting for particular language.\nSubclasses do not implement any new functioanality,\nthey just provide syntax highlighting rules.\nThe rules sources are in XML format.\n\nTo create a highlighter for a language, there is no need\nto code a new class manually. Simply describe the rules\nin XML file and use Text_Highlighter_Generator to create\na new class."
},
{
"name": "league/html-to-markdown",
"version": "4.4.1",
"version_normalized": "4.4.1.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/html-to-markdown.git",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/82ea375b5b2b1da1da222644c0565c695bf88186",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xml": "*",
"php": ">=5.3.3"
},
"require-dev": {
"mikehaertl/php-shellcommand": "~1.1.0",
"phpunit/phpunit": "4.*",
"scrutinizer/ocular": "~1.1"
},
"time": "2017-03-16T00:45:59+00:00",
"bin": [
"bin/html-to-markdown"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\HTMLToMarkdown\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"role": "Lead Developer"
},
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net",
"role": "Original Author"
}
],
"description": "An HTML-to-markdown conversion helper for PHP",
"homepage": "https://github.com/thephpleague/html-to-markdown",
"keywords": [
"html",
"markdown"
]
} }
] ]

View file

@ -0,0 +1,214 @@
# Change Log
All notable changes to this project will be documented in this file.
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [Unreleased][unreleased]
## [4.4.1]
### Fixed
- Fixed autolinking of invalid URLs (#129)
## [4.4.0]
### Added
- Added `hard_break` configuration option (#112, #115)
- The `HtmlConverter` can now be instantiated with an `Environment` (#118)
### Fixed
- Fixed handling of paragraphs in list item elements (#47, #110)
- Fixed phantom spaces when newlines follow `br` elements (#116, #117)
- Fixed link converter not sanitizing inner spaces properly (#119, #120)
## [4.3.1]
### Changed
- Revised the sanitization implementation (#109)
### Fixed
- Fixed tag-like content not being escaped (#67, #109)
- Fixed thematic break-like content not being escaped (#65, #109)
- Fixed codefence-like content not being escaped (#64, #109)
## [4.3.0]
### Added
- Added full support for PHP 7.0 and 7.1
### Changed
- Changed `<pre>` and `<pre><code>` conversions to use backticks instead of indendation (#102)
### Fixed
- Fixed issue where specified code language was not preserved (#70, #102)
- Fixed issue where `<code>` tags nested in `<pre>` was not converted properly (#70, #102)
- Fixed header-like content not being escaped (#76, #105)
- Fixed blockquote-like content not being escaped (#77, #103)
- Fixed ordered list-like content not being escaped (#73, #106)
- Fixed unordered list-like content not being escaped (#71, #107)
## [4.2.2]
### Fixed
- Fixed sanitization bug which sometimes removes desired content (#63, #101)
## [4.2.1]
### Fixed
- Fixed path to autoload.php when used as a library (#98)
- Fixed edge case for tags containing only whitespace (#99)
### Removed
- Removed double HTML entity decoding, as this is not desireable (#60)
## [4.2.0]
### Added
- Added the ability to invoke HtmlConverter objects as functions (#85)
### Fixed
- Fixed improper handling of nested list items (#19 and #84)
- Fixed preceeding or trailing spaces within emphasis tags (#83)
## [4.1.1]
### Fixed
- Fixed conversion of empty paragraphs (#78)
- Fixed `preg_replace` so it wouldn't break UTF-8 characters (#79)
## [4.1.0]
### Added
- Added `bin/html-to-markdown` script
### Changed
- Changed default italic character to `_` (#58)
## [4.0.1]
### Fixed
- Added escaping to avoid * and _ in a text being rendered as emphasis (#48)
### Removed
- Removed the demo (#51)
- `.styleci.yml` and `CONTRIBUTING.md` are no longer included in distributions (#50)
## [4.0.0]
This release changes the visibility of several methods/properties. #42 and #43 brought to light that some visiblities were
not ideally set, so this releases fixes that. Moving forwards this should reduce the chance of introducing BC-breaking changes.
### Added
- Added new `HtmlConverter::getEnvironment()` method to expose the `Environment` (#42, #43)
### Changed
- Changed `Environment::addConverter()` from `protected` to `public`, enabling custom converters to be added (#42, #43)
- Changed `HtmlConverter::createDOMDocument()` from `protected` to `private`
- Changed `Element::nextCached` from `protected` to `private`
- Made the `Environment` class `final`
## [3.1.1]
### Fixed
- Empty HTML strings now result in empty Markdown documents (#40, #41)
## [3.1.0]
### Added
- Added new `equals` method to `Element` to check for equality
### Changes
- Use Linux line endings consistently instead of plaform-specific line endings (#36)
### Fixed
- Cleaned up code style
## [3.0.0]
### Changed
- Changed namespace to `League\HTMLToMarkdown`
- Changed packagist name to `league/html-to-markdown`
- Re-organized code into several separate classes
- `<a>` tags with identical href and inner text are now rendered using angular bracket syntax (#31)
- `<div>` elements are now treated as block-level elements (#33)
## [2.2.2]
### Added
- Added support for PHP 5.6 and HHVM
- Enabled testing against PHP 7 nightlies
- Added this CHANGELOG.md
### Fixed
- Fixed whitespace preservation between inline elements (#9 and #10)
## [2.2.1]
### Fixed
- Preserve placeholder links (#22)
## [2.2.0]
### Added
- Added CircleCI config
### Changed
- `<pre>` blocks are now treated as code elements
### Removed
- Dropped support for PHP 5.2
- Removed incorrect README comment regarding `#text` nodes (#17)
## [2.1.2]
### Added
- Added the ability to blacklist/remove specific node types (#11)
### Changed
- Line breaks are now placed after divs instead of before them
- Newlines inside of link texts are now removed
- Updated the minimum PHPUnit version to 4.*
## [2.1.1]
### Added
- Added options to customize emphasis characters
## [2.1.0]
### Added
- Added option to strip HTML tags without Markdown equivalents
- Added `convert()` method for converter reuse
- Added ability to set options after instance construction
- Documented the required PHP extensions (#4)
### Changed
- ATX style now used for h1 and h2 tags inside blockquotes
### Fixed
- Newlines inside blockquotes are now started with a bracket
- Fixed some incorrect docblocks
- `__toString()` now returns an empty string if input is empty
- Convert head tag if body tag is empty (#7)
- Preserve special characters inside tags without md equivalents (#6)
## [2.0.1]
### Fixed
- Fixed first line indentation for multi-line code blocks
- Fixed consecutive anchors get separating spaces stripped (#3)
## [2.0.0]
### Added
- Initial release
[unreleased]: https://github.com/thephpleague/html-to-markdown/compare/4.4.1...master
[4.4.1]: https://github.com/thephpleague/html-to-markdown/compare/4.4.0...4.4.1
[4.4.0]: https://github.com/thephpleague/html-to-markdown/compare/4.3.1...4.4.0
[4.3.1]: https://github.com/thephpleague/html-to-markdown/compare/4.3.0...4.3.1
[4.3.0]: https://github.com/thephpleague/html-to-markdown/compare/4.2.2...4.3.0
[4.2.2]: https://github.com/thephpleague/html-to-markdown/compare/4.2.1...4.2.2
[4.2.1]: https://github.com/thephpleague/html-to-markdown/compare/4.2.0...4.2.1
[4.2.0]: https://github.com/thephpleague/html-to-markdown/compare/4.1.1...4.2.0
[4.1.1]: https://github.com/thephpleague/html-to-markdown/compare/4.1.0...4.1.1
[4.1.0]: https://github.com/thephpleague/html-to-markdown/compare/4.0.1...4.1.0
[4.0.1]: https://github.com/thephpleague/html-to-markdown/compare/4.0.0...4.0.1
[4.0.0]: https://github.com/thephpleague/html-to-markdown/compare/3.1.1...4.0.0
[3.1.1]: https://github.com/thephpleague/html-to-markdown/compare/3.1.0...3.1.1
[3.1.0]: https://github.com/thephpleague/html-to-markdown/compare/3.0.0...3.1.0
[3.0.0]: https://github.com/thephpleague/html-to-markdown/compare/2.2.2...3.0.0
[2.2.2]: https://github.com/thephpleague/html-to-markdown/compare/2.2.1...2.2.2
[2.2.1]: https://github.com/thephpleague/html-to-markdown/compare/2.2.0...2.2.1
[2.2.0]: https://github.com/thephpleague/html-to-markdown/compare/2.1.2...2.2.0
[2.1.2]: https://github.com/thephpleague/html-to-markdown/compare/2.1.1...2.1.2
[2.1.1]: https://github.com/thephpleague/html-to-markdown/compare/2.1.0...2.1.1
[2.1.0]: https://github.com/thephpleague/html-to-markdown/compare/2.0.1...2.1.0
[2.0.1]: https://github.com/thephpleague/html-to-markdown/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/thephpleague/html-to-markdown/compare/775f91e...2.0.0

View file

@ -0,0 +1,22 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)

View file

@ -1,6 +1,8 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013 Nick Cernis Copyright (c) 2015 Colin O'Dell
Originally created by Nick Cernis
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

196
vendor/league/html-to-markdown/README.md vendored Normal file
View file

@ -0,0 +1,196 @@
HTML To Markdown for PHP
========================
[![Join the chat at https://gitter.im/thephpleague/html-to-markdown](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/thephpleague/html-to-markdown?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Latest Version](https://img.shields.io/packagist/v/league/html-to-markdown.svg?style=flat-square)](https://packagist.org/packages/league/html-to-markdown)
[![Software License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
[![Build Status](https://img.shields.io/travis/thephpleague/html-to-markdown/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/html-to-markdown)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/html-to-markdown.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/html-to-markdown.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown)
[![Total Downloads](https://img.shields.io/packagist/dt/league/html-to-markdown.svg?style=flat-square)](https://packagist.org/packages/league/html-to-markdown)
Library which converts HTML to [Markdown](http://daringfireball.net/projects/markdown/) for your sanity and convenience.
**Requires**: PHP 5.3+
**Lead Developer**: [@colinodell](http://twitter.com/colinodell)
**Original Author**: [@nickcernis](http://twitter.com/nickcernis)
### Why convert HTML to Markdown?
*"What alchemy is this?"* you mutter. *"I can see why you'd convert [Markdown to HTML](https://github.com/thephpleague/commonmark),"* you continue, already labouring the question somewhat, *"but why go the other way?"*
Typically you would convert HTML to Markdown if:
1. You have an existing HTML document that needs to be edited by people with good taste.
2. You want to store new content in HTML format but edit it as Markdown.
3. You want to convert HTML email to plain text email.
4. You know a guy who's been converting HTML to Markdown for years, and now he can speak Elvish. You'd quite like to be able to speak Elvish.
5. You just really like Markdown.
### How to use it
Require the library by issuing this command:
```bash
composer require league/html-to-markdown
```
Add `require 'vendor/autoload.php';` to the top of your script.
Next, create a new HtmlConverter instance, passing in your valid HTML code to its `convert()` function:
```php
use League\HTMLToMarkdown\HtmlConverter;
$converter = new HtmlConverter();
$html = "<h3>Quick, to the Batpoles!</h3>";
$markdown = $converter->convert($html);
```
The `$markdown` variable now contains the Markdown version of your HTML as a string:
```php
echo $markdown; // ==> ### Quick, to the Batpoles!
```
The included `demo` directory contains an HTML->Markdown conversion form to try out.
### Conversion options
By default, HTML To Markdown preserves HTML tags without Markdown equivalents, like `<span>` and `<div>`.
To strip HTML tags that don't have a Markdown equivalent while preserving the content inside them, set `strip_tags` to true, like this:
```php
$converter = new HtmlConverter(array('strip_tags' => true));
$html = '<span>Turnips!</span>';
$markdown = $converter->convert($html); // $markdown now contains "Turnips!"
```
Or more explicitly, like this:
```php
$converter = new HtmlConverter();
$converter->getConfig()->setOption('strip_tags', true);
$html = '<span>Turnips!</span>';
$markdown = $converter->convert($html); // $markdown now contains "Turnips!"
```
Note that only the tags themselves are stripped, not the content they hold.
To strip tags and their content, pass a space-separated list of tags in `remove_nodes`, like this:
```php
$converter = new HtmlConverter(array('remove_nodes' => 'span div'));
$html = '<span>Turnips!</span><div>Monkeys!</div>';
$markdown = $converter->convert($html); // $markdown now contains ""
```
### Style options
Bold and italic tags are converted using the asterisk syntax by default. Change this to the underlined syntax using the `bold_style` and `italic_style` options.
```php
$converter = new HtmlConverter();
$converter->getConfig()->setOption('italic_style', '_');
$converter->getConfig()->setOption('bold_style', '__');
$html = '<em>Italic</em> and a <strong>bold</strong>';
$markdown = $converter->convert($html); // $markdown now contains "_Italic_ and a __bold__"
```
### Line break options
By default, `br` tags are converted to two spaces followed by a newline character as per [traditional Markdown](https://daringfireball.net/projects/markdown/syntax#p). Set `hard_break` to `true` to omit the two spaces, as per GitHub Flavored Markdown (GFM).
```php
$converter = new HtmlConverter();
$html = '<p>test<br>line break</p>';
$converter->getConfig()->setOption('hard_break', true);
$markdown = $converter->convert($html); // $markdown now contains "test\nline break"
$converter->getConfig()->setOption('hard_break', false); // default
$markdown = $converter->convert($html); // $markdown now contains "test \nline break"
```
### Passing custom Environment object
You can pass current `Environment` object to customize i.e. which converters should be used.
```php
$environment = new Environment(array(
// your configuration here
));
$environment->addConverter(new HeaderConverter()); // optionally - add converter manually
$converter = new HtmlConverter($environment);
$html = '<h3>Header</h3>
<img src="" />
';
$markdown = $converter->convert($html); // $markdown now contains "### Header" and "<img src="" />"
```
### Limitations
- Markdown Extra, MultiMarkdown and other variants aren't supported just Markdown.
### Known issues
- Nested lists and lists containing multiple paragraphs aren't converted correctly.
- Lists inside blockquotes aren't converted correctly.
- Any reported [open issues here](https://github.com/thephpleague/html-to-markdown/issues?state=open).
[Report your issue or request a feature here.](https://github.com/thephpleague/html-to-markdown/issues/new) Issues with patches or failing tests are especially welcome.
### Style notes
- Setext (underlined) headers are the default for H1 and H2. If you prefer the ATX style for H1 and H2 (# Header 1 and ## Header 2), set `header_style` to 'atx' in the options array when you instantiate the object:
`$converter = new HtmlConverter(array('header_style'=>'atx'));`
Headers of H3 priority and lower always use atx style.
- Links and images are referenced inline. Footnote references (where image src and anchor href attributes are listed in the footnotes) are not used.
- Blockquotes aren't line wrapped it makes the converted Markdown easier to edit.
### Dependencies
HTML To Markdown requires PHP's [xml](http://www.php.net/manual/en/xml.installation.php), [lib-xml](http://www.php.net/manual/en/libxml.installation.php), and [dom](http://www.php.net/manual/en/dom.installation.php) extensions, all of which are enabled by default on most distributions.
Errors such as "Fatal error: Class 'DOMDocument' not found" on distributions such as CentOS that disable PHP's xml extension can be resolved by installing php-xml.
### Contributors
Many thanks to all [contributors](https://github.com/thephpleague/html-to-markdown/graphs/contributors) so far. Further improvements and feature suggestions are very welcome.
### How it works
HTML To Markdown creates a DOMDocument from the supplied HTML, walks through the tree, and converts each node to a text node containing the equivalent markdown, starting from the most deeply nested node and working inwards towards the root node.
### To-do
- Support for nested lists and lists inside blockquotes.
- Offer an option to preserve tags as HTML if they contain attributes that can't be represented with Markdown (e.g. `style`).
### Trying to convert Markdown to HTML?
Use one of these great libraries:
- [league/commonmark](https://github.com/thephpleague/commonmark) (recommended)
- [cebe/markdown](https://github.com/cebe/markdown)
- [PHP Markdown](https://michelf.ca/projects/php-markdown/)
- [Parsedown](https://github.com/erusev/parsedown)
No guarantees about the Elvish, though.

View file

@ -0,0 +1,108 @@
#!/usr/bin/env php
<?php
requireAutoloader();
ini_set('display_errors', 'stderr');
foreach ($argv as $i => $arg) {
if ($i === 0) {
continue;
}
if (substr($arg, 0, 1) === '-') {
switch ($arg) {
case '-h':
case '--help':
echo getHelpText();
exit(0);
default:
fail('Unknown option: ' . $arg);
}
} else {
$src = $argv[1];
}
}
if (isset($src)) {
if (!file_exists($src)) {
fail('File not found: ' . $src);
}
$html = file_get_contents($src);
} else {
$stdin = fopen('php://stdin', 'r');
stream_set_blocking($stdin, false);
$html = stream_get_contents($stdin);
fclose($stdin);
if (empty($html)) {
fail(getHelpText());
}
}
$converter = new League\HTMLToMarkdown\HtmlConverter();
echo $converter->convert($html);
/**
* Get help and usage info
*
* @return string
*/
function getHelpText()
{
return <<<HELP
HTML To Markdown
Usage: html-to-markdown [OPTIONS] [FILE]
-h, --help Shows help and usage information
If no file is given, input will be read from STDIN
Examples:
Converting a file named document.html:
html-to-markdown document.html
Converting a file and saving its output:
html-to-markdown document.html > output.md
Converting from STDIN:
echo -e '<h1>Hello World!</h1>' | html-to-markdown
Converting from STDIN and saving the output:
echo -e '<h1>Hello World!</h1>' | html-to-markdown > output.md
HELP;
}
/**
* @param string $message Error message
*/
function fail($message)
{
fwrite(STDERR, $message . "\n");
exit(1);
}
function requireAutoloader()
{
$autoloadPaths = array(
// Local package usage
__DIR__ . '/../vendor/autoload.php',
// Package was included as a library
__DIR__ . '/../../../autoload.php',
);
foreach ($autoloadPaths as $path) {
if (file_exists($path)) {
require_once $path;
break;
}
}
}

View file

@ -0,0 +1,48 @@
{
"name": "league/html-to-markdown",
"type": "library",
"description": "An HTML-to-markdown conversion helper for PHP",
"keywords": ["markdown", "html"],
"homepage": "https://github.com/thephpleague/html-to-markdown",
"license": "MIT",
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"role": "Lead Developer"
},
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net",
"role": "Original Author"
}
],
"autoload": {
"psr-4": {
"League\\HTMLToMarkdown\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"League\\HTMLToMarkdown\\Test\\": "tests"
}
},
"require": {
"php": ">=5.3.3",
"ext-dom": "*",
"ext-xml": "*"
},
"require-dev": {
"mikehaertl/php-shellcommand": "~1.1.0",
"phpunit/phpunit": "4.*",
"scrutinizer/ocular": "~1.1"
},
"bin": ["bin/html-to-markdown"],
"extra": {
"branch-alias": {
"dev-master": "4.5-dev"
}
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace League\HTMLToMarkdown;
class Configuration
{
protected $config;
/**
* @param array $config
*/
public function __construct(array $config = array())
{
$this->config = $config;
}
/**
* @param array $config
*/
public function merge(array $config = array())
{
$this->config = array_replace_recursive($this->config, $config);
}
/**
* @param array $config
*/
public function replace(array $config = array())
{
$this->config = $config;
}
/**
* @param string $key
* @param mixed $value
*/
public function setOption($key, $value)
{
$this->config[$key] = $value;
}
/**
* @param string|null $key
* @param mixed|null $default
*
* @return mixed|null
*/
public function getOption($key = null, $default = null)
{
if ($key === null) {
return $this->config;
}
if (!isset($this->config[$key])) {
return $default;
}
return $this->config[$key];
}
}

View file

@ -0,0 +1,11 @@
<?php
namespace League\HTMLToMarkdown;
interface ConfigurationAwareInterface
{
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config);
}

View file

@ -0,0 +1,44 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class BlockquoteConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
// Contents should have already been converted to Markdown by this point,
// so we just need to add '>' symbols to each line.
$markdown = '';
$quote_content = trim($element->getValue());
$lines = preg_split('/\r\n|\r|\n/', $quote_content);
$total_lines = count($lines);
foreach ($lines as $i => $line) {
$markdown .= '> ' . $line . "\n";
if ($i + 1 === $total_lines) {
$markdown .= "\n";
}
}
return $markdown;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('blockquote');
}
}

View file

@ -0,0 +1,62 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class CodeConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$language = null;
// Checking for language class on the code block
$classes = $element->getAttribute('class');
if ($classes) {
// Since tags can have more than one class, we need to find the one that starts with 'language-'
$classes = explode(' ', $classes);
foreach ($classes as $class) {
if (strpos($class, 'language-') !== false) {
// Found one, save it as the selected language and stop looping over the classes.
// The space after the language avoids gluing the actual code with the language tag
$language = str_replace('language-', '', $class) . ' ';
break;
}
}
}
$markdown = '';
$code = html_entity_decode($element->getChildrenAsString());
// In order to remove the code tags we need to search for them and, in the case of the opening tag
// use a regular expression to find the tag and the other attributes it might have
$code = preg_replace('/<code\b[^>]*>/', '', $code);
$code = str_replace('</code>', '', $code);
// Checking if the code has multiple lines
$lines = preg_split('/\r\n|\r|\n/', $code);
if (count($lines) > 1) {
// Multiple lines detected, adding three backticks and newlines
$markdown .= '```' . $language . "\n" . $code . "\n" . '```';
} else {
// One line of code, wrapping it on one backtick.
$markdown .= '`' . $language . $code . '`';
}
return $markdown;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('code');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class CommentConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
return '';
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('#comment');
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
interface ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element);
/**
* @return string[]
*/
public function getSupportedTags();
}

View file

@ -0,0 +1,50 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\Configuration;
use League\HTMLToMarkdown\ConfigurationAwareInterface;
use League\HTMLToMarkdown\ElementInterface;
class DefaultConverter implements ConverterInterface, ConfigurationAwareInterface
{
const DEFAULT_CONVERTER = '_default';
/**
* @var Configuration
*/
protected $config;
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config)
{
$this->config = $config;
}
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
// If strip_tags is false (the default), preserve tags that don't have Markdown equivalents,
// such as <span> nodes on their own. C14N() canonicalizes the node to a string.
// See: http://www.php.net/manual/en/domnode.c14n.php
if ($this->config->getOption('strip_tags', false)) {
return $element->getValue();
}
return html_entity_decode($element->getChildrenAsString());
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array(self::DEFAULT_CONVERTER);
}
}

View file

@ -0,0 +1,45 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\Configuration;
use League\HTMLToMarkdown\ConfigurationAwareInterface;
use League\HTMLToMarkdown\ElementInterface;
class DivConverter implements ConverterInterface, ConfigurationAwareInterface
{
/**
* @var Configuration
*/
protected $config;
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config)
{
$this->config = $config;
}
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
if ($this->config->getOption('strip_tags', false)) {
return $element->getValue() . "\n\n";
}
return html_entity_decode($element->getChildrenAsString());
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('div');
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\Configuration;
use League\HTMLToMarkdown\ConfigurationAwareInterface;
use League\HTMLToMarkdown\ElementInterface;
class EmphasisConverter implements ConverterInterface, ConfigurationAwareInterface
{
/**
* @var Configuration
*/
protected $config;
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config)
{
$this->config = $config;
}
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$tag = $element->getTagName();
$value = $element->getValue();
if (!trim($value)) {
return '';
}
if ($tag === 'i' || $tag === 'em') {
$style = $this->config->getOption('italic_style');
} else {
$style = $this->config->getOption('bold_style');
}
$prefix = ltrim($value) !== $value ? ' ' : '';
$suffix = rtrim($value) !== $value ? ' ' : '';
return $prefix . $style . trim($value) . $style . $suffix;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('em', 'i', 'strong', 'b');
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\Configuration;
use League\HTMLToMarkdown\ConfigurationAwareInterface;
use League\HTMLToMarkdown\ElementInterface;
class HardBreakConverter implements ConverterInterface, ConfigurationAwareInterface
{
/**
* @var Configuration
*/
protected $config;
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config)
{
$this->config = $config;
}
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
return $this->config->getOption('hard_break') ? "\n" : " \n";
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('br');
}
}

View file

@ -0,0 +1,78 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\Configuration;
use League\HTMLToMarkdown\ConfigurationAwareInterface;
use League\HTMLToMarkdown\ElementInterface;
class HeaderConverter implements ConverterInterface, ConfigurationAwareInterface
{
const STYLE_ATX = 'atx';
const STYLE_SETEXT = 'setext';
/**
* @var Configuration
*/
protected $config;
/**
* @param Configuration $config
*/
public function setConfig(Configuration $config)
{
$this->config = $config;
}
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$level = (int) substr($element->getTagName(), 1, 1);
$style = $this->config->getOption('header_style', self::STYLE_SETEXT);
if (($level === 1 || $level === 2) && !$element->isDescendantOf('blockquote') && $style === self::STYLE_SETEXT) {
return $this->createSetextHeader($level, $element->getValue());
}
return $this->createAtxHeader($level, $element->getValue());
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
}
/**
* @param int $level
* @param string $content
*
* @return string
*/
private function createSetextHeader($level, $content)
{
$length = function_exists('mb_strlen') ? mb_strlen($content, 'utf-8') : strlen($content);
$underline = ($level === 1) ? '=' : '-';
return $content . "\n" . str_repeat($underline, $length) . "\n\n";
}
/**
* @param int $level
* @param string $content
*
* @return string
*/
private function createAtxHeader($level, $content)
{
$prefix = str_repeat('#', $level) . ' ';
return $prefix . $content . "\n\n";
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class HorizontalRuleConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
return "- - - - - -\n\n";
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('hr');
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class ImageConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$src = $element->getAttribute('src');
$alt = $element->getAttribute('alt');
$title = $element->getAttribute('title');
if ($title !== '') {
// No newlines added. <img> should be in a block-level element.
return '![' . $alt . '](' . $src . ' "' . $title . '")';
}
return '![' . $alt . '](' . $src . ')';
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('img');
}
}

View file

@ -0,0 +1,52 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class LinkConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$href = $element->getAttribute('href');
$title = $element->getAttribute('title');
$text = trim($element->getValue());
if ($title !== '') {
$markdown = '[' . $text . '](' . $href . ' "' . $title . '")';
} elseif ($href === $text && $this->isValidAutolink($href)) {
$markdown = '<' . $href . '>';
} else {
$markdown = '[' . $text . '](' . $href . ')';
}
if (!$href) {
$markdown = html_entity_decode($element->getChildrenAsString());
}
return $markdown;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('a');
}
/**
* @param string $href
*
* @return bool
*/
private function isValidAutolink($href)
{
return preg_match('/^[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*/i', $href) === 1;
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class ListBlockConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
return $element->getValue() . "\n";
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('ol', 'ul');
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class ListItemConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
// If parent is an ol, use numbers, otherwise, use dashes
$list_type = $element->getParent()->getTagName();
// Add spaces to start for nested list items
$level = $element->getListItemLevel($element);
$prefixForParagraph = str_repeat(' ', $level + 1);
$value = trim(implode("\n" . $prefixForParagraph, explode("\n", trim($element->getValue()))));
// If list item is the first in a nested list, add a newline before it
$prefix = '';
if ($level > 0 && $element->getSiblingPosition() === 1) {
$prefix = "\n";
}
if ($list_type === 'ul') {
return $prefix . '- ' . $value . "\n";
}
$number = $element->getSiblingPosition();
return $prefix . $number . '. ' . $value . "\n";
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('li');
}
}

View file

@ -0,0 +1,124 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class ParagraphConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$value = $element->getValue();
$markdown = '';
$lines = preg_split('/\r\n|\r|\n/', $value);
foreach ($lines as $line) {
/*
* Some special characters need to be escaped based on the position that they appear
* The following function will deal with those special cases.
*/
$markdown .= $this->escapeSpecialCharacters($line);
$markdown .= "\n";
}
return trim($markdown) !== '' ? rtrim($markdown) . "\n\n" : '';
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('p');
}
/**
* @param string $line
*
* @return string
*/
private function escapeSpecialCharacters($line)
{
$line = $this->escapeFirstCharacters($line);
$line = $this->escapeOtherCharacters($line);
$line = $this->escapeOtherCharactersRegex($line);
return $line;
}
/**
* @param string $line
*
* @return string
*/
private function escapeFirstCharacters($line)
{
$escapable = array(
'>',
'- ',
'+ ',
'--',
'~~~',
'---',
'- - -'
);
foreach ($escapable as $i) {
if (strpos(ltrim($line), $i) === 0) {
// Found a character that must be escaped, adding a backslash before
return '\\' . ltrim($line);
}
}
return $line;
}
/**
* @param string $line
*
* @return string
*/
private function escapeOtherCharacters($line)
{
$escapable = array(
'<!--'
);
foreach ($escapable as $i) {
if (strpos($line, $i) !== false) {
// Found an escapable character, escaping it
$line = substr_replace($line, '\\', strpos($line, $i), 0);
}
}
return $line;
}
/**
* @param string $line
*
* @return string
*/
private function escapeOtherCharactersRegex($line)
{
$regExs = array(
// Match numbers ending on ')' or '.' that are at the beginning of the line.
'/^[0-9]+(?=\)|\.)/'
);
foreach ($regExs as $i) {
if (preg_match($i, $line, $match)) {
// Matched an escapable character, adding a backslash on the string before the offending character
$line = substr_replace($line, '\\', strlen($match[0]), 0);
}
}
return $line;
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class PreformattedConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$markdown = '';
$pre_content = html_entity_decode($element->getChildrenAsString());
$pre_content = str_replace(array('<pre>', '</pre>'), '', $pre_content);
/*
* Checking for the code tag.
* Usually pre tags are used along with code tags. This conditional will check for already converted code tags,
* which use backticks, and if those backticks are at the beginning and at the end of the string it means
* there's no more information to convert.
*/
$firstBacktick = strpos(trim($pre_content), '`');
$lastBacktick = strrpos(trim($pre_content), '`');
if ($firstBacktick === 0 && $lastBacktick === strlen(trim($pre_content)) - 1) {
return $pre_content;
}
// If the execution reaches this point it means it's just a pre tag, with no code tag nested
// Normalizing new lines
$pre_content = preg_replace('/\r\n|\r|\n/', PHP_EOL, $pre_content);
// Checking if the string has multiple lines
$lines = preg_split('/\r\n|\r|\n/', $pre_content);
if (count($lines) > 1) {
// Multiple lines detected, adding three backticks and newlines
$markdown .= '```' . "\n" . $pre_content . "\n" . '```';
} else {
// One line of code, wrapping it on one backtick.
$markdown .= '`' . $pre_content . '`';
}
return $markdown;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('pre');
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace League\HTMLToMarkdown\Converter;
use League\HTMLToMarkdown\ElementInterface;
class TextConverter implements ConverterInterface
{
/**
* @param ElementInterface $element
*
* @return string
*/
public function convert(ElementInterface $element)
{
$markdown = $element->getValue();
// Remove leftover \n at the beginning of the line
$markdown = ltrim($markdown, "\n");
// Replace sequences of invisible characters with spaces
$markdown = preg_replace('~\s+~u', ' ', $markdown);
// Escape the following characters: '*', '_', '[', ']' and '\'
$markdown = preg_replace('~([*_\\[\\]\\\\])~u', '\\\\$1', $markdown);
$markdown = preg_replace('~^#~u', '\\\\#', $markdown);
if ($markdown === ' ') {
$next = $element->getNext();
if (!$next || $next->isBlock()) {
$markdown = '';
}
}
return $markdown;
}
/**
* @return string[]
*/
public function getSupportedTags()
{
return array('#text');
}
}

View file

@ -0,0 +1,257 @@
<?php
namespace League\HTMLToMarkdown;
class Element implements ElementInterface
{
/**
* @var \DOMNode
*/
protected $node;
/**
* @var ElementInterface|null
*/
private $nextCached;
public function __construct(\DOMNode $node)
{
$this->node = $node;
}
/**
* @return bool
*/
public function isBlock()
{
switch ($this->getTagName()) {
case 'blockquote':
case 'body':
case 'code':
case 'div':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
case 'hr':
case 'html':
case 'li':
case 'p':
case 'ol':
case 'ul':
return true;
default:
return false;
}
}
/**
* @return bool
*/
public function isText()
{
return $this->getTagName() === '#text';
}
/**
* @return bool
*/
public function isWhitespace()
{
return $this->getTagName() === '#text' && trim($this->getValue()) === '';
}
/**
* @return string
*/
public function getTagName()
{
return $this->node->nodeName;
}
/**
* @return string
*/
public function getValue()
{
return $this->node->nodeValue;
}
/**
* @return ElementInterface|null
*/
public function getParent()
{
return new static($this->node->parentNode) ?: null;
}
/**
* @return bool
*/
public function hasChildren()
{
return $this->node->hasChildNodes();
}
/**
* @return ElementInterface[]
*/
public function getChildren()
{
$ret = array();
/** @var \DOMNode $node */
foreach ($this->node->childNodes as $node) {
$ret[] = new static($node);
}
return $ret;
}
/**
* @return ElementInterface|null
*/
public function getNext()
{
if ($this->nextCached === null) {
$nextNode = $this->getNextNode($this->node);
if ($nextNode !== null) {
$this->nextCached = new static($nextNode);
}
}
return $this->nextCached;
}
/**
* @param \DomNode $node
* @param bool $checkChildren
*
* @return \DomNode|null
*/
private function getNextNode($node, $checkChildren = true)
{
if ($checkChildren && $node->firstChild) {
return $node->firstChild;
}
if ($node->nextSibling) {
return $node->nextSibling;
}
if ($node->parentNode) {
return $this->getNextNode($node->parentNode, false);
}
}
/**
* @param string[]|string $tagNames
*
* @return bool
*/
public function isDescendantOf($tagNames)
{
if (!is_array($tagNames)) {
$tagNames = array($tagNames);
}
for ($p = $this->node->parentNode; $p !== false; $p = $p->parentNode) {
if (is_null($p)) {
return false;
}
if (in_array($p->nodeName, $tagNames)) {
return true;
}
}
return false;
}
/**
* @param string $markdown
*/
public function setFinalMarkdown($markdown)
{
$markdown_node = $this->node->ownerDocument->createTextNode($markdown);
$this->node->parentNode->replaceChild($markdown_node, $this->node);
}
/**
* @return string
*/
public function getChildrenAsString()
{
return $this->node->C14N();
}
/**
* @return int
*/
public function getSiblingPosition()
{
$position = 0;
// Loop through all nodes and find the given $node
foreach ($this->getParent()->getChildren() as $current_node) {
if (!$current_node->isWhitespace()) {
$position++;
}
// TODO: Need a less-buggy way of comparing these
// Perhaps we can somehow ensure that we always have the exact same object and use === instead?
if ($this->equals($current_node)) {
break;
}
}
return $position;
}
/**
* @return int
*/
public function getListItemLevel()
{
$level = 0;
$parent = $this->getParent();
while ($parent !== null && $parent->node->parentNode) {
if ($parent->getTagName() === 'li') {
$level++;
}
$parent = $parent->getParent();
}
return $level;
}
/**
* @param string $name
*
* @return string
*/
public function getAttribute($name)
{
if ($this->node instanceof \DOMElement) {
return $this->node->getAttribute($name);
}
return '';
}
/**
* @param ElementInterface $element
*
* @return bool
*/
public function equals(ElementInterface $element)
{
if ($element instanceof self) {
return $element->node === $this->node;
}
return $element === $this;
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace League\HTMLToMarkdown;
interface ElementInterface
{
/**
* @return bool
*/
public function isBlock();
/**
* @return bool
*/
public function isText();
/**
* @return bool
*/
public function isWhitespace();
/**
* @return string
*/
public function getTagName();
/**
* @return string
*/
public function getValue();
/**
* @return ElementInterface|null
*/
public function getParent();
/**
* @param string|string[] $tagNames
*
* @return bool
*/
public function isDescendantOf($tagNames);
/**
* @return bool
*/
public function hasChildren();
/**
* @return ElementInterface[]
*/
public function getChildren();
/**
* @return ElementInterface|null
*/
public function getNext();
/**
* @return int
*/
public function getSiblingPosition();
/**
* @return string
*/
public function getChildrenAsString();
/**
* @param string $markdown
*/
public function setFinalMarkdown($markdown);
/**
* @param string $name
*
* @return string
*/
public function getAttribute($name);
}

View file

@ -0,0 +1,104 @@
<?php
namespace League\HTMLToMarkdown;
use League\HTMLToMarkdown\Converter\BlockquoteConverter;
use League\HTMLToMarkdown\Converter\CodeConverter;
use League\HTMLToMarkdown\Converter\CommentConverter;
use League\HTMLToMarkdown\Converter\ConverterInterface;
use League\HTMLToMarkdown\Converter\DefaultConverter;
use League\HTMLToMarkdown\Converter\DivConverter;
use League\HTMLToMarkdown\Converter\EmphasisConverter;
use League\HTMLToMarkdown\Converter\HardBreakConverter;
use League\HTMLToMarkdown\Converter\HeaderConverter;
use League\HTMLToMarkdown\Converter\HorizontalRuleConverter;
use League\HTMLToMarkdown\Converter\ImageConverter;
use League\HTMLToMarkdown\Converter\LinkConverter;
use League\HTMLToMarkdown\Converter\ListBlockConverter;
use League\HTMLToMarkdown\Converter\ListItemConverter;
use League\HTMLToMarkdown\Converter\ParagraphConverter;
use League\HTMLToMarkdown\Converter\PreformattedConverter;
use League\HTMLToMarkdown\Converter\TextConverter;
final class Environment
{
/**
* @var Configuration
*/
protected $config;
/**
* @var ConverterInterface[]
*/
protected $converters = array();
public function __construct(array $config = array())
{
$this->config = new Configuration($config);
$this->addConverter(new DefaultConverter());
}
/**
* @return Configuration
*/
public function getConfig()
{
return $this->config;
}
/**
* @param ConverterInterface $converter
*/
public function addConverter(ConverterInterface $converter)
{
if ($converter instanceof ConfigurationAwareInterface) {
$converter->setConfig($this->config);
}
foreach ($converter->getSupportedTags() as $tag) {
$this->converters[$tag] = $converter;
}
}
/**
* @param string $tag
*
* @return ConverterInterface
*/
public function getConverterByTag($tag)
{
if (isset($this->converters[$tag])) {
return $this->converters[$tag];
}
return $this->converters[DefaultConverter::DEFAULT_CONVERTER];
}
/**
* @param array $config
*
* @return Environment
*/
public static function createDefaultEnvironment(array $config = array())
{
$environment = new static($config);
$environment->addConverter(new BlockquoteConverter());
$environment->addConverter(new CodeConverter());
$environment->addConverter(new CommentConverter());
$environment->addConverter(new DivConverter());
$environment->addConverter(new EmphasisConverter());
$environment->addConverter(new HardBreakConverter());
$environment->addConverter(new HeaderConverter());
$environment->addConverter(new HorizontalRuleConverter());
$environment->addConverter(new ImageConverter());
$environment->addConverter(new LinkConverter());
$environment->addConverter(new ListBlockConverter());
$environment->addConverter(new ListItemConverter());
$environment->addConverter(new ParagraphConverter());
$environment->addConverter(new PreformattedConverter());
$environment->addConverter(new TextConverter());
return $environment;
}
}

View file

@ -0,0 +1,231 @@
<?php
namespace League\HTMLToMarkdown;
/**
* Class HtmlConverter
*
* A helper class to convert HTML to Markdown.
*
* @author Colin O'Dell <colinodell@gmail.com>
* @author Nick Cernis <nick@cern.is>
*
* @link https://github.com/thephpleague/html-to-markdown/ Latest version on GitHub.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT
*/
class HtmlConverter
{
/**
* @var Environment
*/
protected $environment;
/**
* Constructor
*
* @param Environment|array $options Environment object or configuration options
*/
public function __construct($options = array())
{
if ($options instanceof Environment) {
$this->environment = $options;
} elseif (is_array($options)) {
$defaults = array(
'header_style' => 'setext', // Set to 'atx' to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // Set to '__' if you prefer the underlined style
'italic_style' => '_', // Set to '*' if you prefer the asterisk style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: 'meta style script'
'hard_break' => false,// Set to true to turn <br> into `\n` instead of ` \n`
);
$this->environment = Environment::createDefaultEnvironment($defaults);
$this->environment->getConfig()->merge($options);
}
}
/**
* @return Environment
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* @return Configuration
*/
public function getConfig()
{
return $this->environment->getConfig();
}
/**
* Convert
*
* @see HtmlConverter::convert
*
* @param string $html
*
* @return string The Markdown version of the html
*/
public function __invoke($html)
{
return $this->convert($html);
}
/**
* Convert
*
* Loads HTML and passes to getMarkdown()
*
* @param string $html
*
* @throws \InvalidArgumentException
*
* @return string The Markdown version of the html
*/
public function convert($html)
{
if (trim($html) === '') {
return '';
}
$document = $this->createDOMDocument($html);
// Work on the entire DOM tree (including head and body)
if (!($root = $document->getElementsByTagName('html')->item(0))) {
throw new \InvalidArgumentException('Invalid HTML was provided');
}
$rootElement = new Element($root);
$this->convertChildren($rootElement);
// Store the now-modified DOMDocument as a string
$markdown = $document->saveHTML();
return $this->sanitize($markdown);
}
/**
* @param string $html
*
* @return \DOMDocument
*/
private function createDOMDocument($html)
{
$document = new \DOMDocument();
if ($this->getConfig()->getOption('suppress_errors')) {
// Suppress conversion errors (from http://bit.ly/pCCRSX)
libxml_use_internal_errors(true);
}
// Hack to load utf-8 HTML (from http://bit.ly/pVDyCt)
$document->loadHTML('<?xml encoding="UTF-8">' . $html);
$document->encoding = 'UTF-8';
if ($this->getConfig()->getOption('suppress_errors')) {
libxml_clear_errors();
}
return $document;
}
/**
* Convert Children
*
* Recursive function to drill into the DOM and convert each node into Markdown from the inside out.
*
* Finds children of each node and convert those to #text nodes containing their Markdown equivalent,
* starting with the innermost element and working up to the outermost element.
*
* @param ElementInterface $element
*/
private function convertChildren(ElementInterface $element)
{
// Don't convert HTML code inside <code> and <pre> blocks to Markdown - that should stay as HTML
// except if the current node is a code tag, which needs to be converted by the CodeConverter.
if ($element->isDescendantOf(array('pre', 'code')) && $element->getTagName() !== 'code') {
return;
}
// If the node has children, convert those to Markdown first
if ($element->hasChildren()) {
foreach ($element->getChildren() as $child) {
$this->convertChildren($child);
}
}
// Now that child nodes have been converted, convert the original node
$markdown = $this->convertToMarkdown($element);
// Create a DOM text node containing the Markdown equivalent of the original node
// Replace the old $node e.g. '<h3>Title</h3>' with the new $markdown_node e.g. '### Title'
$element->setFinalMarkdown($markdown);
}
/**
* Convert to Markdown
*
* Converts an individual node into a #text node containing a string of its Markdown equivalent.
*
* Example: An <h3> node with text content of 'Title' becomes a text node with content of '### Title'
*
* @param ElementInterface $element
*
* @return string The converted HTML as Markdown
*/
protected function convertToMarkdown(ElementInterface $element)
{
$tag = $element->getTagName();
// Strip nodes named in remove_nodes
$tags_to_remove = explode(' ', $this->getConfig()->getOption('remove_nodes'));
if (in_array($tag, $tags_to_remove)) {
return false;
}
$converter = $this->environment->getConverterByTag($tag);
return $converter->convert($element);
}
/**
* @param string $markdown
*
* @return string
*/
protected function sanitize($markdown)
{
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
$markdown = preg_replace('/<!DOCTYPE [^>]+>/', '', $markdown); // Strip doctype declaration
$markdown = trim($markdown); // Remove blank spaces at the beggining of the html
/*
* Removing unwanted tags. Tags should be added to the array in the order they are expected.
* XML, html and body opening tags should be in that order. Same case with closing tags
*/
$unwanted = array('<?xml encoding="UTF-8">', '<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '&#xD;');
foreach ($unwanted as $tag) {
if (strpos($tag, '/') === false) {
// Opening tags
if (strpos($markdown, $tag) === 0) {
$markdown = substr($markdown, strlen($tag));
}
} else {
// Closing tags
if (strpos($markdown, $tag) === strlen($markdown) - strlen($tag)) {
$markdown = substr($markdown, 0, -strlen($tag));
}
}
}
return trim($markdown, "\n\r\0\x0B");
}
}

2421
vendor/pear-pear.php.net/Archive_Tar/Archive/Tar.php generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,360 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* PHP Version 5
*
* Copyright (c) 1997-2004 The PHP Group
*
* This source file is subject to version 3.0 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available through the world-wide-web at the following url:
* http://www.php.net/license/3_0.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license@php.net so we can mail you a copy immediately.
*
* @category Console
* @package Console_Getopt
* @author Andrei Zmievski <andrei@php.net>
* @license http://www.php.net/license/3_0.txt PHP 3.0
* @version CVS: $Id$
* @link http://pear.php.net/package/Console_Getopt
*/
require_once 'PEAR.php';
/**
* Command-line options parsing class.
*
* @category Console
* @package Console_Getopt
* @author Andrei Zmievski <andrei@php.net>
* @license http://www.php.net/license/3_0.txt PHP 3.0
* @link http://pear.php.net/package/Console_Getopt
*/
class Console_Getopt
{
/**
* Parses the command-line options.
*
* The first parameter to this function should be the list of command-line
* arguments without the leading reference to the running program.
*
* The second parameter is a string of allowed short options. Each of the
* option letters can be followed by a colon ':' to specify that the option
* requires an argument, or a double colon '::' to specify that the option
* takes an optional argument.
*
* The third argument is an optional array of allowed long options. The
* leading '--' should not be included in the option name. Options that
* require an argument should be followed by '=', and options that take an
* option argument should be followed by '=='.
*
* The return value is an array of two elements: the list of parsed
* options and the list of non-option command-line arguments. Each entry in
* the list of parsed options is a pair of elements - the first one
* specifies the option, and the second one specifies the option argument,
* if there was one.
*
* Long and short options can be mixed.
*
* Most of the semantics of this function are based on GNU getopt_long().
*
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return array two-element array containing the list of parsed options and
* the non-option arguments
*/
public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false)
{
return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown);
}
/**
* This function expects $args to start with the script name (POSIX-style).
* Preserved for backwards compatibility.
*
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
*
* @see getopt2()
* @return array two-element array containing the list of parsed options and
* the non-option arguments
*/
public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false)
{
return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown);
}
/**
* The actual implementation of the argument parsing code.
*
* @param int $version Version to use
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return array
*/
public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false)
{
// in case you pass directly readPHPArgv() as the first arg
if (PEAR::isError($args)) {
return $args;
}
if (empty($args)) {
return array(array(), array());
}
$non_opts = $opts = array();
settype($args, 'array');
if ($long_options) {
sort($long_options);
}
/*
* Preserve backwards compatibility with callers that relied on
* erroneous POSIX fix.
*/
if ($version < 2) {
if (isset($args[0]{0}) && $args[0]{0} != '-') {
array_shift($args);
}
}
reset($args);
while (list($i, $arg) = each($args)) {
/* The special element '--' means explicit end of
options. Treat the rest of the arguments as non-options
and end the loop. */
if ($arg == '--') {
$non_opts = array_merge($non_opts, array_slice($args, $i + 1));
break;
}
if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
$non_opts = array_merge($non_opts, array_slice($args, $i));
break;
} elseif (strlen($arg) > 1 && $arg{1} == '-') {
$error = Console_Getopt::_parseLongOption(substr($arg, 2),
$long_options,
$opts,
$args,
$skip_unknown);
if (PEAR::isError($error)) {
return $error;
}
} elseif ($arg == '-') {
// - is stdin
$non_opts = array_merge($non_opts, array_slice($args, $i));
break;
} else {
$error = Console_Getopt::_parseShortOption(substr($arg, 1),
$short_options,
$opts,
$args,
$skip_unknown);
if (PEAR::isError($error)) {
return $error;
}
}
}
return array($opts, $non_opts);
}
/**
* Parse short option
*
* @param string $arg Argument
* @param string[] $short_options Available short options
* @param string[][] &$opts
* @param string[] &$args
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return void
*/
protected static function _parseShortOption($arg, $short_options, &$opts, &$args, $skip_unknown)
{
for ($i = 0; $i < strlen($arg); $i++) {
$opt = $arg{$i};
$opt_arg = null;
/* Try to find the short option in the specifier string. */
if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') {
if ($skip_unknown === true) {
break;
}
$msg = "Console_Getopt: unrecognized option -- $opt";
return PEAR::raiseError($msg);
}
if (strlen($spec) > 1 && $spec{1} == ':') {
if (strlen($spec) > 2 && $spec{2} == ':') {
if ($i + 1 < strlen($arg)) {
/* Option takes an optional argument. Use the remainder of
the arg string if there is anything left. */
$opts[] = array($opt, substr($arg, $i + 1));
break;
}
} else {
/* Option requires an argument. Use the remainder of the arg
string if there is anything left. */
if ($i + 1 < strlen($arg)) {
$opts[] = array($opt, substr($arg, $i + 1));
break;
} else if (list(, $opt_arg) = each($args)) {
/* Else use the next argument. */;
if (Console_Getopt::_isShortOpt($opt_arg)
|| Console_Getopt::_isLongOpt($opt_arg)) {
$msg = "option requires an argument --$opt";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
} else {
$msg = "option requires an argument --$opt";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
}
}
$opts[] = array($opt, $opt_arg);
}
}
/**
* Checks if an argument is a short option
*
* @param string $arg Argument to check
*
* @return bool
*/
protected static function _isShortOpt($arg)
{
return strlen($arg) == 2 && $arg[0] == '-'
&& preg_match('/[a-zA-Z]/', $arg[1]);
}
/**
* Checks if an argument is a long option
*
* @param string $arg Argument to check
*
* @return bool
*/
protected static function _isLongOpt($arg)
{
return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
preg_match('/[a-zA-Z]+$/', substr($arg, 2));
}
/**
* Parse long option
*
* @param string $arg Argument
* @param string[] $long_options Available long options
* @param string[][] &$opts
* @param string[] &$args
*
* @return void|PEAR_Error
*/
protected static function _parseLongOption($arg, $long_options, &$opts, &$args, $skip_unknown)
{
@list($opt, $opt_arg) = explode('=', $arg, 2);
$opt_len = strlen($opt);
for ($i = 0; $i < count($long_options); $i++) {
$long_opt = $long_options[$i];
$opt_start = substr($long_opt, 0, $opt_len);
$long_opt_name = str_replace('=', '', $long_opt);
/* Option doesn't match. Go on to the next one. */
if ($long_opt_name != $opt) {
continue;
}
$opt_rest = substr($long_opt, $opt_len);
/* Check that the options uniquely matches one of the allowed
options. */
if ($i + 1 < count($long_options)) {
$next_option_rest = substr($long_options[$i + 1], $opt_len);
} else {
$next_option_rest = '';
}
if ($opt_rest != '' && $opt{0} != '=' &&
$i + 1 < count($long_options) &&
$opt == substr($long_options[$i+1], 0, $opt_len) &&
$next_option_rest != '' &&
$next_option_rest{0} != '=') {
$msg = "Console_Getopt: option --$opt is ambiguous";
return PEAR::raiseError($msg);
}
if (substr($long_opt, -1) == '=') {
if (substr($long_opt, -2) != '==') {
/* Long option requires an argument.
Take the next argument if one wasn't specified. */;
if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
$msg = "Console_Getopt: option requires an argument --$opt";
return PEAR::raiseError($msg);
}
if (Console_Getopt::_isShortOpt($opt_arg)
|| Console_Getopt::_isLongOpt($opt_arg)) {
$msg = "Console_Getopt: option requires an argument --$opt";
return PEAR::raiseError($msg);
}
}
} else if ($opt_arg) {
$msg = "Console_Getopt: option --$opt doesn't allow an argument";
return PEAR::raiseError($msg);
}
$opts[] = array('--' . $opt, $opt_arg);
return;
}
if ($skip_unknown === true) {
return;
}
return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
}
/**
* Safely read the $argv PHP array across different PHP configurations.
* Will take care on register_globals and register_argc_argv ini directives
*
* @return mixed the $argv PHP array or PEAR error if not registered
*/
public static function readPHPArgv()
{
global $argv;
if (!is_array($argv)) {
if (!@is_array($_SERVER['argv'])) {
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
$msg = "Could not read cmd args (register_argc_argv=Off?)";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
}
return $_SERVER['argv'];
}
return $argv;
}
}

337
vendor/pear-pear.php.net/PEAR/OS/Guess.php generated vendored Normal file
View file

@ -0,0 +1,337 @@
<?php
/**
* The OS_Guess class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since PEAR 0.1
*/
// {{{ uname examples
// php_uname() without args returns the same as 'uname -a', or a PHP-custom
// string for Windows.
// PHP versions prior to 4.3 return the uname of the host where PHP was built,
// as of 4.3 it returns the uname of the host running the PHP code.
//
// PC RedHat Linux 7.1:
// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
//
// PC Debian Potato:
// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
//
// PC FreeBSD 3.3:
// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.3:
// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5 w/uname from GNU shellutils:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
//
// HP 9000/712 HP-UX 10:
// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
//
// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
// HP-UX host B.10.10 A 9000/712 unknown
//
// IBM RS6000/550 AIX 4.3:
// AIX host 3 4 000003531C00
//
// AIX 4.3 w/uname from GNU shellutils:
// AIX host 3 4 000003531C00 unknown
//
// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
// IRIX64 host 6.5 01091820 IP19 mips
//
// SGI Onyx IRIX 6.5:
// IRIX64 host 6.5 01091820 IP19
//
// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
//
// SparcStation 20 Solaris 8:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
//
// Mac OS X (Darwin)
// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh
//
// Mac OS X early versions
//
// }}}
/* TODO:
* - define endianness, to allow matchSignature("bigend") etc.
*/
/**
* Retrieves information about the current operating system
*
* This class uses php_uname() to grok information about the current OS
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class OS_Guess
{
var $sysname;
var $nodename;
var $cpu;
var $release;
var $extra;
function __construct($uname = null)
{
list($this->sysname,
$this->release,
$this->cpu,
$this->extra,
$this->nodename) = $this->parseSignature($uname);
}
function parseSignature($uname = null)
{
static $sysmap = array(
'HP-UX' => 'hpux',
'IRIX64' => 'irix',
);
static $cpumap = array(
'i586' => 'i386',
'i686' => 'i386',
'ppc' => 'powerpc',
);
if ($uname === null) {
$uname = php_uname();
}
$parts = preg_split('/\s+/', trim($uname));
$n = count($parts);
$release = $machine = $cpu = '';
$sysname = $parts[0];
$nodename = $parts[1];
$cpu = $parts[$n-1];
$extra = '';
if ($cpu == 'unknown') {
$cpu = $parts[$n - 2];
}
switch ($sysname) {
case 'AIX' :
$release = "$parts[3].$parts[2]";
break;
case 'Windows' :
switch ($parts[1]) {
case '95/98':
$release = '9x';
break;
default:
$release = $parts[1];
break;
}
$cpu = 'i386';
break;
case 'Linux' :
$extra = $this->_detectGlibcVersion();
// use only the first two digits from the kernel version
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
case 'Mac' :
$sysname = 'darwin';
$nodename = $parts[2];
$release = $parts[3];
if ($cpu == 'Macintosh') {
if ($parts[$n - 2] == 'Power') {
$cpu = 'powerpc';
}
}
break;
case 'Darwin' :
if ($cpu == 'Macintosh') {
if ($parts[$n - 2] == 'Power') {
$cpu = 'powerpc';
}
}
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
default:
$release = preg_replace('/-.*/', '', $parts[2]);
break;
}
if (isset($sysmap[$sysname])) {
$sysname = $sysmap[$sysname];
} else {
$sysname = strtolower($sysname);
}
if (isset($cpumap[$cpu])) {
$cpu = $cpumap[$cpu];
}
return array($sysname, $release, $cpu, $extra, $nodename);
}
function _detectGlibcVersion()
{
static $glibc = false;
if ($glibc !== false) {
return $glibc; // no need to run this multiple times
}
$major = $minor = 0;
include_once "System.php";
// Use glibc's <features.h> header file to
// get major and minor version number:
if (@file_exists('/usr/include/features.h') &&
@is_readable('/usr/include/features.h')) {
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
$features_file = fopen('/usr/include/features.h', 'rb');
while (!feof($features_file)) {
$line = fgets($features_file, 8192);
if (!$line || (strpos($line, '#define') === false)) {
continue;
}
if (strpos($line, '__GLIBC__')) {
// major version number #define __GLIBC__ version
$line = preg_split('/\s+/', $line);
$glibc_major = trim($line[2]);
if (isset($glibc_minor)) {
break;
}
continue;
}
if (strpos($line, '__GLIBC_MINOR__')) {
// got the minor version number
// #define __GLIBC_MINOR__ version
$line = preg_split('/\s+/', $line);
$glibc_minor = trim($line[2]);
if (isset($glibc_major)) {
break;
}
continue;
}
}
fclose($features_file);
if (!isset($glibc_major) || !isset($glibc_minor)) {
return $glibc = '';
}
return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
} // no cpp
$tmpfile = System::mktemp("glibctest");
$fp = fopen($tmpfile, "w");
fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
fclose($fp);
$cpp = popen("/usr/bin/cpp $tmpfile", "r");
while ($line = fgets($cpp, 1024)) {
if ($line{0} == '#' || trim($line) == '') {
continue;
}
if (list($major, $minor) = explode(' ', trim($line))) {
break;
}
}
pclose($cpp);
unlink($tmpfile);
} // features.h
if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
// Let's try reading the libc.so.6 symlink
if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
list($major, $minor) = explode('.', $matches[1]);
}
}
if (!($major && $minor)) {
return $glibc = '';
}
return $glibc = "glibc{$major}.{$minor}";
}
function getSignature()
{
if (empty($this->extra)) {
return "{$this->sysname}-{$this->release}-{$this->cpu}";
}
return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
}
function getSysname()
{
return $this->sysname;
}
function getNodename()
{
return $this->nodename;
}
function getCpu()
{
return $this->cpu;
}
function getRelease()
{
return $this->release;
}
function getExtra()
{
return $this->extra;
}
function matchSignature($match)
{
$fragments = is_array($match) ? $match : explode('-', $match);
$n = count($fragments);
$matches = 0;
if ($n > 0) {
$matches += $this->_matchFragment($fragments[0], $this->sysname);
}
if ($n > 1) {
$matches += $this->_matchFragment($fragments[1], $this->release);
}
if ($n > 2) {
$matches += $this->_matchFragment($fragments[2], $this->cpu);
}
if ($n > 3) {
$matches += $this->_matchFragment($fragments[3], $this->extra);
}
return ($matches == $n);
}
function _matchFragment($fragment, $value)
{
if (strcspn($fragment, '*?') < strlen($fragment)) {
$reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
return preg_match($reg, $value);
}
return ($fragment == '*' || !strcasecmp($fragment, $value));
}
}
/*
* Local Variables:
* indent-tabs-mode: nil
* c-basic-offset: 4
* End:
*/

1113
vendor/pear-pear.php.net/PEAR/PEAR.php generated vendored Normal file

File diff suppressed because it is too large Load diff

499
vendor/pear-pear.php.net/PEAR/PEAR/Builder.php generated vendored Normal file
View file

@ -0,0 +1,499 @@
<?php
/**
* PEAR_Builder for building PHP extensions (PECL packages)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*
* TODO: log output parameters in PECL command line
* TODO: msdev path in configuration
*/
/**
* Needed for extending PEAR_Builder
*/
require_once 'PEAR/Common.php';
require_once 'PEAR/PackageFile.php';
require_once 'System.php';
/**
* Class to handle building (compiling) extensions.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since PHP 4.0.2
* @see http://pear.php.net/manual/en/core.ppm.pear-builder.php
*/
class PEAR_Builder extends PEAR_Common
{
var $php_api_version = 0;
var $zend_module_api_no = 0;
var $zend_extension_api_no = 0;
var $extensions_built = array();
/**
* @var string Used for reporting when it is not possible to pass function
* via extra parameter, e.g. log, msdevCallback
*/
var $current_callback = null;
// used for msdev builds
var $_lastline = null;
var $_firstline = null;
/**
* PEAR_Builder constructor.
*
* @param object $ui user interface object (instance of PEAR_Frontend_*)
*
* @access public
*/
function __construct(&$ui)
{
parent::__construct();
$this->setFrontendObject($ui);
}
/**
* Build an extension from source on windows.
* requires msdev
*/
function _build_win32($descfile, $callback = null)
{
if (is_object($descfile)) {
$pkg = $descfile;
$descfile = $pkg->getPackageFile();
} else {
$pf = new PEAR_PackageFile($this->config, $this->debug);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
}
$dir = dirname($descfile);
$old_cwd = getcwd();
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
return $this->raiseError("could not chdir to $dir");
}
// packages that were in a .tar have the packagefile in this directory
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
if (file_exists($dir) && is_dir($vdir)) {
if (!chdir($vdir)) {
return $this->raiseError("could not chdir to " . realpath($vdir));
}
$dir = getcwd();
}
$this->log(2, "building in $dir");
$dsp = $pkg->getPackage().'.dsp';
if (!file_exists("$dir/$dsp")) {
return $this->raiseError("The DSP $dsp does not exist.");
}
// XXX TODO: make release build type configurable
$command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"';
$err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
if (PEAR::isError($err)) {
return $err;
}
// figure out the build platform and type
$platform = 'Win32';
$buildtype = 'Release';
if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
$platform = $matches[1];
$buildtype = $matches[2];
}
if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) {
if ($matches[2]) {
// there were errors in the build
return $this->raiseError("There were errors during compilation.");
}
$out = $matches[1];
} else {
return $this->raiseError("Did not understand the completion status returned from msdev.exe.");
}
// msdev doesn't tell us the output directory :/
// open the dsp, find /out and use that directory
$dsptext = join(file($dsp),'');
// this regex depends on the build platform and type having been
// correctly identified above.
$regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
$pkg->getPackage().'\s-\s'.
$platform.'\s'.
$buildtype.'").*?'.
'\/out:"(.*?)"/is';
if ($dsptext && preg_match($regex, $dsptext, $matches)) {
// what we get back is a relative path to the output file itself.
$outfile = realpath($matches[2]);
} else {
return $this->raiseError("Could not retrieve output information from $dsp.");
}
// realpath returns false if the file doesn't exist
if ($outfile && copy($outfile, "$dir/$out")) {
$outfile = "$dir/$out";
}
$built_files[] = array(
'file' => "$outfile",
'php_api' => $this->php_api_version,
'zend_mod_api' => $this->zend_module_api_no,
'zend_ext_api' => $this->zend_extension_api_no,
);
return $built_files;
}
// }}}
// {{{ msdevCallback()
function msdevCallback($what, $data)
{
if (!$this->_firstline)
$this->_firstline = $data;
$this->_lastline = $data;
call_user_func($this->current_callback, $what, $data);
}
/**
* @param string
* @param string
* @param array
* @access private
*/
function _harvestInstDir($dest_prefix, $dirname, &$built_files)
{
$d = opendir($dirname);
if (!$d)
return false;
$ret = true;
while (($ent = readdir($d)) !== false) {
if ($ent{0} == '.')
continue;
$full = $dirname . DIRECTORY_SEPARATOR . $ent;
if (is_dir($full)) {
if (!$this->_harvestInstDir(
$dest_prefix . DIRECTORY_SEPARATOR . $ent,
$full, $built_files)) {
$ret = false;
break;
}
} else {
$dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent;
$built_files[] = array(
'file' => $full,
'dest' => $dest,
'php_api' => $this->php_api_version,
'zend_mod_api' => $this->zend_module_api_no,
'zend_ext_api' => $this->zend_extension_api_no,
);
}
}
closedir($d);
return $ret;
}
/**
* Build an extension from source. Runs "phpize" in the source
* directory, but compiles in a temporary directory
* (TMPDIR/pear-build-USER/PACKAGE-VERSION).
*
* @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
* a PEAR_PackageFile object
*
* @param mixed $callback callback function used to report output,
* see PEAR_Builder::_runCommand for details
*
* @return array an array of associative arrays with built files,
* format:
* array( array( 'file' => '/path/to/ext.so',
* 'php_api' => YYYYMMDD,
* 'zend_mod_api' => YYYYMMDD,
* 'zend_ext_api' => YYYYMMDD ),
* ... )
*
* @access public
*
* @see PEAR_Builder::_runCommand
*/
function build($descfile, $callback = null)
{
if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php([^\\/\\\\]+)?$/',
$this->config->get('php_bin'), $matches)) {
if (isset($matches[2]) && strlen($matches[2]) &&
trim($matches[2]) != trim($this->config->get('php_prefix'))) {
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
' appears to have a prefix ' . $matches[2] . ', but' .
' config variable php_prefix does not match');
}
if (isset($matches[3]) && strlen($matches[3]) &&
trim($matches[3]) != trim($this->config->get('php_suffix'))) {
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
' appears to have a suffix ' . $matches[3] . ', but' .
' config variable php_suffix does not match');
}
}
$this->current_callback = $callback;
if (PEAR_OS == "Windows") {
return $this->_build_win32($descfile, $callback);
}
if (PEAR_OS != 'Unix') {
return $this->raiseError("building extensions not supported on this platform");
}
if (is_object($descfile)) {
$pkg = $descfile;
$descfile = $pkg->getPackageFile();
if (is_a($pkg, 'PEAR_PackageFile_v1')) {
$dir = dirname($descfile);
} else {
$dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
// automatically delete at session end
$this->addTempFile($dir);
}
} else {
$pf = new PEAR_PackageFile($this->config);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
$dir = dirname($descfile);
}
// Find config. outside of normal path - e.g. config.m4
foreach (array_keys($pkg->getInstallationFileList()) as $item) {
if (stristr(basename($item), 'config.m4') && dirname($item) != '.') {
$dir .= DIRECTORY_SEPARATOR . dirname($item);
break;
}
}
$old_cwd = getcwd();
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
return $this->raiseError("could not chdir to $dir");
}
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
if (is_dir($vdir)) {
chdir($vdir);
}
$dir = getcwd();
$this->log(2, "building in $dir");
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
$err = $this->_runCommand($this->config->get('php_prefix')
. "phpize" .
$this->config->get('php_suffix'),
array(&$this, 'phpizeCallback'));
if (PEAR::isError($err)) {
return $err;
}
if (!$err) {
return $this->raiseError("`phpize' failed");
}
// {{{ start of interactive part
$configure_command = "$dir/configure";
$phpConfigName = $this->config->get('php_prefix')
. 'php-config'
. $this->config->get('php_suffix');
$phpConfigPath = System::which($phpConfigName);
if ($phpConfigPath !== false) {
$configure_command .= ' --with-php-config='
. $phpConfigPath;
}
$configure_options = $pkg->getConfigureOptions();
if ($configure_options) {
foreach ($configure_options as $o) {
$default = array_key_exists('default', $o) ? $o['default'] : null;
list($r) = $this->ui->userDialog('build',
array($o['prompt']),
array('text'),
array($default));
if (substr($o['name'], 0, 5) == 'with-' &&
($r == 'yes' || $r == 'autodetect')) {
$configure_command .= " --$o[name]";
} else {
$configure_command .= " --$o[name]=".trim($r);
}
}
}
// }}} end of interactive part
// FIXME make configurable
if (!$user=getenv('USER')) {
$user='defaultuser';
}
$tmpdir = $this->config->get('temp_dir');
$build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"');
$build_dir = "$build_basedir/$vdir";
$inst_dir = "$build_basedir/install-$vdir";
$this->log(1, "building in $build_dir");
if (is_dir($build_dir)) {
System::rm(array('-rf', $build_dir));
}
if (!System::mkDir(array('-p', $build_dir))) {
return $this->raiseError("could not create build dir: $build_dir");
}
$this->addTempFile($build_dir);
if (!System::mkDir(array('-p', $inst_dir))) {
return $this->raiseError("could not create temporary install dir: $inst_dir");
}
$this->addTempFile($inst_dir);
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
$to_run = array(
$configure_command,
$make_command,
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
"find \"$inst_dir\" | xargs ls -dils"
);
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
return $this->raiseError("could not chdir to $build_dir");
}
putenv('PHP_PEAR_VERSION=1.10.3');
foreach ($to_run as $cmd) {
$err = $this->_runCommand($cmd, $callback);
if (PEAR::isError($err)) {
chdir($old_cwd);
return $err;
}
if (!$err) {
chdir($old_cwd);
return $this->raiseError("`$cmd' failed");
}
}
if (!($dp = opendir("modules"))) {
chdir($old_cwd);
return $this->raiseError("no `modules' directory found");
}
$built_files = array();
$prefix = exec($this->config->get('php_prefix')
. "php-config" .
$this->config->get('php_suffix') . " --prefix");
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
chdir($old_cwd);
return $built_files;
}
/**
* Message callback function used when running the "phpize"
* program. Extracts the API numbers used. Ignores other message
* types than "cmdoutput".
*
* @param string $what the type of message
* @param mixed $data the message
*
* @return void
*
* @access public
*/
function phpizeCallback($what, $data)
{
if ($what != 'cmdoutput') {
return;
}
$this->log(1, rtrim($data));
if (preg_match('/You should update your .aclocal.m4/', $data)) {
return;
}
$matches = array();
if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) {
$member = preg_replace('/[^a-z]/', '_', strtolower($matches[1]));
$apino = (int)$matches[2];
if (isset($this->$member)) {
$this->$member = $apino;
//$msg = sprintf("%-22s : %d", $matches[1], $apino);
//$this->log(1, $msg);
}
}
}
/**
* Run an external command, using a message callback to report
* output. The command will be run through popen and output is
* reported for every line with a "cmdoutput" message with the
* line string, including newlines, as payload.
*
* @param string $command the command to run
*
* @param mixed $callback (optional) function to use as message
* callback
*
* @return bool whether the command was successful (exit code 0
* means success, any other means failure)
*
* @access private
*/
function _runCommand($command, $callback = null)
{
$this->log(1, "running: $command");
$pp = popen("$command 2>&1", "r");
if (!$pp) {
return $this->raiseError("failed to run `$command'");
}
if ($callback && $callback[0]->debug == 1) {
$olddbg = $callback[0]->debug;
$callback[0]->debug = 2;
}
while ($line = fgets($pp, 1024)) {
if ($callback) {
call_user_func($callback, 'cmdoutput', $line);
} else {
$this->log(2, rtrim($line));
}
}
if ($callback && isset($olddbg)) {
$callback[0]->debug = $olddbg;
}
$exitcode = is_resource($pp) ? pclose($pp) : -1;
return ($exitcode == 0);
}
function log($level, $msg, $append_crlf = true)
{
if ($this->current_callback) {
if ($this->debug >= $level) {
call_user_func($this->current_callback, 'output', $msg);
}
return;
}
return parent::log($level, $msg, $append_crlf);
}
}

1560
vendor/pear-pear.php.net/PEAR/PEAR/ChannelFile.php generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
<?php
/**
* PEAR_ChannelFile_Parser for parsing channel.xml
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* base xml parser class
*/
require_once 'PEAR/XMLParser.php';
require_once 'PEAR/ChannelFile.php';
/**
* Parser for channel.xml
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_ChannelFile_Parser extends PEAR_XMLParser
{
var $_config;
var $_logger;
var $_registry;
function setConfig(&$c)
{
$this->_config = &$c;
$this->_registry = &$c->getRegistry();
}
function setLogger(&$l)
{
$this->_logger = &$l;
}
function parse($data, $file)
{
if (PEAR::isError($err = parent::parse($data, $file))) {
return $err;
}
$ret = new PEAR_ChannelFile;
$ret->setConfig($this->_config);
if (isset($this->_logger)) {
$ret->setLogger($this->_logger);
}
$ret->fromArray($this->_unserializedData);
// make sure the filelist is in the easy to read format needed
$ret->flattenFilelist();
$ret->setPackagefile($file, $archive);
return $ret;
}
}

389
vendor/pear-pear.php.net/PEAR/PEAR/Command.php generated vendored Normal file
View file

@ -0,0 +1,389 @@
<?php
/**
* PEAR_Command, command pattern class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* Needed for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Frontend.php';
require_once 'PEAR/XMLParser.php';
/**
* List of commands and what classes they are implemented in.
* @var array command => implementing class
*/
$GLOBALS['_PEAR_Command_commandlist'] = array();
/**
* List of commands and their descriptions
* @var array command => description
*/
$GLOBALS['_PEAR_Command_commanddesc'] = array();
/**
* List of shortcuts to common commands.
* @var array shortcut => command
*/
$GLOBALS['_PEAR_Command_shortcuts'] = array();
/**
* Array of command objects
* @var array class => object
*/
$GLOBALS['_PEAR_Command_objects'] = array();
/**
* PEAR command class, a simple factory class for administrative
* commands.
*
* How to implement command classes:
*
* - The class must be called PEAR_Command_Nnn, installed in the
* "PEAR/Common" subdir, with a method called getCommands() that
* returns an array of the commands implemented by the class (see
* PEAR/Command/Install.php for an example).
*
* - The class must implement a run() function that is called with three
* params:
*
* (string) command name
* (array) assoc array with options, freely defined by each
* command, for example:
* array('force' => true)
* (array) list of the other parameters
*
* The run() function returns a PEAR_CommandResponse object. Use
* these methods to get information:
*
* int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
* *_PARTIAL means that you need to issue at least
* one more command to complete the operation
* (used for example for validation steps).
*
* string getMessage() Returns a message for the user. Remember,
* no HTML or other interface-specific markup.
*
* If something unexpected happens, run() returns a PEAR error.
*
* - DON'T OUTPUT ANYTHING! Return text for output instead.
*
* - DON'T USE HTML! The text you return will be used from both Gtk,
* web and command-line interfaces, so for now, keep everything to
* plain text.
*
* - DON'T USE EXIT OR DIE! Always use pear errors. From static
* classes do PEAR::raiseError(), from other classes do
* $this->raiseError().
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command
{
// {{{ factory()
/**
* Get the right object for executing a command.
*
* @param string $command The name of the command
* @param object $config Instance of PEAR_Config object
*
* @return object the command object or a PEAR error
*/
public static function &factory($command, &$config)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
$a = PEAR::raiseError("unknown command `$command'");
return $a;
}
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
if (!class_exists($class)) {
require_once $GLOBALS['_PEAR_Command_objects'][$class];
}
if (!class_exists($class)) {
$a = PEAR::raiseError("unknown command `$command'");
return $a;
}
$ui =& PEAR_Command::getFrontendObject();
$obj = new $class($ui, $config);
return $obj;
}
// }}}
// {{{ & getObject()
public static function &getObject($command)
{
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
if (!class_exists($class)) {
require_once $GLOBALS['_PEAR_Command_objects'][$class];
}
if (!class_exists($class)) {
return PEAR::raiseError("unknown command `$command'");
}
$ui =& PEAR_Command::getFrontendObject();
$config = &PEAR_Config::singleton();
$obj = new $class($ui, $config);
return $obj;
}
// }}}
// {{{ & getFrontendObject()
/**
* Get instance of frontend object.
*
* @return object|PEAR_Error
*/
public static function &getFrontendObject()
{
$a = &PEAR_Frontend::singleton();
return $a;
}
// }}}
// {{{ & setFrontendClass()
/**
* Load current frontend class.
*
* @param string $uiclass Name of class implementing the frontend
*
* @return object the frontend object, or a PEAR error
*/
public static function &setFrontendClass($uiclass)
{
$a = &PEAR_Frontend::setFrontendClass($uiclass);
return $a;
}
// }}}
// {{{ setFrontendType()
/**
* Set current frontend.
*
* @param string $uitype Name of the frontend type (for example "CLI")
*
* @return object the frontend object, or a PEAR error
*/
public static function setFrontendType($uitype)
{
$uiclass = 'PEAR_Frontend_' . $uitype;
return PEAR_Command::setFrontendClass($uiclass);
}
// }}}
// {{{ registerCommands()
/**
* Scan through the Command directory looking for classes
* and see what commands they implement.
*
* @param bool (optional) if FALSE (default), the new list of
* commands should replace the current one. If TRUE,
* new entries will be merged with old.
*
* @param string (optional) where (what directory) to look for
* classes, defaults to the Command subdirectory of
* the directory from where this file (__FILE__) is
* included.
*
* @return bool TRUE on success, a PEAR error on failure
*/
public static function registerCommands($merge = false, $dir = null)
{
$parser = new PEAR_XMLParser;
if ($dir === null) {
$dir = dirname(__FILE__) . '/Command';
}
if (!is_dir($dir)) {
return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
}
$dp = @opendir($dir);
if (empty($dp)) {
return PEAR::raiseError("registerCommands: opendir($dir) failed");
}
if (!$merge) {
$GLOBALS['_PEAR_Command_commandlist'] = array();
}
while ($file = readdir($dp)) {
if ($file{0} == '.' || substr($file, -4) != '.xml') {
continue;
}
$f = substr($file, 0, -4);
$class = "PEAR_Command_" . $f;
// List of commands
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
}
$parser->parse(file_get_contents("$dir/$file"));
$implements = $parser->getData();
foreach ($implements as $command => $desc) {
if ($command == 'attribs') {
continue;
}
if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
return PEAR::raiseError('Command "' . $command . '" already registered in ' .
'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
}
$GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
$GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
if (isset($desc['shortcut'])) {
$shortcut = $desc['shortcut'];
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
'registered to command "' . $command . '" in class "' .
$GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
}
$GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
}
if (isset($desc['options']) && $desc['options']) {
foreach ($desc['options'] as $oname => $option) {
if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
return PEAR::raiseError('Option "' . $oname . '" short option "' .
$option['shortopt'] . '" must be ' .
'only 1 character in Command "' . $command . '" in class "' .
$class . '"');
}
}
}
}
}
ksort($GLOBALS['_PEAR_Command_shortcuts']);
ksort($GLOBALS['_PEAR_Command_commandlist']);
@closedir($dp);
return true;
}
// }}}
// {{{ getCommands()
/**
* Get the list of currently supported commands, and what
* classes implement them.
*
* @return array command => implementing class
*/
public static function getCommands()
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
return $GLOBALS['_PEAR_Command_commandlist'];
}
// }}}
// {{{ getShortcuts()
/**
* Get the list of command shortcuts.
*
* @return array shortcut => command
*/
public static function getShortcuts()
{
if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
PEAR_Command::registerCommands();
}
return $GLOBALS['_PEAR_Command_shortcuts'];
}
// }}}
// {{{ getGetoptArgs()
/**
* Compiles arguments for getopt.
*
* @param string $command command to get optstring for
* @param string $short_args (reference) short getopt format
* @param array $long_args (reference) long getopt format
*
* @return void
*/
public static function getGetoptArgs($command, &$short_args, &$long_args)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
return null;
}
$obj = &PEAR_Command::getObject($command);
return $obj->getGetoptArgs($command, $short_args, $long_args);
}
// }}}
// {{{ getDescription()
/**
* Get description for a command.
*
* @param string $command Name of the command
*
* @return string command description
*/
public static function getDescription($command)
{
if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
return null;
}
return $GLOBALS['_PEAR_Command_commanddesc'][$command];
}
// }}}
// {{{ getHelp()
/**
* Get help for command.
*
* @param string $command Name of the command to return help for
*/
public static function getHelp($command)
{
$cmds = PEAR_Command::getCommands();
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (isset($cmds[$command])) {
$obj = &PEAR_Command::getObject($command);
return $obj->getHelp($command);
}
return false;
}
// }}}
}

80
vendor/pear-pear.php.net/PEAR/PEAR/Command/Auth.php generated vendored Normal file
View file

@ -0,0 +1,80 @@
<?php
/**
* PEAR_Command_Auth (login, logout commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
* @deprecated since 1.8.0alpha1
*/
/**
* base class
*/
require_once 'PEAR/Command/Channels.php';
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @deprecated since 1.8.0alpha1
*/
class PEAR_Command_Auth extends PEAR_Command_Channels
{
var $commands = array(
'login' => array(
'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
'shortcut' => 'li',
'function' => 'doLogin',
'options' => array(),
'doc' => '<channel name>
WARNING: This function is deprecated in favor of using channel-login
Log in to a remote channel server. If <channel name> is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.',
),
'logout' => array(
'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]',
'shortcut' => 'lo',
'function' => 'doLogout',
'options' => array(),
'doc' => '
WARNING: This function is deprecated in favor of using channel-logout
Logs out from the remote server. This command does not actually
connect to the remote server, it only deletes the stored username and
password from your user configuration.',
)
);
/**
* PEAR_Command_Auth constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
}

30
vendor/pear-pear.php.net/PEAR/PEAR/Command/Auth.xml generated vendored Normal file
View file

@ -0,0 +1,30 @@
<commands version="1.0">
<login>
<summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary>
<function>doLogin</function>
<shortcut>li</shortcut>
<options />
<doc>&lt;channel name&gt;
WARNING: This function is deprecated in favor of using channel-login
Log in to a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.</doc>
</login>
<logout>
<summary>Logs out from the remote server [Deprecated in favor of channel-logout]</summary>
<function>doLogout</function>
<shortcut>lo</shortcut>
<options />
<doc>
WARNING: This function is deprecated in favor of using channel-logout
Logs out from the remote server. This command does not actually
connect to the remote server, it only deletes the stored username and
password from your user configuration.</doc>
</logout>
</commands>

84
vendor/pear-pear.php.net/PEAR/PEAR/Command/Build.php generated vendored Normal file
View file

@ -0,0 +1,84 @@
<?php
/**
* PEAR_Command_Auth (build command)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
/**
* PEAR commands for building extensions.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Build extends PEAR_Command_Common
{
var $commands = array(
'build' => array(
'summary' => 'Build an Extension From C Source',
'function' => 'doBuild',
'shortcut' => 'b',
'options' => array(),
'doc' => '[package.xml]
Builds one or more extensions contained in a package.'
),
);
/**
* PEAR_Command_Build constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
function doBuild($command, $options, $params)
{
require_once 'PEAR/Builder.php';
if (sizeof($params) < 1) {
$params[0] = 'package.xml';
}
$builder = new PEAR_Builder($this->ui);
$this->debug = $this->config->get('verbose');
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
if (PEAR::isError($err)) {
return $err;
}
return true;
}
function buildCallback($what, $data)
{
if (($what == 'cmdoutput' && $this->debug > 1) ||
($what == 'output' && $this->debug > 0)) {
$this->ui->outputData(rtrim($data), 'build');
}
}
}

10
vendor/pear-pear.php.net/PEAR/PEAR/Command/Build.xml generated vendored Normal file
View file

@ -0,0 +1,10 @@
<commands version="1.0">
<build>
<summary>Build an Extension From C Source</summary>
<function>doBuild</function>
<shortcut>b</shortcut>
<options />
<doc>[package.xml]
Builds one or more extensions contained in a package.</doc>
</build>
</commands>

882
vendor/pear-pear.php.net/PEAR/PEAR/Command/Channels.php generated vendored Normal file
View file

@ -0,0 +1,882 @@
<?php
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
* channel-update, channel-info, channel-alias, channel-discover commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500);
/**
* PEAR commands for managing channels.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Command_Channels extends PEAR_Command_Common
{
var $commands = array(
'list-channels' => array(
'summary' => 'List Available Channels',
'function' => 'doList',
'shortcut' => 'lc',
'options' => array(),
'doc' => '
List all available channels for installation.
',
),
'update-channels' => array(
'summary' => 'Update the Channel List',
'function' => 'doUpdateAll',
'shortcut' => 'uc',
'options' => array(),
'doc' => '
List all installed packages in all channels.
'
),
'channel-delete' => array(
'summary' => 'Remove a Channel From the List',
'function' => 'doDelete',
'shortcut' => 'cde',
'options' => array(),
'doc' => '<channel name>
Delete a channel from the registry. You may not
remove any channel that has installed packages.
'
),
'channel-add' => array(
'summary' => 'Add a Channel',
'function' => 'doAdd',
'shortcut' => 'ca',
'options' => array(),
'doc' => '<channel.xml>
Add a private channel to the channel list. Note that all
public channels should be synced using "update-channels".
Parameter may be either a local file or remote URL to a
channel.xml.
'
),
'channel-update' => array(
'summary' => 'Update an Existing Channel',
'function' => 'doUpdate',
'shortcut' => 'cu',
'options' => array(
'force' => array(
'shortopt' => 'f',
'doc' => 'will force download of new channel.xml if an existing channel name is used',
),
'channel' => array(
'shortopt' => 'c',
'arg' => 'CHANNEL',
'doc' => 'will force download of new channel.xml if an existing channel name is used',
),
),
'doc' => '[<channel.xml>|<channel name>]
Update a channel in the channel list directly. Note that all
public channels can be synced using "update-channels".
Parameter may be a local or remote channel.xml, or the name of
an existing channel.
'
),
'channel-info' => array(
'summary' => 'Retrieve Information on a Channel',
'function' => 'doInfo',
'shortcut' => 'ci',
'options' => array(),
'doc' => '<package>
List the files in an installed package.
'
),
'channel-alias' => array(
'summary' => 'Specify an alias to a channel name',
'function' => 'doAlias',
'shortcut' => 'cha',
'options' => array(),
'doc' => '<channel> <alias>
Specify a specific alias to use for a channel name.
The alias may not be an existing channel name or
alias.
'
),
'channel-discover' => array(
'summary' => 'Initialize a Channel from its server',
'function' => 'doDiscover',
'shortcut' => 'di',
'options' => array(),
'doc' => '[<channel.xml>|<channel name>]
Initialize a channel from its server and create a local channel.xml.
If <channel name> is in the format "<username>:<password>@<channel>" then
<username> and <password> will be set as the login username/password for
<channel>. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system\'s process list.
'
),
'channel-login' => array(
'summary' => 'Connects and authenticates to remote channel server',
'shortcut' => 'cli',
'function' => 'doLogin',
'options' => array(),
'doc' => '<channel name>
Log in to a remote channel server. If <channel name> is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.',
),
'channel-logout' => array(
'summary' => 'Logs out from the remote channel server',
'shortcut' => 'clo',
'function' => 'doLogout',
'options' => array(),
'doc' => '<channel name>
Logs out from a remote channel server. If <channel name> is not supplied,
the default channel is used. This command does not actually connect to the
remote server, it only deletes the stored username and password from your user
configuration.',
),
);
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
function _sortChannels($a, $b)
{
return strnatcasecmp($a->getName(), $b->getName());
}
function doList($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$registered = $reg->getChannels();
usort($registered, array(&$this, '_sortchannels'));
$i = $j = 0;
$data = array(
'caption' => 'Registered Channels:',
'border' => true,
'headline' => array('Channel', 'Alias', 'Summary')
);
foreach ($registered as $channel) {
$data['data'][] = array($channel->getName(),
$channel->getAlias(),
$channel->getSummary());
}
if (count($registered) === 0) {
$data = '(no registered channels)';
}
$this->ui->outputData($data, $command);
return true;
}
function doUpdateAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channels = $reg->getChannels();
$success = true;
foreach ($channels as $channel) {
if ($channel->getName() != '__uri') {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doUpdate('channel-update',
$options,
array($channel->getName()));
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
$success = false;
} else {
$success &= $err;
}
}
}
return $success;
}
function doInfo($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError("No channel specified");
}
$reg = &$this->config->getRegistry();
$channel = strtolower($params[0]);
if ($reg->channelExists($channel)) {
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
} else {
if (strpos($channel, '://')) {
$downloader = &$this->getDownloader();
$tmpdir = $this->config->get('temp_dir');
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('Cannot open "' . $channel .
'" (' . $loc->getMessage() . ')');
} else {
$contents = implode('', file($loc));
}
} else {
if (!file_exists($params[0])) {
return $this->raiseError('Unknown channel "' . $channel . '"');
}
$fp = fopen($params[0], 'r');
if (!$fp) {
return $this->raiseError('Cannot open "' . $params[0] . '"');
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$chan = new PEAR_ChannelFile;
$chan->fromXmlString($contents);
$chan->validate();
if ($errs = $chan->getErrors(true)) {
foreach ($errs as $err) {
$this->ui->outputData($err['level'] . ': ' . $err['message']);
}
return $this->raiseError('Channel file "' . $params[0] . '" is not valid');
}
}
if (!$chan) {
return $this->raiseError('Serious error: Channel "' . $params[0] .
'" has a corrupted registry entry');
}
$channel = $chan->getName();
$caption = 'Channel ' . $channel . ' Information:';
$data1 = array(
'caption' => $caption,
'border' => true);
$data1['data']['server'] = array('Name and Server', $chan->getName());
if ($chan->getAlias() != $chan->getName()) {
$data1['data']['alias'] = array('Alias', $chan->getAlias());
}
$data1['data']['summary'] = array('Summary', $chan->getSummary());
$validate = $chan->getValidationPackage();
$data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']);
$data1['data']['vpackageversion'] =
array('Validation Package Version', $validate['attribs']['version']);
$d = array();
$d['main'] = $data1;
$data['data'] = array();
$data['caption'] = 'Server Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
if ($chan->supportsREST()) {
if ($chan->supportsREST()) {
$funcs = $chan->getFunctions('rest');
if (!isset($funcs[0])) {
$funcs = array($funcs);
}
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
}
}
} else {
$data['data'][] = array('No supported protocols');
}
$d['protocols'] = $data;
$data['data'] = array();
$mirrors = $chan->getMirrors();
if ($mirrors) {
$data['caption'] = 'Channel ' . $channel . ' Mirrors:';
unset($data['headline']);
foreach ($mirrors as $mirror) {
$data['data'][] = array($mirror['attribs']['host']);
$d['mirrors'] = $data;
}
foreach ($mirrors as $i => $mirror) {
$data['data'] = array();
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
if ($chan->supportsREST($mirror['attribs']['host'])) {
if ($chan->supportsREST($mirror['attribs']['host'])) {
$funcs = $chan->getFunctions('rest', $mirror['attribs']['host']);
if (!isset($funcs[0])) {
$funcs = array($funcs);
}
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
}
}
} else {
$data['data'][] = array('No supported protocols');
}
$d['mirrorprotocols' . $i] = $data;
}
}
$this->ui->outputData($d, 'channel-info');
}
// }}}
function doDelete($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError('channel-delete: no channel specified');
}
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($params[0])) {
return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist');
}
$channel = $reg->channelName($params[0]);
if ($channel == 'pear.php.net') {
return $this->raiseError('Cannot delete the pear.php.net channel');
}
if ($channel == 'pecl.php.net') {
return $this->raiseError('Cannot delete the pecl.php.net channel');
}
if ($channel == 'doc.php.net') {
return $this->raiseError('Cannot delete the doc.php.net channel');
}
if ($channel == '__uri') {
return $this->raiseError('Cannot delete the __uri pseudo-channel');
}
if (PEAR::isError($err = $reg->listPackages($channel))) {
return $err;
}
if (count($err)) {
return $this->raiseError('Channel "' . $channel .
'" has installed packages, cannot delete');
}
if (!$reg->deleteChannel($channel)) {
return $this->raiseError('Channel "' . $channel . '" deletion failed');
} else {
$this->config->deleteChannel($channel);
$this->ui->outputData('Channel "' . $channel . '" deleted', $command);
}
}
function doAdd($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError('channel-add: no channel file specified');
}
if (strpos($params[0], '://')) {
$downloader = &$this->getDownloader();
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('channel-add: Cannot open "' . $params[0] .
'" (' . $loc->getMessage() . ')');
}
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
} else {
$lastmodified = $fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError('channel-add: cannot open "' . $params[0] . '"');
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$result = $channel->fromXmlString($contents);
PEAR::staticPopErrorHandling();
if (!$result) {
$exit = false;
if (count($errors = $channel->getErrors(true))) {
foreach ($errors as $error) {
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
if (!$exit) {
$exit = $error['level'] == 'error' ? true : false;
}
}
if ($exit) {
return $this->raiseError('channel-add: invalid channel.xml file');
}
}
}
$reg = &$this->config->getRegistry();
if ($reg->channelExists($channel->getName())) {
return $this->raiseError('channel-add: Channel "' . $channel->getName() .
'" exists, use channel-update to update entry', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
}
$ret = $reg->addChannel($channel, $lastmodified);
if (PEAR::isError($ret)) {
return $ret;
}
if (!$ret) {
return $this->raiseError('channel-add: adding Channel "' . $channel->getName() .
'" to registry failed');
}
$this->config->setChannels($reg->listChannels());
$this->config->writeConfigFile();
$this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command);
}
function doUpdate($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError("No channel file specified");
}
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
$reg = &$this->config->getRegistry();
$lastmodified = false;
if ((!file_exists($params[0]) || is_dir($params[0]))
&& $reg->channelExists(strtolower($params[0]))) {
$c = $reg->getChannel(strtolower($params[0]));
if (PEAR::isError($c)) {
return $this->raiseError($c);
}
$this->ui->outputData("Updating channel \"$params[0]\"", $command);
$dl = &$this->getDownloader(array());
// if force is specified, use a timestamp of "1" to force retrieval
$lastmodified = isset($options['force']) ? false : $c->lastModified();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
// Attempt to fall back to https
$this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage());
$this->ui->outputData("Trying channel \"$params[0]\" over https:// instead");
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('https://' . $c->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
return $this->raiseError('Cannot retrieve channel.xml for channel "' .
$c->getName() . '" (' . $contents->getMessage() . ')');
}
}
list($contents, $lastmodified) = $contents;
if (!$contents) {
$this->ui->outputData("Channel \"$params[0]\" is up to date");
return;
}
$contents = implode('', file($contents));
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
$channel->fromXmlString($contents);
if (!$channel->getErrors()) {
// security check: is the downloaded file for the channel we got it from?
if (strtolower($channel->getName()) != strtolower($c->getName())) {
if (!isset($options['force'])) {
return $this->raiseError('ERROR: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
}
$this->ui->log(0, 'WARNING: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
}
}
} else {
if (strpos($params[0], '://')) {
$dl = &$this->getDownloader();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $dl->downloadHttp($params[0],
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError("Cannot open " . $params[0] .
' (' . $loc->getMessage() . ')');
}
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
} else {
$fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError("Cannot open " . $params[0]);
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
$channel->fromXmlString($contents);
}
$exit = false;
if (count($errors = $channel->getErrors(true))) {
foreach ($errors as $error) {
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
if (!$exit) {
$exit = $error['level'] == 'error' ? true : false;
}
}
if ($exit) {
return $this->raiseError('Invalid channel.xml file');
}
}
if (!$reg->channelExists($channel->getName())) {
return $this->raiseError('Error: Channel "' . $channel->getName() .
'" does not exist, use channel-add to add an entry');
}
$ret = $reg->updateChannel($channel, $lastmodified);
if (PEAR::isError($ret)) {
return $ret;
}
if (!$ret) {
return $this->raiseError('Updating Channel "' . $channel->getName() .
'" in registry failed');
}
$this->config->setChannels($reg->listChannels());
$this->config->writeConfigFile();
$this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded');
}
function &getDownloader()
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = new PEAR_Downloader($this->ui, array(), $this->config);
return $a;
}
function doAlias($command, $options, $params)
{
if (count($params) === 1) {
return $this->raiseError('No channel alias specified');
}
if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
return $this->raiseError(
'Invalid format, correct is: channel-alias channel alias');
}
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($params[0], true)) {
$extra = '';
if ($reg->isAlias($params[0])) {
$extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' .
strtolower($params[1]) . '")';
}
return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra);
}
if ($reg->isAlias($params[1])) {
return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' .
'already aliased to "' . strtolower($params[1]) . '", cannot re-alias');
}
$chan = $reg->getChannel($params[0]);
if (PEAR::isError($chan)) {
return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] .
'" information (' . $chan->getMessage() . ')');
}
// make it a local alias
if (!$chan->setAlias(strtolower($params[1]), true)) {
return $this->raiseError('Alias "' . strtolower($params[1]) .
'" is not a valid channel alias');
}
$reg->updateChannel($chan);
$this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' .
strtolower($params[1]) . '"');
}
/**
* The channel-discover command
*
* @param string $command command name
* @param array $options option_name => value
* @param array $params list of additional parameters.
* $params[0] should contain a string with either:
* - <channel name> or
* - <username>:<password>@<channel name>
* @return null|PEAR_Error
*/
function doDiscover($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError("No channel server specified");
}
// Look for the possible input format "<username>:<password>@<channel>"
if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) {
$username = $matches[1];
$password = $matches[2];
$channel = $matches[3];
} else {
$channel = $params[0];
}
$reg = &$this->config->getRegistry();
if ($reg->channelExists($channel)) {
if (!$reg->isAlias($channel)) {
return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
}
return $this->raiseError("A channel alias named \"$channel\" " .
'already exists, aliasing channel "' . $reg->channelName($channel)
. '"');
}
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) {
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
$err->getMessage() . ')');
}
// Attempt fetch via https
$this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage());
$this->ui->outputData("Trying to discover channel $channel over https:// instead");
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
$err->getMessage() . ')');
}
}
// Store username/password if they were given
// Arguably we should do a logintest on the channel here, but since
// that's awkward on a REST-based channel (even "pear login" doesn't
// do it for those), and XML-RPC is deprecated, it's fairly pointless.
if (isset($username)) {
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
$this->config->store();
$this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command);
}
$this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command);
}
/**
* Execute the 'login' command.
*
* @param string $command command name
* @param array $options option_name => value
* @param array $params list of additional parameters
*
* @return bool TRUE on success or
* a PEAR error on failure
*
* @access public
*/
function doLogin($command, $options, $params)
{
$reg = &$this->config->getRegistry();
// If a parameter is supplied, use that as the channel to log in to
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror', null, $channel);
$username = $this->config->get('username', null, $channel);
if (empty($username)) {
$username = isset($_ENV['USER']) ? $_ENV['USER'] : null;
}
$this->ui->outputData("Logging in to $server.", $command);
list($username, $password) = $this->ui->userDialog(
$command,
array('Username', 'Password'),
array('text', 'password'),
array($username, '')
);
$username = trim($username);
$password = trim($password);
$ourfile = $this->config->getConfFile('user');
if (!$ourfile) {
$ourfile = $this->config->getConfFile('system');
}
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
if ($chan->supportsREST()) {
$ok = true;
}
if ($ok !== true) {
return $this->raiseError('Login failed!');
}
$this->ui->outputData("Logged in.", $command);
// avoid changing any temporary settings changed with -d
$ourconfig = new PEAR_Config($ourfile, $ourfile);
$ourconfig->set('username', $username, 'user', $channel);
$ourconfig->set('password', $password, 'user', $channel);
$ourconfig->store();
return true;
}
/**
* Execute the 'logout' command.
*
* @param string $command command name
* @param array $options option_name => value
* @param array $params list of additional parameters
*
* @return bool TRUE on success or
* a PEAR error on failure
*
* @access public
*/
function doLogout($command, $options, $params)
{
$reg = &$this->config->getRegistry();
// If a parameter is supplied, use that as the channel to log in to
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror', null, $channel);
$this->ui->outputData("Logging out from $server.", $command);
$this->config->remove('username', 'user', $channel);
$this->config->remove('password', 'user', $channel);
$this->config->store();
return true;
}
}

123
vendor/pear-pear.php.net/PEAR/PEAR/Command/Channels.xml generated vendored Normal file
View file

@ -0,0 +1,123 @@
<commands version="1.0">
<list-channels>
<summary>List Available Channels</summary>
<function>doList</function>
<shortcut>lc</shortcut>
<options />
<doc>
List all available channels for installation.
</doc>
</list-channels>
<update-channels>
<summary>Update the Channel List</summary>
<function>doUpdateAll</function>
<shortcut>uc</shortcut>
<options />
<doc>
List all installed packages in all channels.
</doc>
</update-channels>
<channel-delete>
<summary>Remove a Channel From the List</summary>
<function>doDelete</function>
<shortcut>cde</shortcut>
<options />
<doc>&lt;channel name&gt;
Delete a channel from the registry. You may not
remove any channel that has installed packages.
</doc>
</channel-delete>
<channel-add>
<summary>Add a Channel</summary>
<function>doAdd</function>
<shortcut>ca</shortcut>
<options />
<doc>&lt;channel.xml&gt;
Add a private channel to the channel list. Note that all
public channels should be synced using &quot;update-channels&quot;.
Parameter may be either a local file or remote URL to a
channel.xml.
</doc>
</channel-add>
<channel-update>
<summary>Update an Existing Channel</summary>
<function>doUpdate</function>
<shortcut>cu</shortcut>
<options>
<force>
<shortopt>f</shortopt>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
</force>
<channel>
<shortopt>c</shortopt>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
<arg>CHANNEL</arg>
</channel>
</options>
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Update a channel in the channel list directly. Note that all
public channels can be synced using &quot;update-channels&quot;.
Parameter may be a local or remote channel.xml, or the name of
an existing channel.
</doc>
</channel-update>
<channel-info>
<summary>Retrieve Information on a Channel</summary>
<function>doInfo</function>
<shortcut>ci</shortcut>
<options />
<doc>&lt;package&gt;
List the files in an installed package.
</doc>
</channel-info>
<channel-alias>
<summary>Specify an alias to a channel name</summary>
<function>doAlias</function>
<shortcut>cha</shortcut>
<options />
<doc>&lt;channel&gt; &lt;alias&gt;
Specify a specific alias to use for a channel name.
The alias may not be an existing channel name or
alias.
</doc>
</channel-alias>
<channel-discover>
<summary>Initialize a Channel from its server</summary>
<function>doDiscover</function>
<shortcut>di</shortcut>
<options />
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Initialize a channel from its server and create a local channel.xml.
If &lt;channel name&gt; is in the format &quot;&lt;username&gt;:&lt;password&gt;@&lt;channel&gt;&quot; then
&lt;username&gt; and &lt;password&gt; will be set as the login username/password for
&lt;channel&gt;. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system&#039;s process list.
</doc>
</channel-discover>
<channel-login>
<summary>Connects and authenticates to remote channel server</summary>
<function>doLogin</function>
<shortcut>cli</shortcut>
<options />
<doc>&lt;channel name&gt;
Log in to a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.</doc>
</channel-login>
<channel-logout>
<summary>Logs out from the remote channel server</summary>
<function>doLogout</function>
<shortcut>clo</shortcut>
<options />
<doc>&lt;channel name&gt;
Logs out from a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. This command does not actually connect to the
remote server, it only deletes the stored username and password from your user
configuration.</doc>
</channel-logout>
</commands>

272
vendor/pear-pear.php.net/PEAR/PEAR/Command/Common.php generated vendored Normal file
View file

@ -0,0 +1,272 @@
<?php
/**
* PEAR_Command_Common base class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR.php';
/**
* PEAR commands base class
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Common extends PEAR
{
/**
* PEAR_Config object used to pass user system and configuration
* on when executing commands
*
* @var PEAR_Config
*/
var $config;
/**
* @var PEAR_Registry
* @access protected
*/
var $_registry;
/**
* User Interface object, for all interaction with the user.
* @var object
*/
var $ui;
var $_deps_rel_trans = array(
'lt' => '<',
'le' => '<=',
'eq' => '=',
'ne' => '!=',
'gt' => '>',
'ge' => '>=',
'has' => '=='
);
var $_deps_type_trans = array(
'pkg' => 'package',
'ext' => 'extension',
'php' => 'PHP',
'prog' => 'external program',
'ldlib' => 'external library for linking',
'rtlib' => 'external runtime library',
'os' => 'operating system',
'websrv' => 'web server',
'sapi' => 'SAPI backend'
);
/**
* PEAR_Command_Common constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct();
$this->config = &$config;
$this->ui = &$ui;
}
/**
* Return a list of all the commands defined by this class.
* @return array list of commands
* @access public
*/
function getCommands()
{
$ret = array();
foreach (array_keys($this->commands) as $command) {
$ret[$command] = $this->commands[$command]['summary'];
}
return $ret;
}
/**
* Return a list of all the command shortcuts defined by this class.
* @return array shortcut => command
* @access public
*/
function getShortcuts()
{
$ret = array();
foreach (array_keys($this->commands) as $command) {
if (isset($this->commands[$command]['shortcut'])) {
$ret[$this->commands[$command]['shortcut']] = $command;
}
}
return $ret;
}
function getOptions($command)
{
$shortcuts = $this->getShortcuts();
if (isset($shortcuts[$command])) {
$command = $shortcuts[$command];
}
if (isset($this->commands[$command]) &&
isset($this->commands[$command]['options'])) {
return $this->commands[$command]['options'];
}
return null;
}
function getGetoptArgs($command, &$short_args, &$long_args)
{
$short_args = '';
$long_args = array();
if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) {
return;
}
reset($this->commands[$command]['options']);
while (list($option, $info) = each($this->commands[$command]['options'])) {
$larg = $sarg = '';
if (isset($info['arg'])) {
if ($info['arg']{0} == '(') {
$larg = '==';
$sarg = '::';
$arg = substr($info['arg'], 1, -1);
} else {
$larg = '=';
$sarg = ':';
$arg = $info['arg'];
}
}
if (isset($info['shortopt'])) {
$short_args .= $info['shortopt'] . $sarg;
}
$long_args[] = $option . $larg;
}
}
/**
* Returns the help message for the given command
*
* @param string $command The command
* @return mixed A fail string if the command does not have help or
* a two elements array containing [0]=>help string,
* [1]=> help string for the accepted cmd args
*/
function getHelp($command)
{
$config = &PEAR_Config::singleton();
if (!isset($this->commands[$command])) {
return "No such command \"$command\"";
}
$help = null;
if (isset($this->commands[$command]['doc'])) {
$help = $this->commands[$command]['doc'];
}
if (empty($help)) {
// XXX (cox) Fallback to summary if there is no doc (show both?)
if (!isset($this->commands[$command]['summary'])) {
return "No help for command \"$command\"";
}
$help = $this->commands[$command]['summary'];
}
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
foreach($matches[0] as $k => $v) {
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
}
}
return array($help, $this->getHelpArgs($command));
}
/**
* Returns the help for the accepted arguments of a command
*
* @param string $command
* @return string The help string
*/
function getHelpArgs($command)
{
if (isset($this->commands[$command]['options']) &&
count($this->commands[$command]['options']))
{
$help = "Options:\n";
foreach ($this->commands[$command]['options'] as $k => $v) {
if (isset($v['arg'])) {
if ($v['arg'][0] == '(') {
$arg = substr($v['arg'], 1, -1);
$sapp = " [$arg]";
$lapp = "[=$arg]";
} else {
$sapp = " $v[arg]";
$lapp = "=$v[arg]";
}
} else {
$sapp = $lapp = "";
}
if (isset($v['shortopt'])) {
$s = $v['shortopt'];
$help .= " -$s$sapp, --$k$lapp\n";
} else {
$help .= " --$k$lapp\n";
}
$p = " ";
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
$help .= " $doc\n";
}
return $help;
}
return null;
}
function run($command, $options, $params)
{
if (empty($this->commands[$command]['function'])) {
// look for shortcuts
foreach (array_keys($this->commands) as $cmd) {
if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) {
if (empty($this->commands[$cmd]['function'])) {
return $this->raiseError("unknown command `$command'");
} else {
$func = $this->commands[$cmd]['function'];
}
$command = $cmd;
//$command = $this->commands[$cmd]['function'];
break;
}
}
} else {
$func = $this->commands[$command]['function'];
}
return $this->$func($command, $options, $params);
}
}

414
vendor/pear-pear.php.net/PEAR/PEAR/Command/Config.php generated vendored Normal file
View file

@ -0,0 +1,414 @@
<?php
/**
* PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
/**
* PEAR commands for managing configuration data.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Config extends PEAR_Command_Common
{
var $commands = array(
'config-show' => array(
'summary' => 'Show All Settings',
'function' => 'doConfigShow',
'shortcut' => 'csh',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '[layer]
Displays all configuration values. An optional argument
may be used to tell which configuration layer to display. Valid
configuration layers are "user", "system" and "default". To display
configurations for different channels, set the default_channel
configuration variable and run config-show again.
',
),
'config-get' => array(
'summary' => 'Show One Setting',
'function' => 'doConfigGet',
'shortcut' => 'cg',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '<parameter> [layer]
Displays the value of one configuration parameter. The
first argument is the name of the parameter, an optional second argument
may be used to tell which configuration layer to look in. Valid configuration
layers are "user", "system" and "default". If no layer is specified, a value
will be picked from the first layer that defines the parameter, in the order
just specified. The configuration value will be retrieved for the channel
specified by the default_channel configuration variable.
',
),
'config-set' => array(
'summary' => 'Change Setting',
'function' => 'doConfigSet',
'shortcut' => 'cs',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '<parameter> <value> [layer]
Sets the value of one configuration parameter. The first argument is
the name of the parameter, the second argument is the new value. Some
parameters are subject to validation, and the command will fail with
an error message if the new value does not make sense. An optional
third argument may be used to specify in which layer to set the
configuration parameter. The default layer is "user". The
configuration value will be set for the current channel, which
is controlled by the default_channel configuration variable.
',
),
'config-help' => array(
'summary' => 'Show Information About Setting',
'function' => 'doConfigHelp',
'shortcut' => 'ch',
'options' => array(),
'doc' => '[parameter]
Displays help for a configuration parameter. Without arguments it
displays help for all configuration parameters.
',
),
'config-create' => array(
'summary' => 'Create a Default configuration file',
'function' => 'doConfigCreate',
'shortcut' => 'coc',
'options' => array(
'windows' => array(
'shortopt' => 'w',
'doc' => 'create a config file for a windows install',
),
),
'doc' => '<root path> <filename>
Create a default configuration file with all directory configuration
variables set to subdirectories of <root path>, and save it as <filename>.
This is useful especially for creating a configuration file for a remote
PEAR installation (using the --remoteconfig option of install, upgrade,
and uninstall).
',
),
);
/**
* PEAR_Command_Config constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
function doConfigShow($command, $options, $params)
{
$layer = null;
if (is_array($params)) {
$layer = isset($params[0]) ? $params[0] : null;
}
// $params[0] -> the layer
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-show:$error");
}
$keys = $this->config->getKeys();
sort($keys);
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$channel = $reg->channelName($channel);
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
foreach ($keys as $key) {
$type = $this->config->getType($key);
$value = $this->config->get($key, $layer, $channel);
if ($type == 'password' && $value) {
$value = '********';
}
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
$value = 'true';
}
$data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value);
}
foreach ($this->config->getLayers() as $layer) {
$data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer));
}
$this->ui->outputData($data, $command);
return true;
}
function doConfigGet($command, $options, $params)
{
$args_cnt = is_array($params) ? count($params) : 0;
switch ($args_cnt) {
case 1:
$config_key = $params[0];
$layer = null;
break;
case 2:
$config_key = $params[0];
$layer = $params[1];
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-get:$error");
}
break;
case 0:
default:
return $this->raiseError("config-get expects 1 or 2 parameters");
}
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$channel = $reg->channelName($channel);
$this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
return true;
}
function doConfigSet($command, $options, $params)
{
// $param[0] -> a parameter to set
// $param[1] -> the value for the parameter
// $param[2] -> the layer
$failmsg = '';
if (count($params) < 2 || count($params) > 3) {
$failmsg .= "config-set expects 2 or 3 parameters";
return PEAR::raiseError($failmsg);
}
if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
$failmsg .= $error;
return PEAR::raiseError("config-set:$failmsg");
}
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$channel = $reg->channelName($channel);
if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) {
return $this->raiseError('Channel "' . $params[1] . '" does not exist');
}
if ($params[0] == 'preferred_mirror'
&& (
!$reg->mirrorExists($channel, $params[1]) &&
(!$reg->channelExists($params[1]) || $channel != $params[1])
)
) {
$msg = 'Channel Mirror "' . $params[1] . '" does not exist';
$msg .= ' in your registry for channel "' . $channel . '".';
$msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"';
$msg .= ' if you believe this mirror should exist as you may';
$msg .= ' have outdated channel information.';
return $this->raiseError($msg);
}
if (count($params) == 2) {
array_push($params, 'user');
$layer = 'user';
} else {
$layer = $params[2];
}
array_push($params, $channel);
if (!call_user_func_array(array(&$this->config, 'set'), $params)) {
array_pop($params);
$failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel";
} else {
$this->config->store($layer);
}
if ($failmsg) {
return $this->raiseError($failmsg);
}
$this->ui->outputData('config-set succeeded', $command);
return true;
}
function doConfigHelp($command, $options, $params)
{
if (empty($params)) {
$params = $this->config->getKeys();
}
$data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
$data['headline'] = array('Name', 'Type', 'Description');
$data['border'] = true;
foreach ($params as $name) {
$type = $this->config->getType($name);
$docs = $this->config->getDocs($name);
if ($type == 'set') {
$docs = rtrim($docs) . "\nValid set: " .
implode(' ', $this->config->getSetValues($name));
}
$data['data'][] = array($name, $type, $docs);
}
$this->ui->outputData($data, $command);
}
function doConfigCreate($command, $options, $params)
{
if (count($params) != 2) {
return PEAR::raiseError('config-create: must have 2 parameters, root path and ' .
'filename to save as');
}
$root = $params[0];
// Clean up the DIRECTORY_SEPARATOR mess
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
$root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"),
array('/', '/', '/'),
$root);
if ($root{0} != '/') {
if (!isset($options['windows'])) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "/", was: "' . $root . '"');
}
if (!preg_match('/^[A-Za-z]:/', $root)) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "\\" or "C:\\", was: "' . $root . '"');
}
}
$windows = isset($options['windows']);
if ($windows) {
$root = str_replace('/', '\\', $root);
}
if (!file_exists($params[1]) && !@touch($params[1])) {
return PEAR::raiseError('Could not create "' . $params[1] . '"');
}
$params[1] = realpath($params[1]);
$config = new PEAR_Config($params[1], '#no#system#config#', false, false);
if ($root{strlen($root) - 1} == '/') {
$root = substr($root, 0, strlen($root) - 1);
}
$config->noRegistry();
$config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user');
$config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data");
$config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www");
$config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg");
$config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext");
$config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs");
$config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests");
$config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache");
$config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download");
$config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp");
$config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
$config->set('man_dir', $windows ? "$root\\pear\\man" : "$root/pear/man");
$config->writeConfigFile();
$this->_showConfig($config);
$this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"',
$command);
}
function _showConfig(&$config)
{
$params = array('user');
$keys = $config->getKeys();
sort($keys);
$channel = 'pear.php.net';
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
foreach ($keys as $key) {
$type = $config->getType($key);
$value = $config->get($key, 'user', $channel);
if ($type == 'password' && $value) {
$value = '********';
}
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
$value = 'true';
}
$data['data'][$config->getGroup($key)][] =
array($config->getPrompt($key) , $key, $value);
}
foreach ($config->getLayers() as $layer) {
$data['data']['Config Files'][] =
array(ucfirst($layer) . ' Configuration File', 'Filename' ,
$config->getConfFile($layer));
}
$this->ui->outputData($data, 'config-show');
return true;
}
/**
* Checks if a layer is defined or not
*
* @param string $layer The layer to search for
* @return mixed False on no error or the error message
*/
function _checkLayer($layer = null)
{
if (!empty($layer) && $layer != 'default') {
$layers = $this->config->getLayers();
if (!in_array($layer, $layers)) {
return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
}
}
return false;
}
}

92
vendor/pear-pear.php.net/PEAR/PEAR/Command/Config.xml generated vendored Normal file
View file

@ -0,0 +1,92 @@
<commands version="1.0">
<config-show>
<summary>Show All Settings</summary>
<function>doConfigShow</function>
<shortcut>csh</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>[layer]
Displays all configuration values. An optional argument
may be used to tell which configuration layer to display. Valid
configuration layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;. To display
configurations for different channels, set the default_channel
configuration variable and run config-show again.
</doc>
</config-show>
<config-get>
<summary>Show One Setting</summary>
<function>doConfigGet</function>
<shortcut>cg</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>&lt;parameter&gt; [layer]
Displays the value of one configuration parameter. The
first argument is the name of the parameter, an optional second argument
may be used to tell which configuration layer to look in. Valid configuration
layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;. If no layer is specified, a value
will be picked from the first layer that defines the parameter, in the order
just specified. The configuration value will be retrieved for the channel
specified by the default_channel configuration variable.
</doc>
</config-get>
<config-set>
<summary>Change Setting</summary>
<function>doConfigSet</function>
<shortcut>cs</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>&lt;parameter&gt; &lt;value&gt; [layer]
Sets the value of one configuration parameter. The first argument is
the name of the parameter, the second argument is the new value. Some
parameters are subject to validation, and the command will fail with
an error message if the new value does not make sense. An optional
third argument may be used to specify in which layer to set the
configuration parameter. The default layer is &quot;user&quot;. The
configuration value will be set for the current channel, which
is controlled by the default_channel configuration variable.
</doc>
</config-set>
<config-help>
<summary>Show Information About Setting</summary>
<function>doConfigHelp</function>
<shortcut>ch</shortcut>
<options />
<doc>[parameter]
Displays help for a configuration parameter. Without arguments it
displays help for all configuration parameters.
</doc>
</config-help>
<config-create>
<summary>Create a Default configuration file</summary>
<function>doConfigCreate</function>
<shortcut>coc</shortcut>
<options>
<windows>
<shortopt>w</shortopt>
<doc>create a config file for a windows install</doc>
</windows>
</options>
<doc>&lt;root path&gt; &lt;filename&gt;
Create a default configuration file with all directory configuration
variables set to subdirectories of &lt;root path&gt;, and save it as &lt;filename&gt;.
This is useful especially for creating a configuration file for a remote
PEAR installation (using the --remoteconfig option of install, upgrade,
and uninstall).
</doc>
</config-create>
</commands>

1269
vendor/pear-pear.php.net/PEAR/PEAR/Command/Install.php generated vendored Normal file

File diff suppressed because it is too large Load diff

276
vendor/pear-pear.php.net/PEAR/PEAR/Command/Install.xml generated vendored Normal file
View file

@ -0,0 +1,276 @@
<commands version="1.0">
<install>
<summary>Install Package</summary>
<function>doInstall</function>
<shortcut>i</shortcut>
<options>
<force>
<shortopt>f</shortopt>
<doc>will overwrite newer installed packages</doc>
</force>
<loose>
<shortopt>l</shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, install anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as installed</doc>
</register-only>
<soft>
<shortopt>s</shortopt>
<doc>soft install, fail silently, or upgrade if already installed</doc>
</soft>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
</installroot>
<packagingroot>
<shortopt>P</shortopt>
<doc>root directory used when packaging files, like RPM packaging</doc>
<arg>DIR</arg>
</packagingroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<alldeps>
<shortopt>a</shortopt>
<doc>install all required and optional dependencies</doc>
</alldeps>
<onlyreqdeps>
<shortopt>o</shortopt>
<doc>install all required dependencies</doc>
</onlyreqdeps>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to download any urls or contact channels</doc>
</offline>
<pretend>
<shortopt>p</shortopt>
<doc>Only list the packages that would be downloaded</doc>
</pretend>
</options>
<doc>[channel/]&lt;package&gt; ...
Installs one or more PEAR packages. You can specify a package to
install in four ways:
&quot;Package-1.0.tgz&quot; : installs from a local file
&quot;http://example.com/Package-1.0.tgz&quot; : installs from
anywhere on the net.
&quot;package.xml&quot; : installs the package described in
package.xml. Useful for testing, or for wrapping a PEAR package in
another package manager such as RPM.
&quot;Package[-version/state][.tar]&quot; : queries your default channel&#039;s server
({config master_server}) and downloads the newest package with
the preferred quality/state ({config preferred_state}).
To retrieve Package version 1.1, use &quot;Package-1.1,&quot; to retrieve
Package state beta, use &quot;Package-beta.&quot; To retrieve an uncompressed
file, append .tar (make sure there is no file by the same name first)
To download a package from another channel, prefix with the channel name like
&quot;channel/Package&quot;
More than one package may be specified at once. It is ok to mix these
four ways of specifying packages.
</doc>
</install>
<upgrade>
<summary>Upgrade Package</summary>
<function>doInstall</function>
<shortcut>up</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>upgrade packages from a specific channel</doc>
<arg>CHAN</arg>
</channel>
<force>
<shortopt>f</shortopt>
<doc>overwrite newer installed packages</doc>
</force>
<loose>
<shortopt>l</shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, upgrade anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as upgraded</doc>
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<alldeps>
<shortopt>a</shortopt>
<doc>install all required and optional dependencies</doc>
</alldeps>
<onlyreqdeps>
<shortopt>o</shortopt>
<doc>install all required dependencies</doc>
</onlyreqdeps>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to download any urls or contact channels</doc>
</offline>
<pretend>
<shortopt>p</shortopt>
<doc>Only list the packages that would be downloaded</doc>
</pretend>
</options>
<doc>&lt;package&gt; ...
Upgrades one or more PEAR packages. See documentation for the
&quot;install&quot; command for ways to specify a package.
When upgrading, your package will be updated if the provided new
package has a higher version number (use the -f option if you need to
upgrade anyway).
More than one package may be specified at once.
</doc>
</upgrade>
<upgrade-all>
<summary>Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]</summary>
<function>doUpgradeAll</function>
<shortcut>ua</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>upgrade packages from a specific channel</doc>
<arg>CHAN</arg>
</channel>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, upgrade anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as upgraded</doc>
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<loose>
<shortopt></shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
</options>
<doc>
WARNING: This function is deprecated in favor of using the upgrade command with no params
Upgrades all packages that have a newer release available. Upgrades are
done only if there is a release available of the state specified in
&quot;preferred_state&quot; (currently {config preferred_state}), or a state considered
more stable.
</doc>
</upgrade-all>
<uninstall>
<summary>Un-install Package</summary>
<function>doUninstall</function>
<shortcut>un</shortcut>
<options>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, uninstall anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not remove files, only register the packages as not installed</doc>
</register-only>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to uninstall remotely</doc>
</offline>
</options>
<doc>[channel/]&lt;package&gt; ...
Uninstalls one or more PEAR packages. More than one package may be
specified at once. Prefix with channel name to uninstall from a
channel not in your default channel ({config default_channel})
</doc>
</uninstall>
<bundle>
<summary>Unpacks a Pecl Package</summary>
<function>doBundle</function>
<shortcut>bun</shortcut>
<options>
<destination>
<shortopt>d</shortopt>
<doc>Optional destination directory for unpacking (defaults to current path or &quot;ext&quot; if exists)</doc>
<arg>DIR</arg>
</destination>
<force>
<shortopt>f</shortopt>
<doc>Force the unpacking even if there were errors in the package</doc>
</force>
</options>
<doc>&lt;package&gt;
Unpacks a Pecl Package into the selected location. It will download the
package if needed.
</doc>
</bundle>
<run-scripts>
<summary>Run Post-Install Scripts bundled with a package</summary>
<function>doRunScripts</function>
<shortcut>rs</shortcut>
<options />
<doc>&lt;package&gt;
Run post-installation scripts in package &lt;package&gt;, if any exist.
</doc>
</run-scripts>
</commands>

138
vendor/pear-pear.php.net/PEAR/PEAR/Command/Mirror.php generated vendored Normal file
View file

@ -0,0 +1,138 @@
<?php
/**
* PEAR_Command_Mirror (download-all command)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.2.0
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
/**
* PEAR commands for providing file mirrors
*
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
class PEAR_Command_Mirror extends PEAR_Command_Common
{
var $commands = array(
'download-all' => array(
'summary' => 'Downloads each available package from the default channel',
'function' => 'doDownloadAll',
'shortcut' => 'da',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
),
),
'doc' => '
Requests a list of available packages from the default channel ({config default_channel})
and downloads them to current working directory. Note: only
packages within preferred_state ({config preferred_state}) will be downloaded'
),
);
/**
* PEAR_Command_Mirror constructor.
*
* @access public
* @param object PEAR_Frontend a reference to an frontend
* @param object PEAR_Config a reference to the configuration data
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
/**
* For unit-testing
*/
function &factory($a)
{
$a = &PEAR_Command::factory($a, $this->config);
return $a;
}
/**
* retrieves a list of avaible Packages from master server
* and downloads them
*
* @access public
* @param string $command the command
* @param array $options the command options before the command
* @param array $params the stuff after the command name
* @return bool true if successful
* @throw PEAR_Error
*/
function doDownloadAll($command, $options, $params)
{
$savechannel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$this->config->set('default_channel', $channel);
$this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$remoteInfo = array_flip($rest->listPackages($base, $channel));
}
if (PEAR::isError($remoteInfo)) {
return $remoteInfo;
}
$cmd = &$this->factory("download");
if (PEAR::isError($cmd)) {
return $cmd;
}
$this->ui->outputData('Using Preferred State of ' .
$this->config->get('preferred_state'));
$this->ui->outputData('Gathering release information, please wait...');
/**
* Error handling not necessary, because already done by
* the download command
*/
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo));
PEAR::staticPopErrorHandling();
$this->config->set('default_channel', $savechannel);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage());
}
return true;
}
}

18
vendor/pear-pear.php.net/PEAR/PEAR/Command/Mirror.xml generated vendored Normal file
View file

@ -0,0 +1,18 @@
<commands version="1.0">
<download-all>
<summary>Downloads each available package from the default channel</summary>
<function>doDownloadAll</function>
<shortcut>da</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>
Requests a list of available packages from the default channel ({config default_channel})
and downloads them to current working directory. Note: only
packages within preferred_state ({config preferred_state}) will be downloaded</doc>
</download-all>
</commands>

1123
vendor/pear-pear.php.net/PEAR/PEAR/Command/Package.php generated vendored Normal file

File diff suppressed because it is too large Load diff

237
vendor/pear-pear.php.net/PEAR/PEAR/Command/Package.xml generated vendored Normal file
View file

@ -0,0 +1,237 @@
<commands version="1.0">
<package>
<summary>Build Package</summary>
<function>doPackage</function>
<shortcut>p</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>Do not gzip the package file</doc>
</nocompress>
<showname>
<shortopt>n</shortopt>
<doc>Print the name of the packaged file.</doc>
</showname>
</options>
<doc>[descfile] [descfile2]
Creates a PEAR package from its description file (usually called
package.xml). If a second packagefile is passed in, then
the packager will check to make sure that one is a package.xml
version 1.0, and the other is a package.xml version 2.0. The
package.xml version 1.0 will be saved as &quot;package.xml&quot; in the archive,
and the other as &quot;package2.xml&quot; in the archive&quot;
</doc>
</package>
<package-validate>
<summary>Validate Package Consistency</summary>
<function>doPackageValidate</function>
<shortcut>pv</shortcut>
<options />
<doc>
</doc>
</package-validate>
<cvsdiff>
<summary>Run a &quot;cvs diff&quot; for all files in a package</summary>
<function>doCvsDiff</function>
<shortcut>cd</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<reallyquiet>
<shortopt>Q</shortopt>
<doc>Be really quiet</doc>
</reallyquiet>
<date>
<shortopt>D</shortopt>
<doc>Diff against revision of DATE</doc>
<arg>DATE</arg>
</date>
<release>
<shortopt>R</shortopt>
<doc>Diff against tag for package release REL</doc>
<arg>REL</arg>
</release>
<revision>
<shortopt>r</shortopt>
<doc>Diff against revision REV</doc>
<arg>REV</arg>
</revision>
<context>
<shortopt>c</shortopt>
<doc>Generate context diff</doc>
</context>
<unified>
<shortopt>u</shortopt>
<doc>Generate unified diff</doc>
</unified>
<ignore-case>
<shortopt>i</shortopt>
<doc>Ignore case, consider upper- and lower-case letters equivalent</doc>
</ignore-case>
<ignore-whitespace>
<shortopt>b</shortopt>
<doc>Ignore changes in amount of white space</doc>
</ignore-whitespace>
<ignore-blank-lines>
<shortopt>B</shortopt>
<doc>Ignore changes that insert or delete blank lines</doc>
</ignore-blank-lines>
<brief>
<shortopt></shortopt>
<doc>Report only whether the files differ, no details</doc>
</brief>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt;
Compares all the files in a package. Without any options, this
command will compare the current code with the last checked-in code.
Using the -r or -R option you may compare the current code with that
of a specific release.
</doc>
</cvsdiff>
<svntag>
<summary>Set SVN Release Tag</summary>
<function>doSvnTag</function>
<shortcut>sv</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<slide>
<shortopt>F</shortopt>
<doc>Move (slide) tag if it exists</doc>
</slide>
<delete>
<shortopt>d</shortopt>
<doc>Remove tag</doc>
</delete>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
Sets a SVN tag on all files in a package. Use this command after you have
packaged a distribution tarball with the &quot;package&quot; command to tag what
revisions of what files were in that release. If need to fix something
after running svntag once, but before the tarball is released to the public,
use the &quot;slide&quot; option to move the release tag.
to include files (such as a second package.xml, or tests not included in the
release), pass them as additional parameters.
</doc>
</svntag>
<cvstag>
<summary>Set CVS Release Tag</summary>
<function>doCvsTag</function>
<shortcut>ct</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<reallyquiet>
<shortopt>Q</shortopt>
<doc>Be really quiet</doc>
</reallyquiet>
<slide>
<shortopt>F</shortopt>
<doc>Move (slide) tag if it exists</doc>
</slide>
<delete>
<shortopt>d</shortopt>
<doc>Remove tag</doc>
</delete>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
Sets a CVS tag on all files in a package. Use this command after you have
packaged a distribution tarball with the &quot;package&quot; command to tag what
revisions of what files were in that release. If need to fix something
after running cvstag once, but before the tarball is released to the public,
use the &quot;slide&quot; option to move the release tag.
to include files (such as a second package.xml, or tests not included in the
release), pass them as additional parameters.
</doc>
</cvstag>
<package-dependencies>
<summary>Show package dependencies</summary>
<function>doPackageDependencies</function>
<shortcut>pd</shortcut>
<options />
<doc>&lt;package-file&gt; or &lt;package.xml&gt; or &lt;install-package-name&gt;
List all dependencies the package has.
Can take a tgz / tar file, package.xml or a package name of an installed package.</doc>
</package-dependencies>
<sign>
<summary>Sign a package distribution file</summary>
<function>doSign</function>
<shortcut>si</shortcut>
<options>
<verbose>
<shortopt>v</shortopt>
<doc>Display GnuPG output</doc>
</verbose>
</options>
<doc>&lt;package-file&gt;
Signs a package distribution (.tar or .tgz) file with GnuPG.</doc>
</sign>
<makerpm>
<summary>Builds an RPM spec file from a PEAR package</summary>
<function>doMakeRPM</function>
<shortcut>rpm</shortcut>
<options>
<spec-template>
<shortopt>t</shortopt>
<doc>Use FILE as RPM spec file template</doc>
<arg>FILE</arg>
</spec-template>
<rpm-pkgname>
<shortopt>p</shortopt>
<doc>Use FORMAT as format string for RPM package name, %s is replaced
by the PEAR package name, defaults to &quot;PEAR::%s&quot;.</doc>
<arg>FORMAT</arg>
</rpm-pkgname>
</options>
<doc>&lt;package-file&gt;
Creates an RPM .spec file for wrapping a PEAR package inside an RPM
package. Intended to be used from the SPECS directory, with the PEAR
package tarball in the SOURCES directory:
$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
Wrote RPM spec file PEAR::Net_Geo-1.0.spec
$ rpm -bb PEAR::Net_Socket-1.0.spec
...
Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
</doc>
</makerpm>
<convert>
<summary>Convert a package.xml 1.0 to package.xml 2.0 format</summary>
<function>doConvert</function>
<shortcut>c2</shortcut>
<options>
<flat>
<shortopt>f</shortopt>
<doc>do not beautify the filelist.</doc>
</flat>
</options>
<doc>[descfile] [descfile2]
Converts a package.xml in 1.0 format into a package.xml
in 2.0 format. The new file will be named package2.xml by default,
and package.xml will be used as the old file by default.
This is not the most intelligent conversion, and should only be
used for automated conversion or learning the format.
</doc>
</convert>
</commands>

420
vendor/pear-pear.php.net/PEAR/PEAR/Command/Pickle.php generated vendored Normal file
View file

@ -0,0 +1,420 @@
<?php
/**
* PEAR_Command_Pickle (pickle command)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.1
*/
class PEAR_Command_Pickle extends PEAR_Command_Common
{
var $commands = array(
'pickle' => array(
'summary' => 'Build PECL Package',
'function' => 'doPackage',
'shortcut' => 'pi',
'options' => array(
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'Do not gzip the package file'
),
'showname' => array(
'shortopt' => 'n',
'doc' => 'Print the name of the packaged file.',
),
),
'doc' => '[descfile]
Creates a PECL package from its package2.xml file.
An automatic conversion will be made to a package.xml 1.0 and written out to
disk in the current directory as "package.xml". Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease or zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace
- custom roles
will cause pickle to fail, and output an error message. If your package2.xml
uses any of these features, you are best off using PEAR_PackageFileManager to
generate both package.xml.
'
),
);
/**
* PEAR_Command_Package constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
/**
* For unit-testing ease
*
* @return PEAR_Packager
*/
function &getPackager()
{
if (!class_exists('PEAR_Packager')) {
require_once 'PEAR/Packager.php';
}
$a = new PEAR_Packager;
return $a;
}
/**
* For unit-testing ease
*
* @param PEAR_Config $config
* @param bool $debug
* @param string|null $tmpdir
* @return PEAR_PackageFile
*/
function &getPackageFile($config, $debug = false)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = new PEAR_PackageFile($config, $debug);
$common = new PEAR_Common;
$common->ui = $this->ui;
$a->setLogger($common);
return $a;
}
function doPackage($command, $options, $params)
{
$this->output = '';
$pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml';
$packager = &$this->getPackager();
if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) {
return $err;
}
$compress = empty($options['nocompress']) ? true : false;
$result = $packager->package($pkginfofile, $compress, 'package.xml');
if (PEAR::isError($result)) {
return $this->raiseError($result);
}
// Don't want output, only the package file name just created
if (isset($options['showname'])) {
$this->ui->outputData($result, $command);
}
return true;
}
function _convertPackage($packagexml)
{
$pkg = &$this->getPackageFile($this->config);
$pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
if (!is_a($pf2, 'PEAR_PackageFile_v2')) {
return $this->raiseError('Cannot process "' .
$packagexml . '", is not a package.xml 2.0');
}
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->config);
if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", is not an extension source package. Using a PEAR_PackageFileManager-based ' .
'script is an option');
}
if (is_array($pf2->getUsesRole())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom roles. Using a PEAR_PackageFileManager-based script or ' .
'the convert command is an option');
}
if (is_array($pf2->getUsesTask())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' .
'the convert command is an option');
}
$deps = $pf2->getDependencies();
if (isset($deps['group'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains dependency groups. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if (isset($deps['required']['subpackage']) ||
isset($deps['optional']['subpackage'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
if (isset($deps['required']['os'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains os dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
if (isset($deps['required']['arch'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains arch dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
$pf->setPackage($pf2->getPackage());
$pf->setSummary($pf2->getSummary());
$pf->setDescription($pf2->getDescription());
foreach ($pf2->getMaintainers() as $maintainer) {
$pf->addMaintainer($maintainer['role'], $maintainer['handle'],
$maintainer['name'], $maintainer['email']);
}
$pf->setVersion($pf2->getVersion());
$pf->setDate($pf2->getDate());
$pf->setLicense($pf2->getLicense());
$pf->setState($pf2->getState());
$pf->setNotes($pf2->getNotes());
$pf->addPhpDep($deps['required']['php']['min'], 'ge');
if (isset($deps['required']['php']['max'])) {
$pf->addPhpDep($deps['required']['php']['max'], 'le');
}
if (isset($deps['required']['package'])) {
if (!isset($deps['required']['package'][0])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dep) {
if (!isset($dep['channel'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains uri-based dependency on a package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if ($dep['channel'] != 'pear.php.net'
&& $dep['channel'] != 'pecl.php.net'
&& $dep['channel'] != 'doc.php.net') {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains dependency on a non-standard channel package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['conflicts'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains conflicts dependency. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addPackageDep($dep['name'], $dep['min'], 'ge');
}
if (isset($dep['max'])) {
$pf->addPackageDep($dep['name'], $dep['max'], 'le');
}
}
}
if (isset($deps['required']['extension'])) {
if (!isset($deps['required']['extension'][0])) {
$deps['required']['extension'] = array($deps['required']['extension']);
}
foreach ($deps['required']['extension'] as $dep) {
if (isset($dep['conflicts'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains conflicts dependency. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge');
}
if (isset($dep['max'])) {
$pf->addExtensionDep($dep['name'], $dep['max'], 'le');
}
}
}
if (isset($deps['optional']['package'])) {
if (!isset($deps['optional']['package'][0])) {
$deps['optional']['package'] = array($deps['optional']['package']);
}
foreach ($deps['optional']['package'] as $dep) {
if (!isset($dep['channel'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains uri-based dependency on a package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if ($dep['channel'] != 'pear.php.net'
&& $dep['channel'] != 'pecl.php.net'
&& $dep['channel'] != 'doc.php.net') {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains dependency on a non-standard channel package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes');
}
if (isset($dep['max'])) {
$pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes');
}
}
}
if (isset($deps['optional']['extension'])) {
if (!isset($deps['optional']['extension'][0])) {
$deps['optional']['extension'] = array($deps['optional']['extension']);
}
foreach ($deps['optional']['extension'] as $dep) {
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes');
}
if (isset($dep['max'])) {
$pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes');
}
}
}
$contents = $pf2->getContents();
$release = $pf2->getReleases();
if (isset($releases[0])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
. 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if ($configoptions = $pf2->getConfigureOptions()) {
foreach ($configoptions as $option) {
$default = isset($option['default']) ? $option['default'] : false;
$pf->addConfigureOption($option['name'], $option['prompt'], $default);
}
}
if (isset($release['filelist']['ignore'])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
. 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' .
' command is an option');
}
if (isset($release['filelist']['install']) &&
!isset($release['filelist']['install'][0])) {
$release['filelist']['install'] = array($release['filelist']['install']);
}
if (isset($contents['dir']['attribs']['baseinstalldir'])) {
$baseinstalldir = $contents['dir']['attribs']['baseinstalldir'];
} else {
$baseinstalldir = false;
}
if (!isset($contents['dir']['file'][0])) {
$contents['dir']['file'] = array($contents['dir']['file']);
}
foreach ($contents['dir']['file'] as $file) {
if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) {
$file['attribs']['baseinstalldir'] = $baseinstalldir;
}
$processFile = $file;
unset($processFile['attribs']);
if (count($processFile)) {
foreach ($processFile as $name => $task) {
if ($name != $pf2->getTasksNs() . ':replace') {
return $this->raiseError('Cannot safely process "' . $packagexml .
'" contains tasks other than replace. Using a ' .
'PEAR_PackageFileManager-based script is an option.');
}
$file['attribs']['replace'][] = $task;
}
}
if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom roles. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if (isset($release['filelist']['install'])) {
foreach ($release['filelist']['install'] as $installas) {
if ($installas['attribs']['name'] == $file['attribs']['name']) {
$file['attribs']['install-as'] = $installas['attribs']['as'];
}
}
}
$pf->addFile('/', $file['attribs']['name'], $file['attribs']);
}
if ($pf2->getChangeLog()) {
$this->ui->outputData('WARNING: changelog is not translated to package.xml ' .
'1.0, use PEAR_PackageFileManager-based script if you need changelog-' .
'translation for package.xml 1.0');
}
$gen = &$pf->getDefaultGenerator();
$gen->toPackageFile('.');
}
}

36
vendor/pear-pear.php.net/PEAR/PEAR/Command/Pickle.xml generated vendored Normal file
View file

@ -0,0 +1,36 @@
<commands version="1.0">
<pickle>
<summary>Build PECL Package</summary>
<function>doPackage</function>
<shortcut>pi</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>Do not gzip the package file</doc>
</nocompress>
<showname>
<shortopt>n</shortopt>
<doc>Print the name of the packaged file.</doc>
</showname>
</options>
<doc>[descfile]
Creates a PECL package from its package2.xml file.
An automatic conversion will be made to a package.xml 1.0 and written out to
disk in the current directory as &quot;package.xml&quot;. Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease or zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace
- custom roles
will cause pickle to fail, and output an error message. If your package2.xml
uses any of these features, you are best off using PEAR_PackageFileManager to
generate both package.xml.
</doc>
</pickle>
</commands>

1144
vendor/pear-pear.php.net/PEAR/PEAR/Command/Registry.php generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
<commands version="1.0">
<list>
<summary>List Installed Packages In The Default Channel</summary>
<function>doList</function>
<shortcut>l</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>list installed packages from this channel</doc>
<arg>CHAN</arg>
</channel>
<allchannels>
<shortopt>a</shortopt>
<doc>list installed packages from all channels</doc>
</allchannels>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>&lt;package&gt;
If invoked without parameters, this command lists the PEAR packages
installed in your php_dir ({config php_dir}). With a parameter, it
lists the files in a package.
</doc>
</list>
<list-files>
<summary>List Files In Installed Package</summary>
<function>doFileList</function>
<shortcut>fl</shortcut>
<options />
<doc>&lt;package&gt;
List the files in an installed package.
</doc>
</list-files>
<shell-test>
<summary>Shell Script Test</summary>
<function>doShellTest</function>
<shortcut>st</shortcut>
<options />
<doc>&lt;package&gt; [[relation] version]
Tests if a package is installed in the system. Will exit(1) if it is not.
&lt;relation&gt; The version comparison operator. One of:
&lt;, lt, &lt;=, le, &gt;, gt, &gt;=, ge, ==, =, eq, !=, &lt;&gt;, ne
&lt;version&gt; The version to compare with
</doc>
</shell-test>
<info>
<summary>Display information about a package</summary>
<function>doInfo</function>
<shortcut>in</shortcut>
<options />
<doc>&lt;package&gt;
Displays information about a package. The package argument may be a
local package file, an URL to a package file, or the name of an
installed package.</doc>
</info>
</commands>

809
vendor/pear-pear.php.net/PEAR/PEAR/Command/Remote.php generated vendored Normal file
View file

@ -0,0 +1,809 @@
<?php
/**
* PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
* clear-cache commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
require_once 'PEAR/REST.php';
/**
* PEAR commands for remote server querying
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Remote extends PEAR_Command_Common
{
var $commands = array(
'remote-info' => array(
'summary' => 'Information About Remote Packages',
'function' => 'doRemoteInfo',
'shortcut' => 'ri',
'options' => array(),
'doc' => '<package>
Get details on a package from the server.',
),
'list-upgrades' => array(
'summary' => 'List Available Upgrades',
'function' => 'doListUpgrades',
'shortcut' => 'lu',
'options' => array(
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '[preferred_state]
List releases on the server of packages you have installed where
a newer version is available with the same release state (stable etc.)
or the state passed as the second parameter.'
),
'remote-list' => array(
'summary' => 'List Remote Packages',
'function' => 'doRemoteList',
'shortcut' => 'rl',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'doc' => '
Lists the packages available on the configured server along with the
latest stable release of each package.',
),
'search' => array(
'summary' => 'Search remote package database',
'function' => 'doSearch',
'shortcut' => 'sp',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
),
'allchannels' => array(
'shortopt' => 'a',
'doc' => 'search packages from all known channels',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
parameter is a fragment of a packagename. The default channel
will be used unless explicitly overridden. The second parameter
will be used to match any portion of the summary/description',
),
'list-all' => array(
'summary' => 'List All Packages',
'function' => 'doListAll',
'shortcut' => 'la',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '
Lists the packages available on the configured server along with the
latest stable release of each package.',
),
'download' => array(
'summary' => 'Download Package',
'function' => 'doDownload',
'shortcut' => 'd',
'options' => array(
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'download an uncompressed (.tar) file',
),
),
'doc' => '<package>...
Download package tarballs. The files will be named as suggested by the
server, for example if you download the DB package and the latest stable
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
),
'clear-cache' => array(
'summary' => 'Clear Web Services Cache',
'function' => 'doClearCache',
'shortcut' => 'cc',
'options' => array(),
'doc' => '
Clear the REST cache. See also the cache_ttl configuration
parameter.
',
),
);
/**
* PEAR_Command_Remote constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
function _checkChannelForStatus($channel, $chan)
{
if (PEAR::isError($chan)) {
$this->raiseError($chan);
}
if (!is_a($chan, 'PEAR_ChannelFile')) {
return $this->raiseError('Internal corruption error: invalid channel "' .
$channel . '"');
}
$rest = new PEAR_REST($this->config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$mirror = $this->config->get('preferred_mirror', null,
$channel);
$a = $rest->downloadHttp('http://' . $channel .
'/channel.xml', $chan->lastModified());
PEAR::staticPopErrorHandling();
if (!PEAR::isError($a) && $a) {
$this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel .
'" to update');
}
}
function doRemoteInfo($command, $options, $params)
{
if (sizeof($params) != 1) {
return $this->raiseError("$command expects one param: the remote package name");
}
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$package = $params[0];
$parsed = $reg->parsePackageName($package, $channel);
if (PEAR::isError($parsed)) {
return $this->raiseError('Invalid package name "' . $package . '"');
}
$channel = $parsed['channel'];
$this->config->set('default_channel', $channel);
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
$mirror = $this->config->get('preferred_mirror');
if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) {
$rest = &$this->config->getREST('1.0', array());
$info = $rest->packageInfo($base, $parsed['package'], $channel);
}
if (!isset($info)) {
return $this->raiseError('No supported protocol was found');
}
if (PEAR::isError($info)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($info);
}
if (!isset($info['name'])) {
return $this->raiseError('No remote package "' . $package . '" was found');
}
$installed = $reg->packageInfo($info['name'], null, $channel);
$info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
if (is_array($info['installed'])) {
$info['installed'] = $info['installed']['release'];
}
$this->ui->outputData($info, $command);
$this->config->set('default_channel', $savechannel);
return true;
}
function doRemoteList($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$this->config->set('default_channel', $channel);
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
$available = array();
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))
) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
$i = $j = 0;
$data = array(
'caption' => 'Channel ' . $channel . ' Available packages:',
'border' => true,
'headline' => array('Package', 'Version'),
'channel' => $channel
);
if (count($available) == 0) {
$data = '(no packages available yet)';
} else {
foreach ($available as $name => $info) {
$version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-';
$data['data'][] = array($name, $version);
}
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $savechannel);
return true;
}
function doListAll($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
return $this->raiseError("Channel \"$channel\" does not exist");
}
$this->config->set('default_channel', $channel);
}
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
}
$data = array(
'caption' => 'All packages [Channel ' . $channel . ']:',
'border' => true,
'headline' => array('Package', 'Latest', 'Local'),
'channel' => $channel,
);
if (isset($options['channelinfo'])) {
// add full channelinfo
$data['caption'] = 'Channel ' . $channel . ' All packages:';
$data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
'Description', 'Dependencies');
}
$local_pkgs = $reg->listPackages($channel);
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
if (is_array($installed['version'])) {
$installed['version'] = $installed['version']['release'];
}
$desc = $info['summary'];
if (isset($params[$name])) {
$desc .= "\n\n".$info['description'];
}
if (isset($options['mode']))
{
if ($options['mode'] == 'installed' && !isset($installed['version'])) {
continue;
}
if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
continue;
}
if ($options['mode'] == 'upgrades'
&& (!isset($installed['version']) || version_compare($installed['version'],
$info['stable'], '>='))) {
continue;
}
}
$pos = array_search(strtolower($name), $local_pkgs);
if ($pos !== false) {
unset($local_pkgs[$pos]);
}
if (isset($info['stable']) && !$info['stable']) {
$info['stable'] = null;
}
if (isset($options['channelinfo'])) {
// add full channelinfo
if ($info['stable'] === $info['unstable']) {
$state = $info['state'];
} else {
$state = 'stable';
}
$latest = $info['stable'].' ('.$state.')';
$local = '';
if (isset($installed['version'])) {
$inst_state = $reg->packageInfo($name, 'release_state', $channel);
$local = $installed['version'].' ('.$inst_state.')';
}
$packageinfo = array(
$channel,
$name,
$latest,
$local,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
} else {
$packageinfo = array(
$reg->channelAlias($channel) . '/' . $name,
isset($info['stable']) ? $info['stable'] : null,
isset($installed['version']) ? $installed['version'] : null,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
$this->config->set('default_channel', $savechannel);
$this->ui->outputData($data, $command);
return true;
}
foreach ($local_pkgs as $name) {
$info = &$reg->getPackage($name, $channel);
$data['data']['Local'][] = array(
$reg->channelAlias($channel) . '/' . $info->getPackage(),
'',
$info->getVersion(),
$info->getSummary(),
$info->getDeps()
);
}
$this->config->set('default_channel', $savechannel);
$this->ui->outputData($data, $command);
return true;
}
function doSearch($command, $options, $params)
{
if ((!isset($params[0]) || empty($params[0]))
&& (!isset($params[1]) || empty($params[1])))
{
return $this->raiseError('no valid search string supplied');
}
$channelinfo = isset($options['channelinfo']);
$reg = &$this->config->getRegistry();
if (isset($options['allchannels'])) {
// search all channels
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
if ($channel->getName() != '__uri') {
$options['channel'] = $channel->getName();
$ret = $this->doSearch($command, $options, $params);
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
}
PEAR::staticPopErrorHandling();
if (count($errors) !== 0) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
return true;
}
$savechannel = $channel = $this->config->get('default_channel');
$package = strtolower($params[0]);
$summary = isset($params[1]) ? $params[1] : false;
if (isset($options['channel'])) {
$reg = &$this->config->getRegistry();
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$this->config->set('default_channel', $channel);
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
if (!$available && !$channelinfo) {
// clean exit when not found, no error !
$data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
$this->ui->outputData($data);
$this->config->set('default_channel', $channel);
return true;
}
if ($channelinfo) {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
} else {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
}
if (!$available && $channelinfo) {
unset($data['headline']);
$data['data'] = 'No packages found that match pattern "' . $package . '".';
$available = array();
}
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
$desc = $info['summary'];
if (isset($params[$name]))
$desc .= "\n\n".$info['description'];
if (!isset($info['stable']) || !$info['stable']) {
$version_remote = 'none';
} else {
if ($info['unstable']) {
$version_remote = $info['unstable'];
} else {
$version_remote = $info['stable'];
}
$version_remote .= ' ('.$info['state'].')';
}
$version = is_array($installed['version']) ? $installed['version']['release'] :
$installed['version'];
if ($channelinfo) {
$packageinfo = array(
$channel,
$name,
$version_remote,
$version,
$desc,
);
} else {
$packageinfo = array(
$name,
$version_remote,
$version,
$desc,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $channel);
return true;
}
function &getDownloader($options)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = new PEAR_Downloader($this->ui, $options, $this->config);
return $a;
}
function doDownload($command, $options, $params)
{
// make certain that dependencies are ignored
$options['downloadonly'] = 1;
// eliminate error messages for preferred_state-related errors
/* TODO: Should be an option, but until now download does respect
preferred state */
/* $options['ignorepreferred_state'] = 1; */
// eliminate error messages for preferred_state-related errors
$downloader = &$this->getDownloader($options);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$e = $downloader->setDownloadDir(getcwd());
PEAR::staticPopErrorHandling();
if (PEAR::isError($e)) {
return $this->raiseError('Current directory is not writeable, cannot download');
}
$errors = array();
$downloaded = array();
$err = $downloader->download($params);
if (PEAR::isError($err)) {
return $err;
}
$errors = $downloader->getErrorMsgs();
if (count($errors)) {
foreach ($errors as $error) {
if ($error !== null) {
$this->ui->outputData($error);
}
}
return $this->raiseError("$command failed");
}
$downloaded = $downloader->getDownloadedPackages();
foreach ($downloaded as $pkg) {
$this->ui->outputData("File $pkg[file] downloaded", $command);
}
return true;
}
function downloadCallback($msg, $params = null)
{
if ($msg == 'done') {
$this->bytes_downloaded = $params;
}
}
function doListUpgrades($command, $options, $params)
{
require_once 'PEAR/Common.php';
if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
}
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
foreach ($reg->listChannels() as $channel) {
$inst = array_flip($reg->listPackages($channel));
if (!count($inst)) {
continue;
}
if ($channel == '__uri') {
continue;
}
$this->config->set('default_channel', $channel);
$state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0];
$caption = $channel . ' Available Upgrades';
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
$latest = array();
$base2 = false;
$preferred_mirror = $this->config->get('preferred_mirror');
if ($chan->supportsREST($preferred_mirror) &&
(
($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
|| ($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
if ($base2) {
$rest = &$this->config->getREST('1.3', array());
$base = $base2;
} else {
$rest = &$this->config->getREST('1.0', array());
}
if (empty($state) || $state == 'any') {
$state = false;
} else {
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
PEAR::staticPopErrorHandling();
}
if (PEAR::isError($latest)) {
$this->ui->outputData($latest->getMessage());
continue;
}
$caption .= ':';
if (PEAR::isError($latest)) {
$this->config->set('default_channel', $savechannel);
return $latest;
}
$data = array(
'caption' => $caption,
'border' => 1,
'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
'channel' => $channel
);
foreach ((array)$latest as $pkg => $info) {
$package = strtolower($pkg);
if (!isset($inst[$package])) {
// skip packages we don't have installed
continue;
}
extract($info);
$inst_version = $reg->packageInfo($package, 'version', $channel);
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
if (version_compare("$version", "$inst_version", "le")) {
// installed version is up-to-date
continue;
}
if ($filesize >= 20480) {
$filesize += 1024 - ($filesize % 1024);
$fs = sprintf("%dkB", $filesize / 1024);
} elseif ($filesize > 0) {
$filesize += 103 - ($filesize % 103);
$fs = sprintf("%.1fkB", $filesize / 1024.0);
} else {
$fs = " -"; // XXX center instead
}
$data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
}
if (isset($options['channelinfo'])) {
if (empty($data['data'])) {
unset($data['headline']);
if (count($inst) == 0) {
$data['data'] = '(no packages installed)';
} else {
$data['data'] = '(no upgrades available)';
}
}
$this->ui->outputData($data, $command);
} else {
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
$this->ui->outputData($data, $command);
}
}
}
$this->config->set('default_channel', $savechannel);
return true;
}
function doClearCache($command, $options, $params)
{
$cache_dir = $this->config->get('cache_dir');
$verbose = $this->config->get('verbose');
$output = '';
if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
return $this->raiseError("$cache_dir does not exist or is not a directory");
}
if (!($dp = @opendir($cache_dir))) {
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
}
if ($verbose >= 1) {
$output .= "reading directory $cache_dir\n";
}
$num = 0;
while ($ent = readdir($dp)) {
if (preg_match('/rest.cache(file|id)\\z/', $ent)) {
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
if (file_exists($path)) {
$ok = @unlink($path);
} else {
$ok = false;
$php_errormsg = '';
}
if ($ok) {
if ($verbose >= 2) {
$output .= "deleted $path\n";
}
$num++;
} elseif ($verbose >= 1) {
$output .= "failed to delete $path $php_errormsg\n";
}
}
}
closedir($dp);
if ($verbose >= 1) {
$output .= "$num cache entries cleared\n";
}
$this->ui->outputData(rtrim($output), $command);
return $num;
}
}

109
vendor/pear-pear.php.net/PEAR/PEAR/Command/Remote.xml generated vendored Normal file
View file

@ -0,0 +1,109 @@
<commands version="1.0">
<remote-info>
<summary>Information About Remote Packages</summary>
<function>doRemoteInfo</function>
<shortcut>ri</shortcut>
<options />
<doc>&lt;package&gt;
Get details on a package from the server.</doc>
</remote-info>
<list-upgrades>
<summary>List Available Upgrades</summary>
<function>doListUpgrades</function>
<shortcut>lu</shortcut>
<options>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>[preferred_state]
List releases on the server of packages you have installed where
a newer version is available with the same release state (stable etc.)
or the state passed as the second parameter.</doc>
</list-upgrades>
<remote-list>
<summary>List Remote Packages</summary>
<function>doRemoteList</function>
<shortcut>rl</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>
Lists the packages available on the configured server along with the
latest stable release of each package.</doc>
</remote-list>
<search>
<summary>Search remote package database</summary>
<function>doSearch</function>
<shortcut>sp</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
<allchannels>
<shortopt>a</shortopt>
<doc>search packages from all known channels</doc>
</allchannels>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
parameter is a fragment of a packagename. The default channel
will be used unless explicitly overridden. The second parameter
will be used to match any portion of the summary/description</doc>
</search>
<list-all>
<summary>List All Packages</summary>
<function>doListAll</function>
<shortcut>la</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>
Lists the packages available on the configured server along with the
latest stable release of each package.</doc>
</list-all>
<download>
<summary>Download Package</summary>
<function>doDownload</function>
<shortcut>d</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>download an uncompressed (.tar) file</doc>
</nocompress>
</options>
<doc>&lt;package&gt;...
Download package tarballs. The files will be named as suggested by the
server, for example if you download the DB package and the latest stable
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.</doc>
</download>
<clear-cache>
<summary>Clear Web Services Cache</summary>
<function>doClearCache</function>
<shortcut>cc</shortcut>
<options />
<doc>
Clear the XML-RPC/REST cache. See also the cache_ttl configuration
parameter.
</doc>
</clear-cache>
</commands>

343
vendor/pear-pear.php.net/PEAR/PEAR/Command/Test.php generated vendored Normal file
View file

@ -0,0 +1,343 @@
<?php
/**
* PEAR_Command_Test (run-tests)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Test extends PEAR_Command_Common
{
var $commands = array(
'run-tests' => array(
'summary' => 'Run Regression Tests',
'function' => 'doRunTests',
'shortcut' => 'rt',
'options' => array(
'recur' => array(
'shortopt' => 'r',
'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum',
),
'ini' => array(
'shortopt' => 'i',
'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
'arg' => 'SETTINGS'
),
'realtimelog' => array(
'shortopt' => 'l',
'doc' => 'Log test runs/results as they are run',
),
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Only display detail for failed tests',
),
'simple' => array(
'shortopt' => 's',
'doc' => 'Display simple output for all tests',
),
'package' => array(
'shortopt' => 'p',
'doc' => 'Treat parameters as installed packages from which to run tests',
),
'phpunit' => array(
'shortopt' => 'u',
'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
If none is found, all .phpt tests will be tried instead.',
),
'tapoutput' => array(
'shortopt' => 't',
'doc' => 'Output run-tests.log in TAP-compliant format',
),
'cgi' => array(
'shortopt' => 'c',
'doc' => 'CGI php executable (needed for tests with POST/GET section)',
'arg' => 'PHPCGI',
),
'coverage' => array(
'shortopt' => 'x',
'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
),
'showdiff' => array(
'shortopt' => 'd',
'doc' => 'Output diff on test failure',
),
),
'doc' => '[testfile|dir ...]
Run regression tests with PHP\'s regression testing script (run-tests.php).',
),
);
var $output;
/**
* PEAR_Command_Test constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
function doRunTests($command, $options, $params)
{
if (isset($options['phpunit']) && isset($options['tapoutput'])) {
return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
}
require_once 'PEAR/Common.php';
require_once 'System.php';
$log = new PEAR_Common;
$log->ui = &$this->ui; // slightly hacky, but it will work
$tests = array();
$depth = isset($options['recur']) ? 14 : 1;
if (!count($params)) {
$params[] = '.';
}
if (isset($options['package'])) {
$oldparams = $params;
$params = array();
$reg = &$this->config->getRegistry();
foreach ($oldparams as $param) {
$pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
if (PEAR::isError($pname)) {
return $this->raiseError($pname);
}
$package = &$reg->getPackage($pname['package'], $pname['channel']);
if (!$package) {
return PEAR::raiseError('Unknown package "' .
$reg->parsedPackageNameToString($pname) . '"');
}
$filelist = $package->getFilelist();
foreach ($filelist as $name => $atts) {
if (isset($atts['role']) && $atts['role'] != 'test') {
continue;
}
if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
$params[] = $atts['installed_as'];
continue;
} elseif (!preg_match('/\.phpt\\z/', $name)) {
continue;
}
$params[] = $atts['installed_as'];
}
}
}
foreach ($params as $p) {
if (is_dir($p)) {
if (isset($options['phpunit'])) {
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', 'AllTests.php'));
if (count($dir)) {
foreach ($dir as $p) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
}
continue;
}
$args = array($p, '-type', 'f', '-name', '*.phpt');
} else {
if (isset($options['phpunit'])) {
if (preg_match('/AllTests\.php\\z/i', $p)) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
continue;
}
if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
$tests[] = $p;
continue;
}
if (!preg_match('/\.phpt\\z/', $p)) {
$p .= '.phpt';
}
$args = array(dirname($p), '-type', 'f', '-name', $p);
}
if (!isset($options['recur'])) {
$args[] = '-maxdepth';
$args[] = 1;
}
$dir = System::find($args);
$tests = array_merge($tests, $dir);
}
$ini_settings = '';
if (isset($options['ini'])) {
$ini_settings .= $options['ini'];
}
if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
$ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
}
if ($ini_settings) {
$this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
}
$skipped = $passed = $failed = array();
$tests_count = count($tests);
$this->ui->outputData('Running ' . $tests_count . ' tests', $command);
$start = time();
if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
unlink('run-tests.log');
}
if (isset($options['tapoutput'])) {
$tap = '1..' . $tests_count . "\n";
}
require_once 'PEAR/RunTest.php';
$run = new PEAR_RunTest($log, $options);
$run->tests_count = $tests_count;
if (isset($options['coverage']) && extension_loaded('xdebug')){
$run->xdebug_loaded = true;
} else {
$run->xdebug_loaded = false;
}
$j = $i = 1;
foreach ($tests as $t) {
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "Running test [$i / $tests_count] $t...");
fclose($fp);
}
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (isset($options['phpunit'])) {
$result = $run->runPHPUnit($t, $ini_settings);
} else {
$result = $run->run($t, $ini_settings, $j);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($result)) {
$this->ui->log($result->getMessage());
continue;
}
if (isset($options['tapoutput'])) {
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
continue;
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "$result\n");
fclose($fp);
}
}
if ($result == 'FAILED') {
$failed[] = $t;
}
if ($result == 'PASSED') {
$passed[] = $t;
}
if ($result == 'SKIPPED') {
$skipped[] = $t;
}
$j++;
}
$total = date('i:s', time() - $start);
if (isset($options['tapoutput'])) {
$fp = @fopen('run-tests.log', 'w');
if ($fp) {
fwrite($fp, $tap, strlen($tap));
fclose($fp);
$this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
'"', $command);
}
} else {
if (count($failed)) {
$output = "TOTAL TIME: $total\n";
$output .= count($passed) . " PASSED TESTS\n";
$output .= count($skipped) . " SKIPPED TESTS\n";
$output .= count($failed) . " FAILED TESTS:\n";
foreach ($failed as $failure) {
$output .= $failure . "\n";
}
$mode = isset($options['realtimelog']) ? 'a' : 'w';
$fp = @fopen('run-tests.log', $mode);
if ($fp) {
fwrite($fp, $output, strlen($output));
fclose($fp);
$this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
}
} elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
@unlink('run-tests.log');
}
}
$this->ui->outputData('TOTAL TIME: ' . $total);
$this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
$this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
if (count($failed)) {
$this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
foreach ($failed as $failure) {
$this->ui->outputData($failure, $command);
}
}
if (count($failed) == 0) {
return true;
}
return $this->raiseError('Some tests failed');
}
}

54
vendor/pear-pear.php.net/PEAR/PEAR/Command/Test.xml generated vendored Normal file
View file

@ -0,0 +1,54 @@
<commands version="1.0">
<run-tests>
<summary>Run Regression Tests</summary>
<function>doRunTests</function>
<shortcut>rt</shortcut>
<options>
<recur>
<shortopt>r</shortopt>
<doc>Run tests in child directories, recursively. 4 dirs deep maximum</doc>
</recur>
<ini>
<shortopt>i</shortopt>
<doc>actual string of settings to pass to php in format &quot; -d setting=blah&quot;</doc>
<arg>SETTINGS</arg>
</ini>
<realtimelog>
<shortopt>l</shortopt>
<doc>Log test runs/results as they are run</doc>
</realtimelog>
<quiet>
<shortopt>q</shortopt>
<doc>Only display detail for failed tests</doc>
</quiet>
<simple>
<shortopt>s</shortopt>
<doc>Display simple output for all tests</doc>
</simple>
<package>
<shortopt>p</shortopt>
<doc>Treat parameters as installed packages from which to run tests</doc>
</package>
<phpunit>
<shortopt>u</shortopt>
<doc>Search parameters for AllTests.php, and use that to run phpunit-based tests
If none is found, all .phpt tests will be tried instead.</doc>
</phpunit>
<tapoutput>
<shortopt>t</shortopt>
<doc>Output run-tests.log in TAP-compliant format</doc>
</tapoutput>
<cgi>
<shortopt>c</shortopt>
<doc>CGI php executable (needed for tests with POST/GET section)</doc>
<arg>PHPCGI</arg>
</cgi>
<coverage>
<shortopt>x</shortopt>
<doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc>
</coverage>
</options>
<doc>[testfile|dir ...]
Run regression tests with PHP&#039;s regression testing script (run-tests.php).</doc>
</run-tests>
</commands>

838
vendor/pear-pear.php.net/PEAR/PEAR/Common.php generated vendored Normal file
View file

@ -0,0 +1,838 @@
<?php
/**
* PEAR_Common, the base class for the PEAR Installer
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1.0
* @deprecated File deprecated since Release 1.4.0a1
*/
/**
* Include error handling
*/
require_once 'PEAR.php';
/**
* PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode()
*/
define('PEAR_COMMON_ERROR_INVALIDPHP', 1);
define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+');
define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/');
// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1
define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?');
define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i');
// XXX far from perfect :-)
define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG .
')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG .
'\\z/');
define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+');
define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/');
// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED
define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*');
define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i');
define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')');
define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i');
define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/');
/**
* List of temporary files and directories registered by
* PEAR_Common::addTempFile().
* @var array
*/
$GLOBALS['_PEAR_Common_tempfiles'] = array();
/**
* Valid maintainer roles
* @var array
*/
$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper');
/**
* Valid release states
* @var array
*/
$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel');
/**
* Valid dependency types
* @var array
*/
$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi');
/**
* Valid dependency relations
* @var array
*/
$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne');
/**
* Valid file roles
* @var array
*/
$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script');
/**
* Valid replacement types
* @var array
*/
$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info');
/**
* Valid "provide" types
* @var array
*/
$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api');
/**
* Valid "provide" types
* @var array
*/
$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup');
/**
* Class providing common functionality for PEAR administration classes.
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @deprecated This class will disappear, and its components will be spread
* into smaller classes, like the AT&T breakup, as of Release 1.4.0a1
*/
class PEAR_Common extends PEAR
{
/**
* User Interface object (PEAR_Frontend_* class). If null,
* the log() method uses print.
* @var object
*/
var $ui = null;
/**
* Configuration object (PEAR_Config).
* @var PEAR_Config
*/
var $config = null;
/** stack of elements, gives some sort of XML context */
var $element_stack = array();
/** name of currently parsed XML element */
var $current_element;
/** array of attributes of the currently parsed XML element */
var $current_attributes = array();
/** assoc with information about a package */
var $pkginfo = array();
var $current_path = null;
/**
* Flag variable used to mark a valid package file
* @var boolean
* @access private
*/
var $_validPackageFile;
/**
* PEAR_Common constructor
*
* @access public
*/
function __construct()
{
parent::__construct();
$this->config = &PEAR_Config::singleton();
$this->debug = $this->config->get('verbose');
}
/**
* PEAR_Common destructor
*
* @access private
*/
function _PEAR_Common()
{
// doesn't work due to bug #14744
//$tempfiles = $this->_tempfiles;
$tempfiles =& $GLOBALS['_PEAR_Common_tempfiles'];
while ($file = array_shift($tempfiles)) {
if (@is_dir($file)) {
if (!class_exists('System')) {
require_once 'System.php';
}
System::rm(array('-rf', $file));
} elseif (file_exists($file)) {
unlink($file);
}
}
}
/**
* Register a temporary file or directory. When the destructor is
* executed, all registered temporary files and directories are
* removed.
*
* @param string $file name of file or directory
*
* @return void
*
* @access public
*/
function addTempFile($file)
{
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
}
PEAR_Frontend::addTempFile($file);
}
/**
* Wrapper to System::mkDir(), creates a directory as well as
* any necessary parent directories.
*
* @param string $dir directory name
*
* @return bool TRUE on success, or a PEAR error
*
* @access public
*/
function mkDirHier($dir)
{
// Only used in Installer - move it there ?
$this->log(2, "+ create dir $dir");
if (!class_exists('System')) {
require_once 'System.php';
}
return System::mkDir(array('-p', $dir));
}
/**
* Logging method.
*
* @param int $level log level (0 is quiet, higher is noisier)
* @param string $msg message to write to the log
*
* @return void
*/
public function log($level, $msg, $append_crlf = true)
{
if ($this->debug >= $level) {
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
}
$ui = &PEAR_Frontend::singleton();
if (is_a($ui, 'PEAR_Frontend')) {
$ui->log($msg, $append_crlf);
} else {
print "$msg\n";
}
}
}
/**
* Create and register a temporary directory.
*
* @param string $tmpdir (optional) Directory to use as tmpdir.
* Will use system defaults (for example
* /tmp or c:\windows\temp) if not specified
*
* @return string name of created directory
*
* @access public
*/
function mkTempDir($tmpdir = '')
{
$topt = $tmpdir ? array('-t', $tmpdir) : array();
$topt = array_merge($topt, array('-d', 'pear'));
if (!class_exists('System')) {
require_once 'System.php';
}
if (!$tmpdir = System::mktemp($topt)) {
return false;
}
$this->addTempFile($tmpdir);
return $tmpdir;
}
/**
* Set object that represents the frontend to be used.
*
* @param object Reference of the frontend object
* @return void
* @access public
*/
function setFrontendObject(&$ui)
{
$this->ui = &$ui;
}
/**
* Return an array containing all of the states that are more stable than
* or equal to the passed in state
*
* @param string Release state
* @param boolean Determines whether to include $state in the list
* @return false|array False if $state is not a valid release state
*/
function betterStates($state, $include = false)
{
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
$i = array_search($state, $states);
if ($i === false) {
return false;
}
if ($include) {
$i--;
}
return array_slice($states, $i + 1);
}
/**
* Get the valid roles for a PEAR package maintainer
*
* @return array
*/
public static function getUserRoles()
{
return $GLOBALS['_PEAR_Common_maintainer_roles'];
}
/**
* Get the valid package release states of packages
*
* @return array
*/
public static function getReleaseStates()
{
return $GLOBALS['_PEAR_Common_release_states'];
}
/**
* Get the implemented dependency types (php, ext, pkg etc.)
*
* @return array
*/
public static function getDependencyTypes()
{
return $GLOBALS['_PEAR_Common_dependency_types'];
}
/**
* Get the implemented dependency relations (has, lt, ge etc.)
*
* @return array
*/
public static function getDependencyRelations()
{
return $GLOBALS['_PEAR_Common_dependency_relations'];
}
/**
* Get the implemented file roles
*
* @return array
*/
public static function getFileRoles()
{
return $GLOBALS['_PEAR_Common_file_roles'];
}
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getReplacementTypes()
{
return $GLOBALS['_PEAR_Common_replacement_types'];
}
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getProvideTypes()
{
return $GLOBALS['_PEAR_Common_provide_types'];
}
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getScriptPhases()
{
return $GLOBALS['_PEAR_Common_script_phases'];
}
/**
* Test whether a string contains a valid package name.
*
* @param string $name the package name to test
*
* @return bool
*
* @access public
*/
function validPackageName($name)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name);
}
/**
* Test whether a string contains a valid package version.
*
* @param string $ver the package version to test
*
* @return bool
*
* @access public
*/
function validPackageVersion($ver)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
/**
* @param string $path relative or absolute include path
* @return boolean
*/
public static function isIncludeable($path)
{
if (file_exists($path) && is_readable($path)) {
return true;
}
$ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($ipath as $include) {
$test = realpath($include . DIRECTORY_SEPARATOR . $path);
if (file_exists($test) && is_readable($test)) {
return true;
}
}
return false;
}
function _postProcessChecks($pf)
{
if (!PEAR::isError($pf)) {
return $this->_postProcessValidPackagexml($pf);
}
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
/**
* Returns information about a package file. Expects the name of
* a gzipped tar file as input.
*
* @param string $file name of .tgz file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromTgzFile() instead
*
*/
function infoFromTgzFile($file)
{
$packagefile = new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL);
return $this->_postProcessChecks($pf);
}
/**
* Returns information about a package file. Expects the name of
* a package xml file as input.
*
* @param string $descfile name of package xml file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromPackageFile() instead
*
*/
function infoFromDescriptionFile($descfile)
{
$packagefile = new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
return $this->_postProcessChecks($pf);
}
/**
* Returns information about a package file. Expects the contents
* of a package xml file as input.
*
* @param string $data contents of package.xml file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromXmlstring() instead
*
*/
function infoFromString($data)
{
$packagefile = new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false);
return $this->_postProcessChecks($pf);
}
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return array
*/
function _postProcessValidPackagexml(&$pf)
{
if (!is_a($pf, 'PEAR_PackageFile_v2')) {
$this->pkginfo = $pf->toArray();
return $this->pkginfo;
}
// sort of make this into a package.xml 1.0-style array
// changelog is not converted to old format.
$arr = $pf->toArray(true);
$arr = array_merge($arr, $arr['old']);
unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'],
$arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'],
$arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'],
$arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'],
$arr['helper'], $arr['contributor']);
$arr['filelist'] = $pf->getFilelist();
$this->pkginfo = $arr;
return $arr;
}
/**
* Returns package information from different sources
*
* This method is able to extract information about a package
* from a .tgz archive or from a XML package definition file.
*
* @access public
* @param string Filename of the source ('package.xml', '<package>.tgz')
* @return string
* @deprecated use PEAR_PackageFile->fromAnyFile() instead
*/
function infoFromAny($info)
{
if (is_string($info) && file_exists($info)) {
$packagefile = new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
return $info;
}
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
*
* @param array $pkginfo package info
*
* @return string XML data
*
* @access public
* @deprecated use a PEAR_PackageFile_v* object's generator instead
*/
function xmlFromInfo($pkginfo)
{
$config = &PEAR_Config::singleton();
$packagefile = new PEAR_PackageFile($config);
$pf = &$packagefile->fromArray($pkginfo);
$gen = &$pf->getDefaultGenerator();
return $gen->toXml(PEAR_VALIDATE_PACKAGING);
}
/**
* Validate XML package definition file.
*
* @param string $info Filename of the package archive or of the
* package definition file
* @param array $errors Array that will contain the errors
* @param array $warnings Array that will contain the warnings
* @param string $dir_prefix (optional) directory where source files
* may be found, or empty if they are not available
* @access public
* @return boolean
* @deprecated use the validation of PEAR_PackageFile objects
*/
function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '')
{
$config = &PEAR_Config::singleton();
$packagefile = new PEAR_PackageFile($config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (strpos($info, '<?xml') !== false) {
$pf = &$packagefile->fromXmlString($info, PEAR_VALIDATE_NORMAL, '');
} else {
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
if ($error['level'] == 'error') {
$errors[] = $error['message'];
} else {
$warnings[] = $error['message'];
}
}
}
return false;
}
return true;
}
/**
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
* this:
*
* array(
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
* ...
* )
*
*
* @param array $srcinfo array with information about a source file
* as returned by the analyzeSourceCode() method.
*
* @return void
*
* @access public
*
*/
function buildProvidesArray($srcinfo)
{
$file = basename($srcinfo['source_file']);
$pn = '';
if (isset($this->_packageName)) {
$pn = $this->_packageName;
}
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
if (isset($this->pkginfo['provides'][$key])) {
continue;
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
$this->pkginfo['provides'][$key]['extends'] =
$srcinfo['inheritance'][$class];
}
}
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
if ($method{0} == '_' || !strcasecmp($method, $class) ||
isset($this->pkginfo['provides'][$key])) {
continue;
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) {
continue;
}
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
/**
* Analyze the source code of the given PHP file
*
* @param string Filename of the PHP file
* @return mixed
* @access public
*/
function analyzeSourceCode($file)
{
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
}
$a = new PEAR_PackageFile_v2_Validator;
return $a->analyzeSourceCode($file);
}
function detectDependencies($any, $status_callback = null)
{
if (!function_exists("token_get_all")) {
return false;
}
if (PEAR::isError($info = $this->infoFromAny($any))) {
return $this->raiseError($info);
}
if (!is_array($info)) {
return false;
}
$deps = array();
$used_c = $decl_c = $decl_f = $decl_m = array();
foreach ($info['filelist'] as $file => $fa) {
$tmp = $this->analyzeSourceCode($file);
$used_c = @array_merge($used_c, $tmp['used_classes']);
$decl_c = @array_merge($decl_c, $tmp['declared_classes']);
$decl_f = @array_merge($decl_f, $tmp['declared_functions']);
$decl_m = @array_merge($decl_m, $tmp['declared_methods']);
$inheri = @array_merge($inheri, $tmp['inheritance']);
}
$used_c = array_unique($used_c);
$decl_c = array_unique($decl_c);
$undecl_c = array_diff($used_c, $decl_c);
return array('used_classes' => $used_c,
'declared_classes' => $decl_c,
'declared_methods' => $decl_m,
'declared_functions' => $decl_f,
'undeclared_classes' => $undecl_c,
'inheritance' => $inheri,
);
}
/**
* Download a file through HTTP. Considers suggested file name in
* Content-disposition: header and can run a callback function for
* different events. The callback will be called with two
* parameters: the callback type, and parameters. The implemented
* callback types are:
*
* 'setup' called at the very beginning, parameter is a UI object
* that should be used for all output
* 'message' the parameter is a string with an informational message
* 'saveas' may be used to save with a different file name, the
* parameter is the filename that is about to be used.
* If a 'saveas' callback returns a non-empty string,
* that file name will be used as the filename instead.
* Note that $save_dir will not be affected by this, only
* the basename of the file.
* 'start' download is starting, parameter is number of bytes
* that are expected, or -1 if unknown
* 'bytesread' parameter is the number of bytes read so far
* 'done' download is complete, parameter is the total number
* of bytes read
* 'connfailed' if the TCP connection fails, this callback is called
* with array(host,port,errno,errmsg)
* 'writefailed' if writing to disk fails, this callback is called
* with array(destfile,errmsg)
*
* If an HTTP proxy has been configured (http_proxy PEAR_Config
* setting), the proxy will be used.
*
* @param string $url the URL to download
* @param object $ui PEAR_Frontend_* instance
* @param object $config PEAR_Config instance
* @param string $save_dir (optional) directory to save file in
* @param mixed $callback (optional) function/method to call for status
* updates
* @param false|string|array $lastmodified header values to check against
* for caching
* use false to return the header
* values from this download
* @param false|array $accept Accept headers to send
* @param false|string $channel Channel to use for retrieving
* authentication
*
* @return mixed Returns the full path of the downloaded file or a PEAR
* error on failure. If the error is caused by
* socket-related errors, the error object will
* have the fsockopen error code available through
* getCode(). If caching is requested, then return the header
* values.
* If $lastmodified was given and the there are no changes,
* boolean false is returned.
*
* @access public
*/
function downloadHttp(
$url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false, $channel = false
) {
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
return PEAR_Downloader::_downloadHttp(
$this, $url, $ui, $save_dir, $callback, $lastmodified,
$accept, $channel
);
}
}
require_once 'PEAR/Config.php';
require_once 'PEAR/PackageFile.php';

2131
vendor/pear-pear.php.net/PEAR/PEAR/Config.php generated vendored Normal file

File diff suppressed because it is too large Load diff

1357
vendor/pear-pear.php.net/PEAR/PEAR/Dependency2.php generated vendored Normal file

File diff suppressed because it is too large Load diff

764
vendor/pear-pear.php.net/PEAR/PEAR/DependencyDB.php generated vendored Normal file
View file

@ -0,0 +1,764 @@
<?php
/**
* PEAR_DependencyDB, advanced installed packages dependency database
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Needed for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Config.php';
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
/**
* Track dependency relationships between installed packages
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Tomas V.V.Cox <cox@idec.net.com>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.3
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_DependencyDB
{
// {{{ properties
/**
* This is initialized by {@link setConfig()}
* @var PEAR_Config
* @access private
*/
var $_config;
/**
* This is initialized by {@link setConfig()}
* @var PEAR_Registry
* @access private
*/
var $_registry;
/**
* Filename of the dependency DB (usually .depdb)
* @var string
* @access private
*/
var $_depdb = false;
/**
* File name of the lockfile (usually .depdblock)
* @var string
* @access private
*/
var $_lockfile = false;
/**
* Open file resource for locking the lockfile
* @var resource|false
* @access private
*/
var $_lockFp = false;
/**
* API version of this class, used to validate a file on-disk
* @var string
* @access private
*/
var $_version = '1.0';
/**
* Cached dependency database file
* @var array|null
* @access private
*/
var $_cache;
// }}}
// {{{ & singleton()
/**
* Get a raw dependency database. Calls setConfig() and assertDepsDB()
* @param PEAR_Config
* @param string|false full path to the dependency database, or false to use default
* @return PEAR_DependencyDB|PEAR_Error
*/
public static function &singleton(&$config, $depdb = false)
{
$phpdir = $config->get('php_dir', null, 'pear.php.net');
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
$a = new PEAR_DependencyDB;
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a;
$a->setConfig($config, $depdb);
$e = $a->assertDepsDB();
if (PEAR::isError($e)) {
return $e;
}
}
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
}
/**
* Set up the registry/location of dependency DB
* @param PEAR_Config|false
* @param string|false full path to the dependency database, or false to use default
*/
function setConfig(&$config, $depdb = false)
{
if (!$config) {
$this->_config = &PEAR_Config::singleton();
} else {
$this->_config = &$config;
}
$this->_registry = &$this->_config->getRegistry();
if (!$depdb) {
$dir = $this->_config->get('metadata_dir', null, 'pear.php.net');
if (!$dir) {
$dir = $this->_config->get('php_dir', null, 'pear.php.net');
}
$this->_depdb = $dir . DIRECTORY_SEPARATOR . '.depdb';
} else {
$this->_depdb = $depdb;
}
$this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
}
// }}}
function hasWriteAccess()
{
if (!file_exists($this->_depdb)) {
$dir = $this->_depdb;
while ($dir && $dir != '.') {
$dir = dirname($dir); // cd ..
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
}
return false;
}
}
return false;
}
return is_writeable($this->_depdb);
}
// {{{ assertDepsDB()
/**
* Create the dependency database, if it doesn't exist. Error if the database is
* newer than the code reading it.
* @return void|PEAR_Error
*/
function assertDepsDB()
{
if (!is_file($this->_depdb)) {
$this->rebuildDB();
return;
}
$depdb = $this->_getDepDB();
// Datatype format has been changed, rebuild the Deps DB
if ($depdb['_version'] < $this->_version) {
$this->rebuildDB();
}
if ($depdb['_version']{0} > $this->_version{0}) {
return PEAR::raiseError('Dependency database is version ' .
$depdb['_version'] . ', and we are version ' .
$this->_version . ', cannot continue');
}
}
/**
* Get a list of installed packages that depend on this package
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependentPackages(&$pkg)
{
$data = $this->_getDepDB();
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
if (isset($data['packages'][$channel][$package])) {
return $data['packages'][$channel][$package];
}
return false;
}
/**
* Get a list of the actual dependencies of installed packages that depend on
* a package.
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependentPackageDependencies(&$pkg)
{
$data = $this->_getDepDB();
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
$depend = $this->getDependentPackages($pkg);
if (!$depend) {
return false;
}
$dependencies = array();
foreach ($depend as $info) {
$temp = $this->getDependencies($info);
foreach ($temp as $dep) {
if (
isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) &&
strtolower($dep['dep']['channel']) == $channel &&
strtolower($dep['dep']['name']) == $package
) {
if (!isset($dependencies[$info['channel']])) {
$dependencies[$info['channel']] = array();
}
if (!isset($dependencies[$info['channel']][$info['package']])) {
$dependencies[$info['channel']][$info['package']] = array();
}
$dependencies[$info['channel']][$info['package']][] = $dep;
}
}
}
return $dependencies;
}
/**
* Get a list of dependencies of this installed package
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependencies(&$pkg)
{
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
$data = $this->_getDepDB();
if (isset($data['dependencies'][$channel][$package])) {
return $data['dependencies'][$channel][$package];
}
return false;
}
/**
* Determine whether $parent depends on $child, near or deep
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
*/
function dependsOn($parent, $child)
{
$c = array();
$this->_getDepDB();
return $this->_dependsOn($parent, $child, $c);
}
function _dependsOn($parent, $child, &$checked)
{
if (is_object($parent)) {
$channel = strtolower($parent->getChannel());
$package = strtolower($parent->getPackage());
} else {
$channel = strtolower($parent['channel']);
$package = strtolower($parent['package']);
}
if (is_object($child)) {
$depchannel = strtolower($child->getChannel());
$deppackage = strtolower($child->getPackage());
} else {
$depchannel = strtolower($child['channel']);
$deppackage = strtolower($child['package']);
}
if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
return false; // avoid endless recursion
}
$checked[$channel][$package][$depchannel][$deppackage] = true;
if (!isset($this->_cache['dependencies'][$channel][$package])) {
return false;
}
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
if (isset($info['dep']['uri'])) {
if (is_object($child)) {
if ($info['dep']['uri'] == $child->getURI()) {
return true;
}
} elseif (isset($child['uri'])) {
if ($info['dep']['uri'] == $child['uri']) {
return true;
}
}
return false;
}
if (strtolower($info['dep']['channel']) == $depchannel &&
strtolower($info['dep']['name']) == $deppackage) {
return true;
}
}
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
if (isset($info['dep']['uri'])) {
if ($this->_dependsOn(array(
'uri' => $info['dep']['uri'],
'package' => $info['dep']['name']), $child, $checked)) {
return true;
}
} else {
if ($this->_dependsOn(array(
'channel' => $info['dep']['channel'],
'package' => $info['dep']['name']), $child, $checked)) {
return true;
}
}
}
return false;
}
/**
* Register dependencies of a package that is being installed or upgraded
* @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
*/
function installPackage(&$package)
{
$data = $this->_getDepDB();
unset($this->_cache);
$this->_setPackageDeps($data, $package);
$this->_writeDepDB($data);
}
/**
* Remove dependencies of a package that is being uninstalled, or upgraded.
*
* Upgraded packages first uninstall, then install
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
* indices 'channel' and 'package'
*/
function uninstallPackage(&$pkg)
{
$data = $this->_getDepDB();
unset($this->_cache);
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
if (!isset($data['dependencies'][$channel][$package])) {
return true;
}
foreach ($data['dependencies'][$channel][$package] as $dep) {
$found = false;
$depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']);
$depname = strtolower($dep['dep']['name']);
if (isset($data['packages'][$depchannel][$depname])) {
foreach ($data['packages'][$depchannel][$depname] as $i => $info) {
if ($info['channel'] == $channel && $info['package'] == $package) {
$found = true;
break;
}
}
}
if ($found) {
unset($data['packages'][$depchannel][$depname][$i]);
if (!count($data['packages'][$depchannel][$depname])) {
unset($data['packages'][$depchannel][$depname]);
if (!count($data['packages'][$depchannel])) {
unset($data['packages'][$depchannel]);
}
} else {
$data['packages'][$depchannel][$depname] =
array_values($data['packages'][$depchannel][$depname]);
}
}
}
unset($data['dependencies'][$channel][$package]);
if (!count($data['dependencies'][$channel])) {
unset($data['dependencies'][$channel]);
}
if (!count($data['dependencies'])) {
unset($data['dependencies']);
}
if (!count($data['packages'])) {
unset($data['packages']);
}
$this->_writeDepDB($data);
}
/**
* Rebuild the dependency DB by reading registry entries.
* @return true|PEAR_Error
*/
function rebuildDB()
{
$depdb = array('_version' => $this->_version);
if (!$this->hasWriteAccess()) {
// allow startup for read-only with older Registry
return $depdb;
}
$packages = $this->_registry->listAllPackages();
if (PEAR::isError($packages)) {
return $packages;
}
foreach ($packages as $channel => $ps) {
foreach ($ps as $package) {
$package = $this->_registry->getPackage($package, $channel);
if (PEAR::isError($package)) {
return $package;
}
$this->_setPackageDeps($depdb, $package);
}
}
$error = $this->_writeDepDB($depdb);
if (PEAR::isError($error)) {
return $error;
}
$this->_cache = $depdb;
return true;
}
/**
* Register usage of the dependency DB to prevent race conditions
* @param int one of the LOCK_* constants
* @return true|PEAR_Error
* @access private
*/
function _lock($mode = LOCK_EX)
{
if (stristr(php_uname(), 'Windows 9')) {
return true;
}
if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
$open_mode = 'w';
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH) {
if (!file_exists($this->_lockfile)) {
touch($this->_lockfile);
} elseif (!is_file($this->_lockfile)) {
return PEAR::raiseError('could not create Dependency lock file, ' .
'it exists and is not a regular file');
}
$open_mode = 'r';
}
if (!is_resource($this->_lockFp)) {
$this->_lockFp = @fopen($this->_lockfile, $open_mode);
}
if (!is_resource($this->_lockFp)) {
return PEAR::raiseError("could not create Dependency lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
}
if (!(int)flock($this->_lockFp, $mode)) {
switch ($mode) {
case LOCK_SH: $str = 'shared'; break;
case LOCK_EX: $str = 'exclusive'; break;
case LOCK_UN: $str = 'unlock'; break;
default: $str = 'unknown'; break;
}
return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
}
return true;
}
/**
* Release usage of dependency DB
* @return true|PEAR_Error
* @access private
*/
function _unlock()
{
$ret = $this->_lock(LOCK_UN);
if (is_resource($this->_lockFp)) {
fclose($this->_lockFp);
}
$this->_lockFp = null;
return $ret;
}
/**
* Load the dependency database from disk, or return the cache
* @return array|PEAR_Error
*/
function _getDepDB()
{
if (!$this->hasWriteAccess()) {
return array('_version' => $this->_version);
}
if (isset($this->_cache)) {
return $this->_cache;
}
if (!$fp = fopen($this->_depdb, 'r')) {
$err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
return $err;
}
clearstatcache();
fclose($fp);
$data = unserialize(file_get_contents($this->_depdb));
$this->_cache = $data;
return $data;
}
/**
* Write out the dependency database to disk
* @param array the database
* @return true|PEAR_Error
* @access private
*/
function _writeDepDB(&$deps)
{
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
if (!$fp = fopen($this->_depdb, 'wb')) {
$this->_unlock();
return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
}
fwrite($fp, serialize($deps));
fclose($fp);
$this->_unlock();
$this->_cache = $deps;
return true;
}
/**
* Register all dependencies from a package in the dependencies database, in essence
* "installing" the package's dependency information
* @param array the database
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @access private
*/
function _setPackageDeps(&$data, &$pkg)
{
$pkg->setConfig($this->_config);
if ($pkg->getPackagexmlVersion() == '1.0') {
$gen = &$pkg->getDefaultGenerator();
$deps = $gen->dependenciesToV2();
} else {
$deps = $pkg->getDeps(true);
}
if (!$deps) {
return;
}
if (!is_array($data)) {
$data = array();
}
if (!isset($data['dependencies'])) {
$data['dependencies'] = array();
}
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
if (!isset($data['dependencies'][$channel])) {
$data['dependencies'][$channel] = array();
}
$data['dependencies'][$channel][$package] = array();
if (isset($deps['required']['package'])) {
if (!isset($deps['required']['package'][0])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'required');
}
}
if (isset($deps['optional']['package'])) {
if (!isset($deps['optional']['package'][0])) {
$deps['optional']['package'] = array($deps['optional']['package']);
}
foreach ($deps['optional']['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional');
}
}
if (isset($deps['required']['subpackage'])) {
if (!isset($deps['required']['subpackage'][0])) {
$deps['required']['subpackage'] = array($deps['required']['subpackage']);
}
foreach ($deps['required']['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'required');
}
}
if (isset($deps['optional']['subpackage'])) {
if (!isset($deps['optional']['subpackage'][0])) {
$deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
}
foreach ($deps['optional']['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional');
}
}
if (isset($deps['group'])) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
foreach ($deps['group'] as $group) {
if (isset($group['package'])) {
if (!isset($group['package'][0])) {
$group['package'] = array($group['package']);
}
foreach ($group['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional',
$group['attribs']['name']);
}
}
if (isset($group['subpackage'])) {
if (!isset($group['subpackage'][0])) {
$group['subpackage'] = array($group['subpackage']);
}
foreach ($group['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional',
$group['attribs']['name']);
}
}
}
}
if ($data['dependencies'][$channel][$package] == array()) {
unset($data['dependencies'][$channel][$package]);
if (!count($data['dependencies'][$channel])) {
unset($data['dependencies'][$channel]);
}
}
}
/**
* @param array the database
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param array the specific dependency
* @param required|optional whether this is a required or an optional dep
* @param string|false dependency group this dependency is from, or false for ordinary dep
*/
function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
{
$info = array(
'dep' => $dep,
'type' => $type,
'group' => $group
);
$dep = array_map('strtolower', $dep);
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
if (!isset($data['dependencies'])) {
$data['dependencies'] = array();
}
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
if (!isset($data['dependencies'][$channel])) {
$data['dependencies'][$channel] = array();
}
if (!isset($data['dependencies'][$channel][$package])) {
$data['dependencies'][$channel][$package] = array();
}
$data['dependencies'][$channel][$package][] = $info;
if (isset($data['packages'][$depchannel][$dep['name']])) {
$found = false;
foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) {
if ($p['channel'] == $channel && $p['package'] == $package) {
$found = true;
break;
}
}
} else {
if (!isset($data['packages'])) {
$data['packages'] = array();
}
if (!isset($data['packages'][$depchannel])) {
$data['packages'][$depchannel] = array();
}
if (!isset($data['packages'][$depchannel][$dep['name']])) {
$data['packages'][$depchannel][$dep['name']] = array();
}
$found = false;
}
if (!$found) {
$data['packages'][$depchannel][$dep['name']][] = array(
'channel' => $channel,
'package' => $package
);
}
}
}

1763
vendor/pear-pear.php.net/PEAR/PEAR/Downloader.php generated vendored Normal file

File diff suppressed because it is too large Load diff

1981
vendor/pear-pear.php.net/PEAR/PEAR/Downloader/Package.php generated vendored Normal file

File diff suppressed because it is too large Load diff

979
vendor/pear-pear.php.net/PEAR/PEAR/ErrorStack.php generated vendored Normal file
View file

@ -0,0 +1,979 @@
<?php
/**
* Error Stack Implementation
*
* This is an incredibly simple implementation of a very complex error handling
* facility. It contains the ability
* to track multiple errors from multiple packages simultaneously. In addition,
* it can track errors of many levels, save data along with the error, context
* information such as the exact file, line number, class and function that
* generated the error, and if necessary, it can raise a traditional PEAR_Error.
* It has built-in support for PEAR::Log, to log errors as they occur
*
* Since version 0.2alpha, it is also possible to selectively ignore errors,
* through the use of an error callback, see {@link pushCallback()}
*
* Since version 0.3alpha, it is possible to specify the exception class
* returned from {@link push()}
*
* Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
* still be done quite handily in an error callback or by manipulating the returned array
* @category Debugging
* @package PEAR_ErrorStack
* @author Greg Beaver <cellog@php.net>
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
/**
* Singleton storage
*
* Format:
* <pre>
* array(
* 'package1' => PEAR_ErrorStack object,
* 'package2' => PEAR_ErrorStack object,
* ...
* )
* </pre>
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
*/
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
/**
* Global error callback (default)
*
* This is only used if set to non-false. * is the default callback for
* all packages, whereas specific packages may set a default callback
* for all instances, regardless of whether they are a singleton or not.
*
* To exclude non-singletons, only set the local callback for the singleton
* @see PEAR_ErrorStack::setDefaultCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
'*' => false,
);
/**
* Global Log object (default)
*
* This is only used if set to non-false. Use to set a default log object for
* all stacks, regardless of instantiation order or location
* @see PEAR_ErrorStack::setDefaultLogger()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
/**
* Global Overriding Callback
*
* This callback will override any error callbacks that specific loggers have set.
* Use with EXTREME caution
* @see PEAR_ErrorStack::staticPushCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
/**#@+
* One of four possible return values from the error Callback
* @see PEAR_ErrorStack::_errorCallback()
*/
/**
* If this is returned, then the error will be both pushed onto the stack
* and logged.
*/
define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
/**
* If this is returned, then the error will only be pushed onto the stack,
* and not logged.
*/
define('PEAR_ERRORSTACK_PUSH', 2);
/**
* If this is returned, then the error will only be logged, but not pushed
* onto the error stack.
*/
define('PEAR_ERRORSTACK_LOG', 3);
/**
* If this is returned, then the error is completely ignored.
*/
define('PEAR_ERRORSTACK_IGNORE', 4);
/**
* If this is returned, then the error is logged and die() is called.
*/
define('PEAR_ERRORSTACK_DIE', 5);
/**#@-*/
/**
* Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
* the singleton method.
*/
define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
/**
* Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
* that has no __toString() method
*/
define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
/**
* Error Stack Implementation
*
* Usage:
* <code>
* // global error stack
* $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
* // local error stack
* $local_stack = new PEAR_ErrorStack('MyPackage');
* </code>
* @author Greg Beaver <cellog@php.net>
* @version 1.10.3
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
class PEAR_ErrorStack {
/**
* Errors are stored in the order that they are pushed on the stack.
* @since 0.4alpha Errors are no longer organized by error level.
* This renders pop() nearly unusable, and levels could be more easily
* handled in a callback anyway
* @var array
* @access private
*/
var $_errors = array();
/**
* Storage of errors by level.
*
* Allows easy retrieval and deletion of only errors from a particular level
* @since PEAR 1.4.0dev
* @var array
* @access private
*/
var $_errorsByLevel = array();
/**
* Package name this error stack represents
* @var string
* @access protected
*/
var $_package;
/**
* Determines whether a PEAR_Error is thrown upon every error addition
* @var boolean
* @access private
*/
var $_compat = false;
/**
* If set to a valid callback, this will be used to generate the error
* message from the error code, otherwise the message passed in will be
* used
* @var false|string|array
* @access private
*/
var $_msgCallback = false;
/**
* If set to a valid callback, this will be used to generate the error
* context for an error. For PHP-related errors, this will be a file
* and line number as retrieved from debug_backtrace(), but can be
* customized for other purposes. The error might actually be in a separate
* configuration file, or in a database query.
* @var false|string|array
* @access protected
*/
var $_contextCallback = false;
/**
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one an PEAR_ERRORSTACK_* constant
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @var false|string|array
* @access protected
*/
var $_errorCallback = array();
/**
* PEAR::Log object for logging errors
* @var false|Log
* @access protected
*/
var $_logger = false;
/**
* Error messages - designed to be overridden
* @var array
* @abstract
*/
var $_errorMsgs = array();
/**
* Set up a new error stack
*
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
*/
function __construct($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false)
{
$this->_package = $package;
$this->setMessageCallback($msgCallback);
$this->setContextCallback($contextCallback);
$this->_compat = $throwPEAR_Error;
}
/**
* Return a single error stack for this package.
*
* Note that all parameters are ignored if the stack for package $package
* has already been instantiated
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
* @param string $stackClass class to instantiate
*
* @return PEAR_ErrorStack
*/
public static function &singleton(
$package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'
) {
if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
if (!class_exists($stackClass)) {
if (function_exists('debug_backtrace')) {
$trace = debug_backtrace();
}
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
'exception', array('stackclass' => $stackClass),
'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
false, $trace);
}
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
/**
* Internal error handler for PEAR_ErrorStack class
*
* Dies if the error is an exception (and would have died anyway)
* @access private
*/
function _handleError($err)
{
if ($err['level'] == 'exception') {
$message = $err['message'];
if (isset($_SERVER['REQUEST_URI'])) {
echo '<br />';
} else {
echo "\n";
}
var_dump($err['context']);
die($message);
}
}
/**
* Set up a PEAR::Log object for all error stacks that don't have one
* @param Log $log
*/
public static function setDefaultLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
} elseif (is_callable($log)) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
}
}
/**
* Set up a PEAR::Log object for this error stack
* @param Log $log
*/
function setLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$this->_logger = &$log;
} elseif (is_callable($log)) {
$this->_logger = &$log;
}
}
/**
* Set an error code => error message mapping callback
*
* This method sets the callback that can be used to generate error
* messages for any instance
* @param array|string Callback function/method
*/
function setMessageCallback($msgCallback)
{
if (!$msgCallback) {
$this->_msgCallback = array(&$this, 'getErrorMessage');
} else {
if (is_callable($msgCallback)) {
$this->_msgCallback = $msgCallback;
}
}
}
/**
* Get an error code => error message mapping callback
*
* This method returns the current callback that can be used to generate error
* messages
* @return array|string|false Callback function/method or false if none
*/
function getMessageCallback()
{
return $this->_msgCallback;
}
/**
* Sets a default callback to be used by all error stacks
*
* This method sets the callback that can be used to generate error
* messages for a singleton
* @param array|string Callback function/method
* @param string Package name, or false for all packages
*/
public static function setDefaultCallback($callback = false, $package = false)
{
if (!is_callable($callback)) {
$callback = false;
}
$package = $package ? $package : '*';
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
}
/**
* Set a callback that generates context information (location of error) for an error stack
*
* This method sets the callback that can be used to generate context
* information for an error. Passing in NULL will disable context generation
* and remove the expensive call to debug_backtrace()
* @param array|string|null Callback function/method
*/
function setContextCallback($contextCallback)
{
if ($contextCallback === null) {
return $this->_contextCallback = false;
}
if (!$contextCallback) {
$this->_contextCallback = array(&$this, 'getFileLine');
} else {
if (is_callable($contextCallback)) {
$this->_contextCallback = $contextCallback;
}
}
}
/**
* Set an error Callback
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one of the ERRORSTACK_* constants.
*
* This functionality can be used to emulate PEAR's pushErrorHandling, and
* the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
* the error stack or logging
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see popCallback()
* @param string|array $cb
*/
function pushCallback($cb)
{
array_push($this->_errorCallback, $cb);
}
/**
* Remove a callback from the error callback stack
* @see pushCallback()
* @return array|string|false
*/
function popCallback()
{
if (!count($this->_errorCallback)) {
return false;
}
return array_pop($this->_errorCallback);
}
/**
* Set a temporary overriding error callback for every package error stack
*
* Use this to temporarily disable all existing callbacks (can be used
* to emulate the @ operator, for instance)
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see staticPopCallback(), pushCallback()
* @param string|array $cb
*/
public static function staticPushCallback($cb)
{
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
}
/**
* Remove a temporary overriding error callback
* @see staticPushCallback()
* @return array|string|false
*/
public static function staticPopCallback()
{
$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
}
return $ret;
}
/**
* Add an error to the stack
*
* If the message generator exists, it is called with 2 parameters.
* - the current Error Stack object
* - an array that is in the same format as an error. Available indices
* are 'code', 'package', 'time', 'params', 'level', and 'context'
*
* Next, if the error should contain context information, this is
* handled by the context grabbing method.
* Finally, the error is pushed onto the proper error stack
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. If a PEAR_Error is returned, the userinfo
* property is set to the following array:
*
* <code>
* array(
* 'code' => $code,
* 'params' => $params,
* 'package' => $this->_package,
* 'level' => $level,
* 'time' => time(),
* 'context' => $context,
* 'message' => $msg,
* //['repackage' => $err] repackaged error array/Exception class
* );
* </code>
*
* Normally, the previous array is returned.
*/
function push($code, $level = 'error', $params = array(), $msg = false,
$repackage = false, $backtrace = false)
{
$context = false;
// grab error context
if ($this->_contextCallback) {
if (!$backtrace) {
$backtrace = debug_backtrace();
}
$context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
}
// save error
$time = explode(' ', microtime());
$time = $time[1] + $time[0];
$err = array(
'code' => $code,
'params' => $params,
'package' => $this->_package,
'level' => $level,
'time' => $time,
'context' => $context,
'message' => $msg,
);
if ($repackage) {
$err['repackage'] = $repackage;
}
// set up the error message, if necessary
if ($this->_msgCallback) {
$msg = call_user_func_array($this->_msgCallback,
array(&$this, $err));
$err['message'] = $msg;
}
$push = $log = true;
$die = false;
// try the overriding callback first
$callback = $this->staticPopCallback();
if ($callback) {
$this->staticPushCallback($callback);
}
if (!is_callable($callback)) {
// try the local callback next
$callback = $this->popCallback();
if (is_callable($callback)) {
$this->pushCallback($callback);
} else {
// try the default callback
$callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
}
}
if (is_callable($callback)) {
switch(call_user_func($callback, $err)){
case PEAR_ERRORSTACK_IGNORE:
return $err;
break;
case PEAR_ERRORSTACK_PUSH:
$log = false;
break;
case PEAR_ERRORSTACK_LOG:
$push = false;
break;
case PEAR_ERRORSTACK_DIE:
$die = true;
break;
// anything else returned has the same effect as pushandlog
}
}
if ($push) {
array_unshift($this->_errors, $err);
if (!isset($this->_errorsByLevel[$err['level']])) {
$this->_errorsByLevel[$err['level']] = array();
}
$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
}
if ($log) {
if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
$this->_log($err);
}
}
if ($die) {
die();
}
if ($this->_compat && $push) {
return $this->raiseError($msg, $code, null, null, $err);
}
return $err;
}
/**
* Static version of {@link push()}
*
* @param string $package Package name this error belongs to
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. see docs for {@link push()}
*/
public static function staticPush(
$package, $code, $level = 'error', $params = array(),
$msg = false, $repackage = false, $backtrace = false
) {
$s = &PEAR_ErrorStack::singleton($package);
if ($s->_contextCallback) {
if (!$backtrace) {
if (function_exists('debug_backtrace')) {
$backtrace = debug_backtrace();
}
}
}
return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
}
/**
* Log an error using PEAR::Log
* @param array $err Error array
* @param array $levels Error level => Log constant map
* @access protected
*/
function _log($err)
{
if ($this->_logger) {
$logger = &$this->_logger;
} else {
$logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
}
if (is_a($logger, 'Log')) {
$levels = array(
'exception' => PEAR_LOG_CRIT,
'alert' => PEAR_LOG_ALERT,
'critical' => PEAR_LOG_CRIT,
'error' => PEAR_LOG_ERR,
'warning' => PEAR_LOG_WARNING,
'notice' => PEAR_LOG_NOTICE,
'info' => PEAR_LOG_INFO,
'debug' => PEAR_LOG_DEBUG);
if (isset($levels[$err['level']])) {
$level = $levels[$err['level']];
} else {
$level = PEAR_LOG_INFO;
}
$logger->log($err['message'], $level, $err);
} else { // support non-standard logs
call_user_func($logger, $err);
}
}
/**
* Pop an error off of the error stack
*
* @return false|array
* @since 0.4alpha it is no longer possible to specify a specific error
* level to return - the last error pushed will be returned, instead
*/
function pop()
{
$err = @array_shift($this->_errors);
if (!is_null($err)) {
@array_pop($this->_errorsByLevel[$err['level']]);
if (!count($this->_errorsByLevel[$err['level']])) {
unset($this->_errorsByLevel[$err['level']]);
}
}
return $err;
}
/**
* Pop an error off of the error stack, static method
*
* @param string package name
* @return boolean
* @since PEAR1.5.0a1
*/
function staticPop($package)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
}
}
/**
* Determine whether there are any errors on the stack
* @param string|array Level name. Use to determine if any errors
* of level (string), or levels (array) have been pushed
* @return boolean
*/
function hasErrors($level = false)
{
if ($level) {
return isset($this->_errorsByLevel[$level]);
}
return count($this->_errors);
}
/**
* Retrieve all errors since last purge
*
* @param boolean set in order to empty the error stack
* @param string level name, to return only errors of a particular severity
* @return array
*/
function getErrors($purge = false, $level = false)
{
if (!$purge) {
if ($level) {
if (!isset($this->_errorsByLevel[$level])) {
return array();
} else {
return $this->_errorsByLevel[$level];
}
} else {
return $this->_errors;
}
}
if ($level) {
$ret = $this->_errorsByLevel[$level];
foreach ($this->_errorsByLevel[$level] as $i => $unused) {
// entries are references to the $_errors array
$this->_errorsByLevel[$level][$i] = false;
}
// array_filter removes all entries === false
$this->_errors = array_filter($this->_errors);
unset($this->_errorsByLevel[$level]);
return $ret;
}
$ret = $this->_errors;
$this->_errors = array();
$this->_errorsByLevel = array();
return $ret;
}
/**
* Determine whether there are any errors on a single error stack, or on any error stack
*
* The optional parameter can be used to test the existence of any errors without the need of
* singleton instantiation
* @param string|false Package name to check for errors
* @param string Level name to check for a particular severity
* @return boolean
*/
public static function staticHasErrors($package = false, $level = false)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
if ($obj->hasErrors($level)) {
return true;
}
}
return false;
}
/**
* Get a list of all errors since last purge, organized by package
* @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
* @param boolean $purge Set to purge the error stack of existing errors
* @param string $level Set to a level name in order to retrieve only errors of a particular level
* @param boolean $merge Set to return a flat array, not organized by package
* @param array $sortfunc Function used to sort a merged array - default
* sorts by time, and should be good for most cases
*
* @return array
*/
public static function staticGetErrors(
$purge = false, $level = false, $merge = false,
$sortfunc = array('PEAR_ErrorStack', '_sortErrors')
) {
$ret = array();
if (!is_callable($sortfunc)) {
$sortfunc = array('PEAR_ErrorStack', '_sortErrors');
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
$test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
if ($test) {
if ($merge) {
$ret = array_merge($ret, $test);
} else {
$ret[$package] = $test;
}
}
}
if ($merge) {
usort($ret, $sortfunc);
}
return $ret;
}
/**
* Error sorting function, sorts by time
* @access private
*/
public static function _sortErrors($a, $b)
{
if ($a['time'] == $b['time']) {
return 0;
}
if ($a['time'] < $b['time']) {
return 1;
}
return -1;
}
/**
* Standard file/line number/function/class context callback
*
* This function uses a backtrace generated from {@link debug_backtrace()}
* and so will not work at all in PHP < 4.3.0. The frame should
* reference the frame that contains the source of the error.
* @return array|false either array('file' => file, 'line' => line,
* 'function' => function name, 'class' => class name) or
* if this doesn't work, then false
* @param unused
* @param integer backtrace frame.
* @param array Results of debug_backtrace()
*/
public static function getFileLine($code, $params, $backtrace = null)
{
if ($backtrace === null) {
return false;
}
$frame = 0;
$functionframe = 1;
if (!isset($backtrace[1])) {
$functionframe = 0;
} else {
while (isset($backtrace[$functionframe]['function']) &&
$backtrace[$functionframe]['function'] == 'eval' &&
isset($backtrace[$functionframe + 1])) {
$functionframe++;
}
}
if (isset($backtrace[$frame])) {
if (!isset($backtrace[$frame]['file'])) {
$frame++;
}
$funcbacktrace = $backtrace[$functionframe];
$filebacktrace = $backtrace[$frame];
$ret = array('file' => $filebacktrace['file'],
'line' => $filebacktrace['line']);
// rearrange for eval'd code or create function errors
if (strpos($filebacktrace['file'], '(') &&
preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
$matches)) {
$ret['file'] = $matches[1];
$ret['line'] = $matches[2] + 0;
}
if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
if ($funcbacktrace['function'] != 'eval') {
if ($funcbacktrace['function'] == '__lambda_func') {
$ret['function'] = 'create_function() code';
} else {
$ret['function'] = $funcbacktrace['function'];
}
}
}
if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
$ret['class'] = $funcbacktrace['class'];
}
return $ret;
}
return false;
}
/**
* Standard error message generation callback
*
* This method may also be called by a custom error message generator
* to fill in template values from the params array, simply
* set the third parameter to the error message template string to use
*
* The special variable %__msg% is reserved: use it only to specify
* where a message passed in by the user should be placed in the template,
* like so:
*
* Error message: %msg% - internal error
*
* If the message passed like so:
*
* <code>
* $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
* </code>
*
* The returned error message will be "Error message: server error 500 -
* internal error"
* @param PEAR_ErrorStack
* @param array
* @param string|false Pre-generated error message template
*
* @return string
*/
public static function getErrorMessage(&$stack, $err, $template = false)
{
if ($template) {
$mainmsg = $template;
} else {
$mainmsg = $stack->getErrorMessageTemplate($err['code']);
}
$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
if (is_array($err['params']) && count($err['params'])) {
foreach ($err['params'] as $name => $val) {
if (is_array($val)) {
// @ is needed in case $val is a multi-dimensional array
$val = @implode(', ', $val);
}
if (is_object($val)) {
if (method_exists($val, '__toString')) {
$val = $val->__toString();
} else {
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
'warning', array('obj' => get_class($val)),
'object %obj% passed into getErrorMessage, but has no __toString() method');
$val = 'Object';
}
}
$mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
}
}
return $mainmsg;
}
/**
* Standard Error Message Template generator from code
* @return string
*/
function getErrorMessageTemplate($code)
{
if (!isset($this->_errorMsgs[$code])) {
return '%__msg%';
}
return $this->_errorMsgs[$code];
}
/**
* Set the Error Message Template array
*
* The array format must be:
* <pre>
* array(error code => 'message template',...)
* </pre>
*
* Error message parameters passed into {@link push()} will be used as input
* for the error message. If the template is 'message %foo% was %bar%', and the
* parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
* be 'message one was six'
* @return string
*/
function setErrorMessageTemplate($template)
{
$this->_errorMsgs = $template;
}
/**
* emulate PEAR::raiseError()
*
* @return PEAR_Error
*/
function raiseError()
{
require_once 'PEAR.php';
$args = func_get_args();
return call_user_func_array(array('PEAR', 'raiseError'), $args);
}
}
$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
?>

Some files were not shown because too many files have changed in this diff Show more