phing-2.17.4/filters/BaseParamFilterReader.php0000644000076500000240000000456714261771713020256 0ustar mrookstaff. */ include_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/types/Parameterizable.php'; include_once 'phing/types/Parameter.php'; /** * Base class for core filter readers. * * @author Yannick Lecaillez * @copyright 2003 seasonfive. All rights reserved * * @see FilterReader * @package phing.filters */ class BaseParamFilterReader extends BaseFilterReader implements Parameterizable { /** * The passed in parameter array. * * @var array $_parameters */ protected $_parameters = array(); /** * Sets the parameters used by this filter, and sets * the filter to an uninitialized status. * * @param array $parameters Array of parameters to be used by this filter. * Should not be null. * * @return void * * @throws Exception */ public function setParameters($parameters) { // type check, error must never occur, bad code of it does if (!is_array($parameters)) { throw new Exception("Expected parameters array got something else"); } $this->_parameters = $parameters; $this->setInitialized(false); } /** * Returns the parameters to be used by this filter. * * @return array the parameters to be used by this filter */ public function &getParameters() { return $this->_parameters; } } phing-2.17.4/filters/TranslateGettext.php0000644000076500000240000002302214261771713017417 0ustar mrookstaff. */ require_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Replaces gettext("message id") and _("message id") with the translated string. * * Gettext is great for creating multi-lingual sites, but in some cases (e.g. for * performance reasons) you may wish to replace the gettext calls with the translations * of the strings; that's what this task is for. Note that this is similar to * ReplaceTokens, but both the find and the replace aspect is more complicated -- hence * this is a separate, stand-alone filter. * *

* Example:
*

 * 
 * 
* * @author Hans Lellelid * @version $Id: ceb6f10071ec525cd89b9f6dba2564971aa67a72 $ * @see BaseFilterReader * @package phing.filters */ class TranslateGettext extends BaseParamFilterReader implements ChainableReader { // constants for specifying keys to expect // when this is called using const DOMAIN_KEY = "domain"; const DIR_KEY = "dir"; const LOCALE_KEY = "locale"; /** The domain to use */ private $domain = 'messages'; /** The dir containing LC_MESSAGES */ private $dir; /** The locale to use */ private $locale; /** The system locale before it was changed for this filter. */ private $storedLocale; /** * Set the text domain to use. * The text domain must correspond to the name of the compiled .mo files. * E.g. "messages" ==> $dir/LC_MESSAGES/messages.mo * "mydomain" ==> $dir/LC_MESSAGES/mydomain.mo * @param string $domain */ public function setDomain($domain) { $this->domain = $domain; } /** * Get the current domain. * @return string */ public function getDomain() { return $this->domain; } /** * Sets the root locale directory. * @param PhingFile $dir */ public function setDir(PhingFile $dir) { $this->dir = $dir; } /** * Gets the root locale directory. * @return PhingFile */ public function getDir() { return $this->dir; } /** * Sets the locale to use for translation. * Note that for gettext() to work, you have to make sure this locale * is specific enough for your system (e.g. some systems may allow an 'en' locale, * but others will require 'en_US', etc.). * @param string $locale */ public function setLocale($locale) { $this->locale = $locale; } /** * Gets the locale to use for translation. * @return string */ public function getLocale() { return $this->locale; } /** * Make sure that required attributes are set. * @throws BuldException - if any required attribs aren't set. */ protected function checkAttributes() { if (!$this->domain || !$this->locale || !$this->dir) { throw new BuildException("You must specify values for domain, locale, and dir attributes."); } } /** * Initialize the gettext/locale environment. * This method will change some env vars and locale settings; the * restoreEnvironment should put them all back :) * * @return void * @throws BuildException - if locale cannot be set. * @see restoreEnvironment() */ protected function initEnvironment() { $this->storedLocale = getenv("LANG"); $this->log("Setting locale to " . $this->locale, Project::MSG_DEBUG); putenv("LANG=" . $this->locale); $ret = setlocale(LC_ALL, $this->locale); if ($ret === false) { $msg = "Could not set locale to " . $this->locale . ". You may need to use fully qualified name" . " (e.g. en_US instead of en)."; throw new BuildException($msg); } $this->log("Binding domain '" . $this->domain . "' to " . $this->dir, Project::MSG_DEBUG); bindtextdomain($this->domain, $this->dir->getAbsolutePath()); textdomain($this->domain); } /** * Restores environment settings and locale. * This does _not_ restore any gettext-specific settings * (e.g. textdomain()). * * @return void */ protected function restoreEnvironment() { putenv("LANG=" . $this->storedLocale); setlocale(LC_ALL, $this->storedLocale); } /** * Performs gettext translation of msgid and returns translated text. * * This function simply wraps gettext() call, but provides ability to log * string replacements. (alternative would be using preg_replace with /e which * would probably be faster, but no ability to debug/log.) * * @param array $matches Array of matches; we're interested in $matches[2]. * @return string Translated text */ private function xlateStringCallback($matches) { $charbefore = $matches[1]; $msgid = $matches[2]; $translated = gettext($msgid); $this->log("Translating \"$msgid\" => \"$translated\"", Project::MSG_DEBUG); return $charbefore . '"' . $translated . '"'; } /** * Returns the filtered stream. * The original stream is first read in fully, and then translation is performed. * * @param null $len * @throws BuildException * @return mixed the filtered stream, or -1 if the end of the resulting stream has been reached. * */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } // Make sure correct params/attribs have been set $this->checkAttributes(); $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } // Setup the locale/gettext environment $this->initEnvironment(); // replace any occurrences of _("") or gettext("") with // the translated value. // // ([^\w]|^)_\("((\\"|[^"])*)"\) // --$1--- -----$2---- // ---$3-- [match escaped quotes or any char that's not a quote] // // also match gettext() -- same as above $buffer = preg_replace_callback( '/([^\w]|^)_\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer ); $buffer = preg_replace_callback( '/([^\w]|^)gettext\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer ); // Check to see if there are any _('') calls and flag an error // Check to see if there are any unmatched gettext() calls -- and flag an error $matches = array(); if (preg_match('/([^\w]|^)(gettext\([^\)]+\))/', $buffer, $matches)) { $this->log("Unable to perform translation on: " . $matches[2], Project::MSG_WARN); } $this->restoreEnvironment(); return $buffer; } /** * Creates a new TranslateGettext filter using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return TranslateGettext A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new TranslateGettext($reader); $newFilter->setProject($this->getProject()); $newFilter->setDomain($this->getDomain()); $newFilter->setLocale($this->getLocale()); $newFilter->setDir($this->getDir()); return $newFilter; } /** * Parses the parameters if this filter is being used in "generic" mode. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { foreach ($params as $param) { switch ($param->getType()) { case self::DOMAIN_KEY: $this->setDomain($param->getValue()); break; case self::DIR_KEY: $this->setDir($this->project->resolveFile($param->getValue())); break; case self::LOCALE_KEY: $this->setLocale($param->getValue()); break; } // switch } } // if params !== null } } phing-2.17.4/filters/EscapeUnicode.php0000644000076500000240000000703014261771713016625 0ustar mrookstaff. */ require_once 'phing/filters/BaseFilterReader.php'; require_once 'phing/filters/ChainableReader.php'; /** * UTF-8 to Unicode Code Points * * This method converts non-latin characters to unicode escapes. * Useful to load properties containing non latin. * * Example: * * `` * * Or: * * `` * * @author Siad Ardroumli * @package phing.filters */ class EscapeUnicode extends BaseFilterReader implements ChainableReader { /** * Returns the next line in the filtered stream, converting non latin * characters to unicode escapes. * * @param int $len optional * @return string the converted lines in the resulting stream, or -1 * if the end of the resulting stream has been reached * @throws IOException if the underlying stream throws * an IOException during reading */ public function read($len = null) { if (!$this->getInitialized()) { $this->initialize(); $this->setInitialized(true); } // Process whole text at once. $text = null; while (($data = $this->in->read($len)) !== -1) { $text .= $data; } // At the end. if (null === $text) { return -1; } $textArray = preg_split("~\R~", $text); $lines = array(); foreach ($textArray as $offset => $line) { $lines[] = trim(json_encode($line), '"'); if (strlen($line) !== strlen($lines[$offset])) { $this->log( "Escape unicode chars on line " . ($offset + 1) . " from " . $line . " to " . $lines[$offset], Project::MSG_VERBOSE ); } } $escaped = implode(PHP_EOL, $lines); return $escaped; } /** * Creates a new EscapeUnicode using the passed in * Reader for instantiation. * * @param rdr A Reader object providing the underlying stream. * Must not be null. * * @return a new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $rdr) { $newFilter = new EscapeUnicode($rdr); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Parses the parameters (currently unused) */ private function initialize() { } } phing-2.17.4/filters/ExpandProperties.php0000644000076500000240000000714014261771713017414 0ustar mrookstaff. */ require_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Expands Phing Properties, if any, in the data. *

* Example:
*

* Or: *
logLevel = Project::MSG_ERR;
                break;
            case "warning":
                $this->logLevel = Project::MSG_WARN;
                break;
            case "info":
                $this->logLevel = Project::MSG_INFO;
                break;
            case "verbose":
                $this->logLevel = Project::MSG_VERBOSE;
                break;
            case "debug":
                $this->logLevel = Project::MSG_DEBUG;
                break;
        }
    }

    /**
     * Returns the filtered stream.
     * The original stream is first read in fully, and the Phing properties are expanded.
     *
     * @param null $len
     * @return mixed the filtered stream, or -1 if the end of the resulting stream has been reached.
     *
     * @exception IOException if the underlying stream throws an IOException
     * during reading
     */
    public function read($len = null)
    {

        $buffer = $this->in->read($len);

        if ($buffer === -1) {
            return -1;
        }

        $project = $this->getProject();
        $buffer = ProjectConfigurator::replaceProperties($project, $buffer, $project->getProperties(), $this->logLevel);

        return $buffer;
    }

    /**
     * Creates a new ExpandProperties filter using the passed in
     * Reader for instantiation.
     *
     * @param Reader $reader A Reader object providing the underlying stream.
     *               Must not be null.
     *
     * @return ExpandProperties A new filter based on this configuration, but filtering
     *                the specified reader
     */
    public function chain(Reader $reader)
    {
        $newFilter = new ExpandProperties($reader);
        $newFilter->setProject($this->getProject());

        return $newFilter;
    }
}
phing-2.17.4/filters/SortFilter.php0000644000076500000240000001426714261771713016225 0ustar  mrookstaff.
 */

require_once 'phing/filters/BaseParamFilterReader.php';
include_once 'phing/util/StringHelper.php';

/**
 * 

* Sort a file before and/or after the file. *

* *

* Examples: *

* *
 *   <copy todir="build">
 *       <fileset dir="input" includes="*.txt"/>
 *       <filterchain>
 *           <sortfilter/>
 *       </filterchain>
 *   </copy>
 * 
* *

* Sort all files *.txt from src location and copy * them into build location. The lines of each file are sorted * in ascendant order comparing the lines. *

* *
 *   <copy todir="build">
 *       <fileset dir="input" includes="*.txt"/>
 *       <filterchain>
 *           <sortfilter reverse="true"/>
 *       </filterchain>
 *   </copy>
 * 
* *

* Sort all files *.txt from src location into reverse * order and copy them into build location. If reverse parameter has * value true (default value), then the output line of the files * will be in ascendant order. *

* * @author Siad.ardroumli * * @see BaseParamFilterReader * * @package phing.filters */ class SortFilter extends BaseParamFilterReader implements ChainableReader { /** Parameter name for reverse order. */ private static $REVERSE_KEY = "reverse"; /** * Controls if the sorting process will be in ascendant/descendant order. If * If has value true, then the line of the file will be * sorted on descendant order. Default value: false. It will * be considered only if comparator is null. */ private $reverse; /** * Stores the lines to be sorted. */ private $lines; /** * Creates a new filtered reader. * * @param Reader $in * A Reader object providing the underlying stream. Must not be * null. */ public function __construct(Reader $in = null) { parent::__construct($in); } /** * Returns the next character in the filtered stream. If the desired number * of lines have already been read, the resulting stream is effectively at * an end. Otherwise, the next character from the underlying stream is read * and returned. * * @param int $len * @return string the next character in the resulting stream, or -1 if the end of * the resulting stream has been reached * @throws BuildException * @exception IOException * if the underlying stream throws an IOException during * reading */ public function read($len = null) { if (!$this->getInitialized()) { $this->initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $this->lines = explode("\n", $buffer); $this->sort(); $filtered_buffer = implode("\n", $this->lines); return $filtered_buffer; } /** * Creates a new SortReader using the passed in Reader for instantiation. * * @param Reader $rdr * A Reader object providing the underlying stream. Must not be * null. * * @return SortFilter a new filter based on this configuration, but filtering the * specified reader */ public function chain(Reader $rdr) { $newFilter = new SortFilter($rdr); $newFilter->setReverse($this->isReverse()); $newFilter->setInitialized(true); return $newFilter; } /** * Returns true if the sorting process will be in reverse * order, otherwise the sorting process will be in ascendant order. * * @return boolean true if the sorting process will be in reverse * order, otherwise the sorting process will be in ascendant order. */ public function isReverse() { return $this->reverse; } /** * Sets the sorting process will be in ascendant (reverse=false) * or to descendant (reverse=true). * * @param boolean $reverse * Boolean representing reverse ordering process. */ public function setReverse($reverse) { $this->reverse = $reverse; } /** * Scans the parameters list */ private function initialize() { // get parameters $params = $this->getParameters(); foreach ($params as $param) { $paramName = $param->getName(); if (self::$REVERSE_KEY === $paramName) { $this->setReverse(StringHelper::booleanValue($param->getValue())); continue; } } } /** * Sorts the read lines ($this->lines) according to the sorting * criteria defined by the user. */ private function sort() { if ($this->reverse) { rsort($this->lines); } else { sort($this->lines); } } } phing-2.17.4/filters/StripPhpComments.php0000644000076500000240000001302714261771713017400 0ustar mrookstaff. */ include_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * This is a Php comment and string stripper reader that filters * those lexical tokens out for purposes of simple Php parsing. * (if you have more complex Php parsing needs, use a real lexer). * Since this class heavily relies on the single char read function, * you are recommended to make it work on top of a buffered reader. * * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @version $Id: e46d7849417c2b8249f317003a3ebc161fac0e96 $ * @see FilterReader * @package phing.filters */ class StripPhpComments extends BaseFilterReader implements ChainableReader { /** * The read-ahead character, used for effectively pushing a single * character back. -1 indicates that no character is in the buffer. */ private $_readAheadCh = -1; /** * Whether or not the parser is currently in the middle of a string * literal. * @var boolean */ private $_inString = false; /** * Returns the stream without Php comments. * * @param null $len * @return string the resulting stream, or -1 * if the end of the resulting stream has been reached * */ public function read($len = null) { $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $newStr = ''; $tokens = token_get_all($buffer); foreach ($tokens as $token) { if (is_array($token)) { list($id, $text) = $token; switch ($id) { case T_COMMENT: case T_DOC_COMMENT: // no action on comments continue 2; default: $newStr .= $text; continue 2; } } $newStr .= $token; } return $newStr; } /** * Returns the next character in the filtered stream, not including * Php comments. * * @return int the next character in the resulting stream, or -1 * if the end of the resulting stream has been reached * * @throws IOException if the underlying stream throws an IOException * during reading * @deprecated */ public function readChar() { $ch = -1; if ($this->_readAheadCh !== -1) { $ch = $this->_readAheadCh; $this->_readAheadCh = -1; } else { $ch = $this->in->readChar(); if ($ch === "\"") { $this->_inString = !$this->_inString; } else { if (!$this->_inString) { if ($ch === "/") { $ch = $this->in->readChar(); if ($ch === "/") { while ($ch !== "\n" && $ch !== -1) { $ch = $this->in->readChar(); } } else { if ($ch === "*") { while ($ch !== -1) { $ch = $this->in->readChar(); while ($ch === "*" && $ch !== -1) { $ch = $this->in->readChar(); } if ($ch === "/") { $ch = $this->readChar(); echo "$ch\n"; break; } } } else { $this->_readAheadCh = $ch; $ch = "/"; } } } } } } return $ch; } /** * Creates a new StripPhpComments using the passed in * Reader for instantiation. * * @param A|Reader $reader * @internal param A $reader Reader object providing the underlying stream. * Must not be null. * * @return $this a new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new StripPhpComments($reader); $newFilter->setProject($this->getProject()); return $newFilter; } } phing-2.17.4/filters/TabToSpaces.php0000644000076500000240000001033114261771713016264 0ustar mrookstaff. */ require_once 'phing/filters/BaseParamFilterReader.php'; require_once 'phing/filters/ChainableReader.php'; /** * Converts tabs to spaces. * * Example: * *
* * Or: * *

 *   
 * 
* * @author Yannick Lecaillez * @author Hans Lellelid * @version $Id: 55c4ddd8825bb8912804163ddbc825abb4bc5aba $ * @see BaseParamFilterReader * @package phing.filters */ class TabToSpaces extends BaseParamFilterReader implements ChainableReader { /** * The default tab length. * @var int */ const DEFAULT_TAB_LENGTH = 8; /** * Parameter name for the length of a tab. * @var string */ const TAB_LENGTH_KEY = "tablength"; /** * Tab length in this filter. * @var int */ private $tabLength = 8; //self::DEFAULT_TAB_LENGTH; /** * Returns stream after converting tabs to the specified number of spaces. * * @param null $len * @return the resulting stream, or -1 * if the end of the resulting stream has been reached * * @exception IOException if the underlying stream throws an IOException * during reading */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $buffer = str_replace("\t", str_repeat(' ', $this->tabLength), $buffer); return $buffer; } /** * Sets the tab length. * * @param int $tabLength The number of spaces to be used when converting a tab. */ public function setTablength($tabLength) { $this->tabLength = (int) $tabLength; } /** * Returns the tab length. * * @return int The number of spaces used when converting a tab */ public function getTablength() { return $this->tabLength; } /** * Creates a new TabsToSpaces using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return Reader A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new TabToSpaces($reader); $newFilter->setTablength($this->getTablength()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Parses the parameters to set the tab length. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0; $i < count($params); $i++) { if (self::TAB_LENGTH_KEY === $params[$i]->getName()) { $this->tabLength = $params[$i]->getValue(); break; } } } } } phing-2.17.4/filters/XsltFilter.php0000644000076500000240000002632314261771713016224 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Applies XSL stylesheet to incoming text. * * Uses PHP XSLT support (libxslt). * * @author Hans Lellelid * @author Yannick Lecaillez * @author Andreas Aderhold * * @see FilterReader * @package phing.filters */ class XsltFilter extends BaseParamFilterReader implements ChainableReader { /** * Path to XSL stylesheet. * @var string */ private $xslFile = null; /** * Whether XML file has been transformed. * @var boolean */ private $processed = false; /** * XSLT Params. * @var array */ private $xsltParams = array(); /** * Whether to use loadHTML() to parse the input XML file. */ private $html = false; /** * Whether to resolve entities in the XML document (see * {@link http://www.php.net/manual/en/class.domdocument.php#domdocument.props.resolveexternals} * for more details). * * @var bool * * @since 2.4 */ private $resolveDocumentExternals = false; /** * Whether to resolve entities in the stylesheet. * * @var bool * * @since 2.4 */ private $resolveStylesheetExternals = false; /** * Create new XSLT Param object, to handle the nested element. * @return XSLTParam */ public function createParam() { $num = array_push($this->xsltParams, new XSLTParam()); return $this->xsltParams[$num - 1]; } /** * Sets the XSLT params for this class. * This is used to "clone" this class, in the chain() method. * @param array $params */ public function setParams($params) { $this->xsltParams = $params; } /** * Returns the XSLT params set for this class. * This is used to "clone" this class, in the chain() method. * @return array */ public function getParams() { return $this->xsltParams; } /** * Set the XSLT stylesheet. * @param mixed $file PhingFile object or path. */ public function setStyle(PhingFile $file) { $this->xslFile = $file; } /** * Whether to use HTML parser for the XML. * This is supported in libxml2 -- Yay! * @return boolean */ public function getHtml() { return $this->html; } /** * Whether to use HTML parser for XML. * @param boolean $b */ public function setHtml($b) { $this->html = (boolean) $b; } /** * Get the path to XSLT stylesheet. * @return mixed XSLT stylesheet path. */ public function getStyle() { return $this->xslFile; } /** * Whether to resolve entities in document. * * @param bool $resolveExternals * * @since 2.4 */ public function setResolveDocumentExternals($resolveExternals) { $this->resolveDocumentExternals = (bool) $resolveExternals; } /** * @return bool * * @since 2.4 */ public function getResolveDocumentExternals() { return $this->resolveDocumentExternals; } /** * Whether to resolve entities in stylesheet. * * @param bool $resolveExternals * * @since 2.4 */ public function setResolveStylesheetExternals($resolveExternals) { $this->resolveStylesheetExternals = (bool) $resolveExternals; } /** * @return bool * * @since 2.4 */ public function getResolveStylesheetExternals() { return $this->resolveStylesheetExternals; } /** * Reads stream, applies XSLT and returns resulting stream. * @param null $len * @throws BuildException * @return string transformed buffer. */ public function read($len = null) { if (!class_exists('XSLTProcessor')) { throw new BuildException("Could not find the XSLTProcessor class. Make sure PHP has been compiled/configured to support XSLT."); } if ($this->processed === true) { return -1; // EOF } if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } // Read XML $_xml = null; while (($data = $this->in->read($len)) !== -1) { $_xml .= $data; } if ($_xml === null) { // EOF? return -1; } if (empty($_xml)) { $this->log("XML file is empty!", Project::MSG_WARN); return ''; // return empty string, don't attempt to apply XSLT } // Read XSLT $_xsl = null; $xslFr = new FileReader($this->xslFile); $xslFr->readInto($_xsl); $this->log( "Tranforming XML " . $this->in->getResource() . " using style " . $this->xslFile->getPath(), Project::MSG_VERBOSE ); $out = ''; try { $out = $this->process($_xml, $_xsl); $this->processed = true; } catch (IOException $e) { throw new BuildException($e); } return $out; } // {{{ method _ProcessXsltTransformation($xml, $xslt) throws BuildException /** * Try to process the XSLT transformation * * @param string $xml XML to process. * @param string $xsl XSLT sheet to use for the processing. * * @return string * * @throws BuildException On XSLT errors */ protected function process($xml, $xsl) { $processor = new XSLTProcessor(); // Create and setup document. $xmlDom = new DOMDocument(); $xmlDom->resolveExternals = $this->resolveDocumentExternals; // Create and setup stylesheet. $xslDom = new DOMDocument(); $xslDom->resolveExternals = $this->resolveStylesheetExternals; if ($this->html) { $xmlDom->loadHTML($xml); } else { $xmlDom->loadXML($xml); } $xslDom->loadxml($xsl); if (defined('XSL_SECPREF_WRITE_FILE')) { if (version_compare(PHP_VERSION, '5.4', "<")) { ini_set("xsl.security_prefs", XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY); } else { $processor->setSecurityPrefs(XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY); } } $processor->importStylesheet($xslDom); // ignoring param "type" attrib, because // we're only supporting direct XSL params right now foreach ($this->xsltParams as $param) { $this->log("Setting XSLT param: " . $param->getName() . "=>" . $param->getExpression(), Project::MSG_DEBUG); $processor->setParameter(null, $param->getName(), $param->getExpression()); } $errorlevel = error_reporting(); error_reporting($errorlevel & ~E_WARNING); @$result = $processor->transformToXML($xmlDom); error_reporting($errorlevel); if (false === $result) { //$errno = xslt_errno($processor); //$err = xslt_error($processor); throw new BuildException("XSLT Error"); } else { return $result; } } /** * Creates a new XsltFilter using the passed in * Reader for instantiation. * * @param Reader A Reader object providing the underlying stream. * Must not be null. * * @return XsltFilter A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new XsltFilter($reader); $newFilter->setProject($this->getProject()); $newFilter->setStyle($this->getStyle()); $newFilter->setInitialized(true); $newFilter->setParams($this->getParams()); $newFilter->setHtml($this->getHtml()); return $newFilter; } /** * Parses the parameters to get stylesheet path. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if ($params[$i]->getType() === null) { if ($params[$i]->getName() === "style") { $this->setStyle($params[$i]->getValue()); } } elseif ($params[$i]->getType() == "param") { $xp = new XSLTParam(); $xp->setName($params[$i]->getName()); $xp->setExpression($params[$i]->getValue()); $this->xsltParams[] = $xp; } } } } } /** * Class that holds an XSLT parameter. * * @package phing.filters */ class XSLTParam { private $name; /** @var RegisterSlot */ private $expr; /** * Sets param name. * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get param name. * @return string */ public function getName() { return $this->name; } /** * Sets expression value (alias to the setExpression()) method. * * @param string $v * @see setExpression() */ public function setValue($v) { $this->setExpression($v); } /** * Gets expression value (alias to the getExpression()) method. * * @return string * @see getExpression() */ public function getValue() { return $this->getExpression(); } /** * Sets expression value. * @param string $expr */ public function setExpression($expr) { $this->expr = $expr; } /** * Sets expression to dynamic register slot. * @param RegisterSlot $expr */ public function setListeningExpression(RegisterSlot $expr) { $this->expr = $expr; } /** * Returns expression value -- performs lookup if expr is registerslot. * * @return string */ public function getExpression() { if ($this->expr instanceof RegisterSlot) { return $this->expr->getValue(); } else { return $this->expr; } } } phing-2.17.4/filters/util/ChainReaderHelper.php0000644000076500000240000001463014261771713020404 0ustar mrookstaff. */ include_once 'phing/Project.php'; include_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/types/PhingFilterReader.php'; include_once 'phing/types/FilterChain.php'; include_once 'phing/types/Parameter.php'; include_once 'phing/util/FileUtils.php'; include_once 'phing/util/StringHelper.php'; include_once 'phing/filters/ChainableReader.php'; /** * Process a FilterReader chain. * * Here, the interesting method is 'getAssembledReader'. * The purpose of this one is to create a simple Reader object which * apply all filters on another primary Reader object. * * For example : In copyFile (phing.util.FileUtils) the primary Reader * is a FileReader object (more accuratly, a BufferedReader) previously * setted for the source file to copy. So, consider this filterchain : * * * * * * * * * * getAssembledReader will return a Reader object wich read on each * of these filters. Something like this : ('->' = 'which read data from') : * * [TABTOSPACES] -> [LINECONTAINS] -> [STRIPPHPCOMMENTS] -> [FILEREADER] * (primary reader) * * So, getAssembledReader will return the TABTOSPACES Reader object. Then * each read done with this Reader object will follow this path. * * Hope this explanation is clear :) * * TODO: Implement the classPath feature. * * @author Yannick Lecaillez * @version $Id: 46536018ea0389c5baca8c49666d35c7524ee15b $ * @package phing.filters.util */ class ChainReaderHelper { /** Primary reader to wich the reader chain is to be attached */ private $primaryReader = null; /** The site of the buffer to be used. */ private $bufferSize = 8192; /** Chain of filters */ private $filterChains = array(); /** The Phing project */ private $project; /* * Sets the primary reader */ /** * @param Reader $reader */ public function setPrimaryReader(Reader $reader) { $this->primaryReader = $reader; } /* * Set the project to work with */ /** * @param Project $project */ public function setProject(Project $project) { $this->project = $project; } /* * Get the project */ public function getProject() { return $this->project; } /* * Sets the buffer size to be used. Defaults to 8192, * if this method is not invoked. */ /** * @param $size */ public function setBufferSize($size) { $this->bufferSize = $size; } /* * Sets the collection of filter reader sets */ /** * @param $fchain */ public function setFilterChains(&$fchain) { $this->filterChains = & $fchain; } /* * Assemble the reader */ /** * @return FilterReader|null|Parameterizable|Reader * @throws Exception */ public function getAssembledReader() { $instream = $this->primaryReader; $filterReadersCount = count($this->filterChains); $finalFilters = array(); // Collect all filter readers of all filter chains used ... for ($i = 0; $i < $filterReadersCount; $i++) { $filterchain = & $this->filterChains[$i]; $filterReaders = $filterchain->getFilterReaders(); $readerCount = count($filterReaders); for ($j = 0; $j < $readerCount; $j++) { $finalFilters[] = $filterReaders[$j]; } } // ... then chain the filter readers. $filtersCount = count($finalFilters); if ($filtersCount > 0) { for ($i = 0; $i < $filtersCount; $i++) { $filter = $finalFilters[$i]; if ($filter instanceof PhingFilterReader) { // This filter reader is an external class. $className = $filter->getClassName(); $classpath = $filter->getClasspath(); $project = $filter->getProject(); if ($className !== null) { $cls = Phing::import($className, $classpath); $impl = new $cls(); } if (!($impl instanceof FilterReader)) { throw new Exception($className . " does not extend phing.system.io.FilterReader"); } $impl->setReader($instream); // chain $impl->setProject($this->getProject()); // what about $project above ? if ($impl instanceof Parameterizable) { $impl->setParameters($filter->getParams()); } $instream = $impl; // now that it's been chained } elseif (($filter instanceof ChainableReader) && ($filter instanceof Reader)) { if ($this->getProject() !== null && ($filter instanceof BaseFilterReader)) { $filter->setProject($this->getProject()); } $instream = $filter->chain($instream); } else { throw new Exception("Cannot chain invalid filter: " . get_class($filter)); } } } return $instream; } } phing-2.17.4/filters/util/IniFileTokenReader.php0000644000076500000240000000747314261771713020551 0ustar mrookstaff. */ include_once 'phing/types/TokenReader.php'; include_once 'phing/system/io/IOException.php'; include_once 'phing/filters/ReplaceTokens.php'; // For class Token /** * Class that allows reading tokens from INI files. * * @author Manuel Holtgewe * @version $Id: 1787bbe5c2ac3fc35faf21652eed36899bff61b6 $ * @package phing.filters.util */ class IniFileTokenReader extends TokenReader { /** * Holds the path to the INI file that is to be read. * @var object Reference to a PhingFile Object representing * the path to the INI file. */ private $file = null; /** * @var string Sets the section to load from the INI file. * if omitted, all sections are loaded. */ private $section = null; /** * @var array */ private $tokens = null; /** * Reads the next token from the INI file * * @throws BuildException * @return Token */ public function readToken() { if ($this->file === null) { throw new BuildException("No File set for IniFileTokenReader"); } if ($this->tokens === null) { $this->processFile(); } if (count($this->tokens) > 0) { return array_pop($this->tokens); } else { return null; } } /** * Parse & process the ini file */ protected function processFile() { $arr = parse_ini_file($this->file->getAbsolutePath(), true); if ($this->section !== null) { if (isset($arr[$this->section])) { $this->processSection($arr[$this->section]); } return; } $values = array_values($arr); if (!is_array($values[0])) { $this->processSection($arr); return; } foreach ($values as $subArr) { $this->processSection($subArr); } } /** * Process an individual section * * @param array $section */ protected function processSection(array $section) { foreach ($section as $key => $value) { $tok = new Token(); $tok->setKey($key); $tok->setValue($value); $this->tokens[] = $tok; } } /** * @param string|PhingFile $file * @throws BuildException */ public function setFile($file) { if (is_string($file)) { $this->file = new PhingFile($file); return; } if (is_object($file) && $file instanceof PhingFile) { $this->file = $file; return; } throw new BuildException("Unsupported value " . (string) $file); } /** * @param $str */ public function setSection($str) { $this->section = (string) $str; } } phing-2.17.4/filters/XincludeFilter.php0000644000076500000240000001126214261771713017041 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Applies Xinclude parsing to incoming text. * * Uses PHP DOM XML support * * @author Bill Karwin * @version $Id: a7da72148cfff4f3daf6f4ea7036f56f5ef2d955 $ * @see FilterReader * @package phing.filters */ class XincludeFilter extends BaseParamFilterReader implements ChainableReader { private $basedir = null; /** * @var bool */ private $processed = false; /** * Whether to resolve entities. * * @var bool * * @since 2.4 */ private $resolveExternals = false; /** * Whether to resolve entities. * * @param $resolveExternals * * @since 2.4 */ public function setResolveExternals($resolveExternals) { $this->resolveExternals = (bool) $resolveExternals; } /** * @return bool * * @since 2.4 */ public function getResolveExternals() { return $this->resolveExternals; } /** * @param PhingFile $dir */ public function setBasedir(PhingFile $dir) { $this->basedir = $dir; } /** * @return null */ public function getBasedir() { return $this->basedir; } /** * Reads stream, applies XSLT and returns resulting stream. * @param null $len * @throws BuildException * @return string transformed buffer. */ public function read($len = null) { if (!class_exists('DomDocument')) { throw new BuildException("Could not find the DomDocument class. Make sure PHP has been compiled/configured to support DOM XML."); } if ($this->processed === true) { return -1; // EOF } // Read XML $_xml = null; while (($data = $this->in->read($len)) !== -1) { $_xml .= $data; } if ($_xml === null) { // EOF? return -1; } if (empty($_xml)) { $this->log("XML file is empty!", Project::MSG_WARN); return ''; } $this->log("Transforming XML " . $this->in->getResource() . " using Xinclude ", Project::MSG_VERBOSE); $out = ''; try { $out = $this->process($_xml); $this->processed = true; } catch (IOException $e) { throw new BuildException($e); } return $out; } /** * Try to process the Xinclude transformation * * @param string XML to process. * * @return string * @throws BuildException On errors */ protected function process($xml) { if ($this->basedir) { $cwd = getcwd(); chdir($this->basedir); } // Create and setup document. $xmlDom = new DomDocument(); $xmlDom->resolveExternals = $this->resolveExternals; $xmlDom->loadXML($xml); $xmlDom->xinclude(); if ($this->basedir) { chdir($cwd); } return $xmlDom->saveXML(); } /** * Creates a new XincludeFilter using the passed in * Reader for instantiation. * * @param Reader A Reader object providing the underlying stream. * Must not be null. * * @return Reader A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new XincludeFilter($reader); $newFilter->setProject($this->getProject()); $newFilter->setBasedir($this->getBasedir()); return $newFilter; } } phing-2.17.4/filters/ReplaceRegexp.php0000644000076500000240000001046114261771713016646 0ustar mrookstaff. */ require_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; include_once 'phing/types/RegularExpression.php'; /** * Performs a regexp find/replace on stream. *

* Example:
*

 * 
 *    
 *    
 * 
 * 
* * @author Hans Lellelid * @version $Id: 4f9916cf83e322464568d6b0d4946f131ecf1c32 $ * @package phing.filters */ class ReplaceRegexp extends BaseFilterReader implements ChainableReader { /** * @var array RegularExpression[] */ private $regexps = array(); /** * Creator method handles nested tags. * @return RegularExpression */ public function createRegexp() { $num = array_push($this->regexps, new RegularExpression()); return $this->regexps[$num - 1]; } /** * Sets the current regexps. * (Used when, e.g., cloning/chaining the method.) * @param array RegularExpression[] */ public function setRegexps($regexps) { $this->regexps = $regexps; } /** * Gets the current regexps. * (Used when, e.g., cloning/chaining the method.) * @return array RegularExpression[] */ public function getRegexps() { return $this->regexps; } /** * Returns the filtered stream. * The original stream is first read in fully, and the regex replace is performed. * * @param int $len Required $len for Reader compliance. * * @return mixed The filtered stream, or -1 if the end of the resulting stream has been reached. * * @exception IOException if the underlying stream throws an IOException * during reading */ public function read($len = null) { $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } // perform regex replace here ... foreach ($this->regexps as $exptype) { $regexp = $exptype->getRegexp($this->project); try { $buffer = $regexp->replace($buffer); $this->log( "Performing regexp replace: /" . $regexp->getPattern() . "/" . $regexp->getReplace( ) . "/g" . $regexp->getModifiers(), Project::MSG_VERBOSE ); } catch (Exception $e) { // perhaps mismatch in params (e.g. no replace or pattern specified) $this->log("Error performing regexp replace: " . $e->getMessage(), Project::MSG_WARN); } } return $buffer; } /** * Creates a new ReplaceRegExp filter using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return ReplaceRegExp A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new ReplaceRegExp($reader); $newFilter->setProject($this->getProject()); $newFilter->setRegexps($this->getRegexps()); return $newFilter; } } phing-2.17.4/filters/LineContainsRegexp.php0000644000076500000240000001411514261771713017661 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/types/RegularExpression.php'; include_once 'phing/filters/ChainableReader.php'; /** * Filter which includes only those lines that contain the user-specified * regular expression matching strings. * * Example: *

 *   
 * 
* * Or: * *

 *    
 * 
* * This will fetch all those lines that contain the pattern foo * * @author Yannick Lecaillez * @author Hans Lellelid * @version $Id: 738a0e1b2434adba882fd21fa59f8a2f41377980 $ * @see FilterReader * @package phing.filters */ class LineContainsRegexp extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for regular expression. * @var string */ const REGEXP_KEY = "regexp"; /** * Regular expressions that are applied against lines. * @var array */ private $_regexps = array(); /** * Returns all lines in a buffer that contain specified strings. * @param null $len * @return mixed buffer, -1 on EOF */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $lines = explode("\n", $buffer); $matched = array(); $regexpsSize = count($this->_regexps); foreach ($lines as $line) { for ($i = 0; $i < $regexpsSize; $i++) { $regexp = $this->_regexps[$i]; $re = $regexp->getRegexp($this->getProject()); $matches = $re->matches($line); if (!$matches) { $line = null; break; } } if ($line !== null) { $matched[] = $line; } } $filtered_buffer = implode("\n", $matched); return $filtered_buffer; } /** * Adds a regexp element. * * @return object regExp The regexp element added. */ public function createRegexp() { $num = array_push($this->_regexps, new RegularExpression()); return $this->_regexps[$num - 1]; } /** * Sets the vector of regular expressions which must be contained within * a line read from the original stream in order for it to match this * filter. * * @param An $regexps * @throws Exception * @internal param An $regexps array of regular expressions which must be contained * within a line in order for it to match in this filter. Must not be * null. */ public function setRegexps($regexps) { // type check, error must never occur, bad code of it does if (!is_array($regexps)) { throw new Exception("Excpected an 'array', got something else"); } $this->_regexps = $regexps; } /** * Returns the array of regular expressions which must be contained within * a line read from the original stream in order for it to match this * filter. * * @return array The array of regular expressions which must be contained within * a line read from the original stream in order for it to match this * filter. The returned object is "live" - in other words, changes made to * the returned object are mirrored in the filter. */ public function getRegexps() { return $this->_regexps; } /** * Creates a new LineContainsRegExp using the passed in * Reader for instantiation. * * @param Reader $reader * @throws Exception * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new LineContainsRegExp($reader); $newFilter->setRegexps($this->getRegexps()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Parses parameters to add user defined regular expressions. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0; $i < count($params); $i++) { if (self::REGEXP_KEY === $params[$i]->getType()) { $pattern = $params[$i]->getValue(); $regexp = new RegularExpression(); $regexp->setPattern($pattern); array_push($this->_regexps, $regexp); } } } } } phing-2.17.4/filters/HeadFilter.php0000644000076500000240000001171414261771713016131 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Reads the first n lines of a stream. * (Default is first 10 lines.) *

* Example: *

* Or: *

 *    
 * 
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * * @see FilterReader * * @package phing.filters */ class HeadFilter extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for the number of lines to be returned. */ const LINES_KEY = "lines"; /** * Number of lines currently read in. * * @var integer */ private $_linesRead = 0; /** * Number of lines to be returned in the filtered stream. * * @var integer */ private $_lines = 10; /** * Returns first n lines of stream. * * @param null $len * @return string|int the resulting stream, or -1 * if the end of the resulting stream has been reached * */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } // note, if buffer contains fewer lines than // $this->_lines this code will not work. if ($this->_linesRead < $this->_lines) { $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } // now grab first X lines from buffer $lines = explode("\n", $buffer); $linesCount = count($lines); // must account for possibility that the num lines requested could // involve more than one buffer read. $len = ($linesCount > $this->_lines ? $this->_lines - $this->_linesRead : $linesCount); $filtered_buffer = implode("\n", array_slice($lines, 0, $len)); $this->_linesRead += $len; return $filtered_buffer; } return -1; // EOF, since the file is "finished" as far as subsequent filters are concerned. } /** * Sets the number of lines to be returned in the filtered stream. * * @param integer $lines the number of lines to be returned in the filtered stream. * * @return void */ public function setLines($lines) { $this->_lines = (int) $lines; } /** * Returns the number of lines to be returned in the filtered stream. * * @return integer The number of lines to be returned in the filtered stream. */ public function getLines() { return $this->_lines; } /** * Creates a new HeadFilter using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return HeadFilter A new filter based on this configuration, but filtering * the specified reader. */ public function chain(Reader $reader) { $newFilter = new HeadFilter($reader); $newFilter->setLines($this->getLines()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Scans the parameters list for the "lines" parameter and uses * it to set the number of lines to be returned in the filtered stream. * * @return void */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if (self::LINES_KEY == $params[$i]->getName()) { $this->_lines = (int) $params[$i]->getValue(); break; } } } } } phing-2.17.4/filters/BaseFilterReader.php0000644000076500000240000001134614261771713017266 0ustar mrookstaff. */ include_once 'phing/system/io/FilterReader.php'; include_once 'phing/system/io/StringReader.php'; /** * Base class for core filter readers. * * @author Yannick Lecaillez * @version $Id: 85cbd982d211b5d05761bd3043d2583b890bdc64 $ * @see FilterReader * @package phing.filters */ class BaseFilterReader extends FilterReader { /** Have the parameters passed been interpreted? */ protected $initialized = false; /** The Phing project this filter is part of. */ protected $project = null; /** * Constructor used by Phing's introspection mechanism. * The original filter reader is only used for chaining * purposes, never for filtering purposes (and indeed * it would be useless for filtering purposes, as it has * no real data to filter). ChainedReaderHelper uses * this placeholder instance to create a chain of real filters. * * @param Reader $in */ public function __construct($in = null) { if ($in === null) { $dummy = ""; $in = new StringReader($dummy); } parent::__construct($in); } /** * Returns the initialized status. * * @return boolean whether or not the filter is initialized */ public function getInitialized() { return $this->initialized; } /** * Sets the initialized status. * * @param boolean $initialized Whether or not the filter is initialized. */ public function setInitialized($initialized) { $this->initialized = (boolean) $initialized; } /** * Sets the project to work with. * * @param object|Project $project The project this filter is part of. * Should not be null. */ public function setProject(Project $project) { // type check, error must never occur, bad code of it does $this->project = $project; } /** * Returns the project this filter is part of. * * @return object The project this filter is part of */ public function getProject() { return $this->project; } /** * Reads characters. * * @param int $len Maximum number of characters to read. * * @return string Characters read, or -1 if the end of the stream * has been reached * * @throws IOException If an I/O error occurs */ public function read($len = null) { return $this->in->read($len); } /** * Reads a line of text ending with '\n' (or until the end of the stream). * The returned String retains the '\n'. * * @return string the line read, or null if the end of the * stream has already been reached * * @throws IOException if the underlying reader throws one during * reading */ public function readLine() { $line = null; while (($ch = $this->in->read(1)) !== -1) { $line .= $ch; if ($ch === "\n") { break; } } return $line; } /** * Returns whether the end of file has been reached with input stream. * * @return boolean */ public function eof() { return $this->in->eof(); } /** * Convenience method to support logging in filters. * * @param string $msg Message to log. * @param int $level Priority level. * * @return void */ public function log($msg, $level = Project::MSG_INFO) { if ($this->project !== null) { $this->project->log("[filter:" . get_class($this) . "] " . $msg, $level); } } } phing-2.17.4/filters/StripWhitespace.php0000644000076500000240000000627114261771713017242 0ustar mrookstaff. */ include_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Strips whitespace from [php] files using PHP stripwhitespace() method. * * @author Hans Lellelid, hans@velum.net * @version $Id: 9e156ae0693bd973b8e0f89490814171365197da $ * @see FilterReader * @package phing.filters * @todo -c use new PHP functions to perform this instead of regex. */ class StripWhitespace extends BaseFilterReader implements ChainableReader { private $processed = false; /** * Returns the stream without Php comments and whitespace. * * @param null $len * @return the resulting stream, or -1 * if the end of the resulting stream has been reached * */ public function read($len = null) { if ($this->processed === true) { return -1; // EOF } // Read XML $php = null; while (($buffer = $this->in->read($len)) !== -1) { $php .= $buffer; } if ($php === null) { // EOF? return -1; } if (empty($php)) { $this->log("PHP file is empty!", Project::MSG_WARN); return ''; // return empty string, don't attempt to strip whitespace } // write buffer to a temporary file, since php_strip_whitespace() needs a filename $file = new PhingFile(tempnam(PhingFile::getTempDir(), 'stripwhitespace')); file_put_contents($file->getAbsolutePath(), $php); $output = php_strip_whitespace($file->getAbsolutePath()); unlink($file->getAbsolutePath()); $this->processed = true; return $output; } /** * Creates a new StripWhitespace using the passed in * Reader for instantiation. * * @param A|Reader $reader * @internal param A $reader Reader object providing the underlying stream. * Must not be null. * * @return a new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new StripWhitespace($reader); $newFilter->setProject($this->getProject()); return $newFilter; } } phing-2.17.4/filters/TidyFilter.php0000644000076500000240000001163314261771713016201 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * This filter uses the bundled-with-PHP Tidy extension to filter input. * *

* Example:
*

 * 
 *   
 *   
 * 
 * 
* * @author Hans Lellelid * @version $Id: 21f7fd2edf8bbbbe620be3d3944e4cdf00cbc264 $ * @package phing.filters */ class TidyFilter extends BaseParamFilterReader implements ChainableReader { /** @var string Encoding of resulting document. */ private $encoding = 'utf8'; /** @var array Parameter[] */ private $configParameters = array(); /** * Set the encoding for resulting (X)HTML document. * @param string $v */ public function setEncoding($v) { $this->encoding = $v; } /** * Sets the config params. * @param array Parameter[] * @see chain() */ public function setConfigParameters($params) { $this->configParameters = $params; } /** * Adds a element (which is a Parameter). * @return Parameter */ public function createConfig() { $num = array_push($this->configParameters, new Parameter()); return $this->configParameters[$num - 1]; } /** * Converts the Parameter objects being used to store configuration into a simle assoc array. * @return array */ private function getDistilledConfig() { $config = array(); foreach ($this->configParameters as $p) { $config[$p->getName()] = $p->getValue(); } return $config; } /** * Reads input and returns Tidy-filtered output. * * @param null $len * @throws BuildException * @return the resulting stream, or -1 if the end of the resulting stream has been reached * */ public function read($len = null) { if (!class_exists('Tidy')) { throw new BuildException("You must enable the 'tidy' extension in your PHP configuration in order to use the Tidy filter."); } if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $config = $this->getDistilledConfig(); $tidy = new Tidy(); $tidy->parseString($buffer, $config, $this->encoding); $tidy->cleanRepair(); return tidy_get_output($tidy); } /** * Creates a new TidyFilter using the passed in Reader for instantiation. * * @param A|Reader $reader * @internal param A $reader Reader object providing the underlying stream. * Must not be null. * * @return a new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new TidyFilter($reader); $newFilter->setConfigParameters($this->configParameters); $newFilter->setEncoding($this->encoding); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Initializes any parameters (e.g. config options). * This method is only called when this filter is used through a tag in build file. */ private function _initialize() { $params = $this->getParameters(); if ($params) { foreach ($params as $param) { if ($param->getType() == "config") { $this->configParameters[] = $param; } else { if ($param->getName() == "encoding") { $this->setEncoding($param->getValue()); } } } } } } phing-2.17.4/filters/ReplaceTokens.php0000644000076500000240000003345014261771713016662 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/types/TokenSource.php'; include_once 'phing/filters/ChainableReader.php'; /** * Replaces tokens in the original input with user-supplied values. * * Example: * *
;
 *   
 * 
* * Or: * *

 *   
 *   
 *   
 * 
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @version $Id: 69ad2e753a6efce00ea1ac34adf119d41294d676 $ * @see BaseParamFilterReader * @package phing.filters */ class ReplaceTokens extends BaseParamFilterReader implements ChainableReader { /** * Default "begin token" character. * @var string */ const DEFAULT_BEGIN_TOKEN = "@"; /** * Default "end token" character. * @var string */ const DEFAULT_END_TOKEN = "@"; /** * [Deprecated] Data that must be read from, if not null. * @var string */ private $_queuedData = null; /** * Array to hold the replacee-replacer pairs (String to String). * @var array */ private $_tokens = array(); /** * Array to hold the token sources that make tokens from * different sources available * @var array */ private $_tokensources = array(); /** * Array holding all tokens given directly to the Filter and * those passed via a TokenSource. * @var array */ private $_alltokens = null; /** * Character marking the beginning of a token. * @var string */ private $_beginToken = "@"; // self::DEFAULT_BEGIN_TOKEN; /** * Character marking the end of a token. * @var string */ private $_endToken = "@"; //self::DEFAULT_END_TOKEN; /** * Performs lookup on key and returns appropriate replacement string. * @param array $matches Array of 1 el containing key to search for. * @return string Text with which to replace key or value of key if none is found. */ private function replaceTokenCallback($matches) { $key = $matches[1]; /* Get tokens from tokensource and merge them with the * tokens given directly via build file. This should be * done a bit more elegantly */ if ($this->_alltokens === null) { $this->_alltokens = array(); $count = count($this->_tokensources); for ($i = 0; $i < $count; $i++) { $source = $this->_tokensources[$i]; $this->_alltokens = array_merge($this->_alltokens, $source->getTokens()); } $this->_alltokens = array_merge($this->_tokens, $this->_alltokens); } $tokens = $this->_alltokens; $replaceWith = null; $count = count($tokens); for ($i = 0; $i < $count; $i++) { if ($tokens[$i]->getKey() === $key) { $replaceWith = $tokens[$i]->getValue(); } } if ($replaceWith === null) { $replaceWith = $this->_beginToken . $key . $this->_endToken; $this->log("No token defined for key \"" . $this->_beginToken . $key . $this->_endToken . "\""); } else { $this->log( "Replaced \"" . $this->_beginToken . $key . $this->_endToken . "\" with \"" . $replaceWith . "\"", Project::MSG_VERBOSE ); } return $replaceWith; } /** * Returns stream with tokens having been replaced with appropriate values. * If a replacement value is not found for a token, the token is left in the stream. * * @param null $len * @return mixed filtered stream, -1 on EOF. */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } // read from next filter up the chain $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } // filter buffer $buffer = preg_replace_callback( "/" . preg_quote($this->_beginToken, '/') . "([\w\.\-:]+?)" . preg_quote($this->_endToken, '/') . "/", array($this, 'replaceTokenCallback'), $buffer ); return $buffer; } /** * Sets the "begin token" character. * * @param string $beginToken the character used to denote the beginning of a token. */ public function setBeginToken($beginToken) { $this->_beginToken = (string) $beginToken; } /** * Returns the "begin token" character. * * @return string The character used to denote the beginning of a token. */ public function getBeginToken() { return $this->_beginToken; } /** * Sets the "end token" character. * * @param string $endToken the character used to denote the end of a token */ public function setEndToken($endToken) { $this->_endToken = (string) $endToken; } /** * Returns the "end token" character. * * @return the character used to denote the beginning of a token */ public function getEndToken() { return $this->_endToken; } /** * Adds a token element to the map of tokens to replace. * * @return object The token added to the map of replacements. * Must not be null. */ public function createToken() { $num = array_push($this->_tokens, new Token()); return $this->_tokens[$num - 1]; } /** * Adds a token source to the sources of this filter. * * @return object A Reference to the source just added. */ public function createTokensource() { $num = array_push($this->_tokensources, new TokenSource()); return $this->_tokensources[$num - 1]; } /** * Sets the map of tokens to replace. * ; used by ReplaceTokens::chain() * * @param $tokens * @throws Exception * @internal param A $array map (String->String) of token keys to replacement * values. Must not be null. */ public function setTokens($tokens) { // type check, error must never occur, bad code of it does if (!is_array($tokens)) { throw new Exception("Excpected 'array', got something else"); } $this->_tokens = $tokens; } /** * Returns the map of tokens which will be replaced. * ; used by ReplaceTokens::chain() * * @return array A map (String->String) of token keys to replacement values. */ public function getTokens() { return $this->_tokens; } /** * Sets the tokensources to use; used by ReplaceTokens::chain() * * @param $sources * @throws Exception * @internal param An $array array of token sources. */ public function setTokensources($sources) { // type check if (!is_array($sources)) { throw new Exception("Exspected 'array', got something else"); } $this->_tokensources = $sources; } /** * Returns the token sources used by this filter; used by ReplaceTokens::chain() * * @return array */ public function getTokensources() { return $this->_tokensources; } /** * Creates a new ReplaceTokens using the passed in * Reader for instantiation. * * @param Reader $reader * @throws Exception * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new ReplaceTokens($reader); $newFilter->setProject($this->getProject()); $newFilter->setBeginToken($this->getBeginToken()); $newFilter->setEndToken($this->getEndToken()); $newFilter->setTokens($this->getTokens()); $newFilter->setTokensources($this->getTokensources()); $newFilter->setInitialized(true); return $newFilter; } /** * Initializes tokens and loads the replacee-replacer hashtable. * This method is only called when this filter is used through * a tag in build file. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0; $i < count($params); $i++) { if ($params[$i] !== null) { $type = $params[$i]->getType(); if ($type === "tokenchar") { $name = $params[$i]->getName(); if ($name === "begintoken") { $this->_beginToken = substr($params[$i]->getValue(), 0, strlen($params[$i]->getValue())); } else { if ($name === "endtoken") { $this->_endToken = substr($params[$i]->getValue(), 0, strlen($params[$i]->getValue())); } } } else { if ($type === "token") { $name = $params[$i]->getName(); $value = $params[$i]->getValue(); $tok = new Token(); $tok->setKey($name); $tok->setValue($value); array_push($this->_tokens, $tok); } else { if ($type === "tokensource") { // Store data from nested tags in local array $arr = array(); $subparams = $params[$i]->getParams(); foreach ($subparams as $subparam) { $arr[$subparam->getName()] = $subparam->getValue(); } // Create TokenSource $tokensource = new TokenSource(); if (isset($arr["classname"])) { $tokensource->setClassname($arr["classname"]); } // Copy other parameters 1:1 to freshly created TokenSource foreach ($arr as $key => $value) { if (strtolower($key) === "classname") { continue; } $param = $tokensource->createParam(); $param->setName($key); $param->setValue($value); } $this->_tokensources[] = $tokensource; } } } } } } } } /** * Holds a token. * * @package phing.filters */ class Token { /** * Token key. * @var string */ private $_key; /** * Token value. * @var string */ private $_value; /** * Sets the token key. * * @param string $key The key for this token. Must not be null. */ public function setKey($key) { $this->_key = (string) $key; } /** * Sets the token value. * * @param string $value The value for this token. Must not be null. */ public function setValue($value) { // special case for boolean values if (is_bool($value)) { if ($value) { $this->_value = "true"; } else { $this->_value = "false"; } } else { $this->_value = (string) $value; } } /** * Returns the key for this token. * * @return string The key for this token. */ public function getKey() { return $this->_key; } /** * Returns the value for this token. * * @return string The value for this token. */ public function getValue() { return $this->_value; } /** * Sets the token value from text. * * @param string $value The value for this token. Must not be null. */ public function addText($value) { $this->setValue($value); } } phing-2.17.4/filters/LineContains.php0000644000076500000240000002001714261771713016504 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/BaseFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Filter which includes only those lines that contain all the user-specified * strings. * * Example: * *

 *   
 *   
 * 
* * Or: * *

 *    
 *    
 * 
* * This will include only those lines that contain foo and * bar. * * @author Yannick Lecaillez * @author Hans Lellelid * @version $Id: feaa90aaa736282a3599e8e5f655c31870b436cc $ * @see PhingFilterReader * @package phing.filters */ class LineContains extends BaseParamFilterReader implements ChainableReader { /** * The parameter name for the string to match on. * @var string */ const CONTAINS_KEY = "contains"; /** * Array of Contains objects. * @var array */ private $_contains = array(); /** * [Deprecated] * @var string */ private $_line = null; /** * Returns all lines in a buffer that contain specified strings. * @param null $len * @return mixed buffer, -1 on EOF */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $lines = explode("\n", $buffer); $matched = array(); $containsSize = count($this->_contains); foreach ($lines as $line) { for ($i = 0; $i < $containsSize; $i++) { $containsStr = $this->_contains[$i]->getValue(); if (strstr($line, $containsStr) === false) { $line = null; break; } } if ($line !== null) { $matched[] = $line; } } $filtered_buffer = implode("\n", $matched); return $filtered_buffer; } /** * [Deprecated. For reference only, used to be read() method.] * Returns the next character in the filtered stream, only including * lines from the original stream which contain all of the specified words. * * @return the next character in the resulting stream, or -1 * if the end of the resulting stream has been reached * * @exception IOException if the underlying stream throws an IOException * during reading */ public function readChar() { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $ch = -1; if ($this->_line !== null) { $ch = substr($this->_line, 0, 1); if (strlen($this->_line) === 1) { $this->_line = null; } else { $this->_line = substr($this->_line, 1); } } else { $this->_line = $this->readLine(); if ($this->_line === null) { $ch = -1; } else { $containsSize = count($this->_contains); for ($i = 0; $i < $containsSize; $i++) { $containsStr = $this->_contains[$i]->getValue(); if (strstr($this->_line, $containsStr) === false) { $this->_line = null; break; } } return $this->readChar(); } } return $ch; } /** * Adds a contains nested element. * * @return Contains The contains element added. * Must not be null. */ public function createContains() { $num = array_push($this->_contains, new Contains()); return $this->_contains[$num - 1]; } /** * Sets the array of words which must be contained within a line read * from the original stream in order for it to match this filter. * * @param array $contains An array of words which must be contained * within a line in order for it to match in this filter. * Must not be null. * @throws Exception */ public function setContains($contains) { // type check, error must never occur, bad code of it does if (!is_array($contains)) { throw new Exception("Excpected array got something else"); } $this->_contains = $contains; } /** * Returns the vector of words which must be contained within a line read * from the original stream in order for it to match this filter. * * @return array The array of words which must be contained within a line read * from the original stream in order for it to match this filter. The * returned object is "live" - in other words, changes made to the * returned object are mirrored in the filter. */ public function getContains() { return $this->_contains; } /** * Creates a new LineContains using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return LineContains A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new LineContains($reader); $newFilter->setContains($this->getContains()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Parses the parameters to add user-defined contains strings. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { foreach ($params as $param) { if (self::CONTAINS_KEY == $param->getType()) { $cont = new Contains(); $cont->setValue($param->getValue()); array_push($this->_contains, $cont); break; // because we only support a single contains } } } } } /** * Holds a contains element. * * @package phing.filters */ class Contains { /** * @var string */ private $_value; /** * Set 'contains' value. * @param string $contains */ public function setValue($contains) { $this->_value = (string) $contains; } /** * Returns 'contains' value. * @return string */ public function getValue() { return $this->_value; } } phing-2.17.4/filters/ChainableReader.php0000644000076500000240000000310614261771713017107 0ustar mrookstaff. */ /** * Interface indicating that a reader may be chained to another one. * * @author Magesh Umasankar * @package phing.filters */ interface ChainableReader { /** * Returns a reader with the same configuration as this one, * but filtering input from the specified reader. * * @param Reader $rdr the reader which the returned reader should be filtering * * @return Reader A reader with the same configuration as this one, but * filtering input from the specified reader */ public function chain(Reader $rdr); } phing-2.17.4/filters/SuffixLines.php0000644000076500000240000001017014261771713016354 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Attaches a suffix to every line. * * Example: *
* * Or: * *

 *  
 * 
* * @author Siad Ardroumli * @see FilterReader * @package phing.filters */ class SuffixLines extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for the suffix. * @var string */ const SUFFIX_KEY = "suffix"; /** * The suffix to be used. * @var string */ private $suffix = null; /** * Adds a suffix to each line of input stream and returns resulting stream. * * @param null $len * @return mixed buffer, -1 on EOF */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $lines = preg_split("~\R~", $buffer); $filtered = array(); foreach ($lines as $line) { $filtered[] = $line . $this->suffix; } $filtered_buffer = implode(PHP_EOL, $filtered); return $filtered_buffer; } /** * Sets the suffix to add at the end of each input line. * * @param string $suffix The suffix to add at the start of each input line. * May be null, in which case no suffix * is added. */ public function setSuffix($suffix) { $this->suffix = (string) $suffix; } /** * Returns the suffix which will be added at the end of each input line. * * @return string The suffix which will be added at the end of each input line */ public function getSuffix() { return $this->suffix; } /** * Creates a new PrefixLines filter using the passed in * Reader for instantiation. * * @param Reader $reader * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new SuffixLines($reader); $newFilter->setSuffix($this->getSuffix()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Initializes the suffix if it is available from the parameters. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if (self::SUFFIX_KEY == $params[$i]->getName()) { $this->suffix = (string) $params[$i]->getValue(); break; } } } } } phing-2.17.4/filters/StripLineBreaks.php0000644000076500000240000001120614261771713017157 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Filter to flatten the stream to a single line. * * Example: * *
* * Or: * *
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @version $Id: dab4c38d630ec372a9a4aecf9284a94a895812d9 $ * @see BaseParamFilterReader * @package phing.filters */ class StripLineBreaks extends BaseParamFilterReader implements ChainableReader { /** * Default line-breaking characters. * @var string */ const DEFAULT_LINE_BREAKS = "\r\n"; /** * Parameter name for the line-breaking characters parameter. * @var string */ const LINES_BREAKS_KEY = "linebreaks"; /** * The characters that are recognized as line breaks. * @var string */ private $_lineBreaks = "\r\n"; // self::DEFAULT_LINE_BREAKS; /** * Returns the filtered stream, only including * characters not in the set of line-breaking characters. * * @param null $len * @return mixed the resulting stream, or -1 * if the end of the resulting stream has been reached. * * @exception IOException if the underlying stream throws an IOException * during reading */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $buffer = preg_replace("/[" . $this->_lineBreaks . "]/", '', $buffer); return $buffer; } /** * Sets the line-breaking characters. * * @param string $lineBreaks A String containing all the characters to be * considered as line-breaking. */ public function setLineBreaks($lineBreaks) { $this->_lineBreaks = (string) $lineBreaks; } /** * Gets the line-breaking characters. * * @return string A String containing all the characters that are considered as line-breaking. */ public function getLineBreaks() { return $this->_lineBreaks; } /** * Creates a new StripLineBreaks using the passed in * Reader for instantiation. * * @param Reader $reader * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new StripLineBreaks($reader); $newFilter->setLineBreaks($this->getLineBreaks()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Parses the parameters to set the line-breaking characters. */ private function _initialize() { $userDefinedLineBreaks = null; $params = $this->getParameters(); if ($params !== null) { for ($i = 0; $i < count($params); $i++) { if (self::LINES_BREAKS_KEY === $params[$i]->getName()) { $userDefinedLineBreaks = $params[$i]->getValue(); break; } } } if ($userDefinedLineBreaks !== null) { $this->_lineBreaks = $userDefinedLineBreaks; } } } phing-2.17.4/filters/IconvFilter.php0000644000076500000240000001113114261771713016337 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Encode data from in encoding to out encoding. * * Example: *
 * 
 * 
* Or: *
 * 
 *    
 *    
 * 
 * 
* * @author Alexey Shockov, * @version $Id: fdd2765ea9675f36fde778b3faf373505cc0ccc2 $ * @package phing.filters */ class IconvFilter extends BaseParamFilterReader implements ChainableReader { private $_inputEncoding; private $_outputEncoding; /** * Returns first n lines of stream. * @param null $len * @return the resulting stream, or -1 * if the end of the resulting stream has been reached * * @exception IOException if the underlying stream throws an IOException * during reading */ public function read($len = null) { $this->_initialize(); // Process whole text at once. $text = null; while (($data = $this->in->read($len)) !== -1) { $text .= $data; } // At the end. if (null === $text) { return -1; } $this->log( "Encoding " . $this->in->getResource() . " from " . $this->getInputEncoding( ) . " to " . $this->getOutputEncoding(), Project::MSG_VERBOSE ); return iconv($this->_inputEncoding, $this->_outputEncoding, $text); } /** * * @param string $encoding Input encoding. */ public function setInputEncoding($encoding) { $this->_inputEncoding = $encoding; } /** * * @return string */ public function getInputEncoding() { return $this->_inputEncoding; } /** * * @param string $encoding Output encoding. */ public function setOutputEncoding($encoding) { $this->_outputEncoding = $encoding; } /** * * @return string */ public function getOutputEncoding() { return $this->_outputEncoding; } /** * Creates a new IconvFilter using the passed in Reader for instantiation. * * @param Reader $reader * @internal param A $object Reader object providing the underlying stream. Must not be null. * * @return object A new filter based on this configuration, but filtering the specified reader. */ public function chain(Reader $reader) { $filter = new self($reader); $filter->setInputEncoding($this->getInputEncoding()); $filter->setOutputEncoding($this->getOutputEncoding()); $filter->setInitialized(true); $filter->setProject($this->getProject()); return $filter; } /** * Configuring object from the parameters list. */ private function _initialize() { if ($this->getInitialized()) { return; } $params = $this->getParameters(); if ($params !== null) { foreach ($params as $param) { if ('in' == $param->getName()) { $this->setInputEncoding($param->getValue()); } else { if ('out' == $param->getName()) { $this->setOutputEncoding($param->getValue()); } } } } $this->setInitialized(true); } } phing-2.17.4/filters/ReplaceTokensWithFile.php0000644000076500000240000002740714261771713020323 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Replaces tokens in the original input with the contents of a file. * The file to be used is controlled by the name of the token which * corresponds to the basename of the file to be used together with * the optional pre and postfix strings that is possible to set. * * By default all HTML entities in the file is replaced by the * corresponding HTML entities. This behaviour can be controlled by * the "translatehtml" parameter. * * Supported parameters are: *
 *  prefix         string Text to be prefixed to token before using as filename
 *  postfix        string Text to be prefixed to token before using as filename
 *  dir            string The directory where the files should be read from
 *  translatehtml  bool   If we should translate all HTML entities in the file.
 * 
* Example: * *

 *   
 *   
 * 
* * @author johan persson, johanp@aditus.nu * @version $Id: 2ce2fe6389844147fcaa7f85308157891a38e7af $ * @see ReplaceTokensWithFile * @package phing.filters */ class ReplaceTokensWithFile extends BaseParamFilterReader implements ChainableReader { /** * Default "begin token" character. * @var string */ const DEFAULT_BEGIN_TOKEN = "#@#"; /** * Default "end token" character. * @var string */ const DEFAULT_END_TOKEN = "#@#"; /** * Array to hold the token sources that make tokens from * different sources available * @var array */ private $_tokensources = array(); /** * Character marking the beginning of a token. * @var string */ private $_beginToken = ReplaceTokensWithFile::DEFAULT_BEGIN_TOKEN; /** * Character marking the end of a token. * @var string */ private $_endToken = ReplaceTokensWithFile::DEFAULT_END_TOKEN; /** * File prefix to be inserted in front of the token to create the * file name to be used. * @var string */ private $_prefix = ''; /** * File postfix to be inserted in front of the token to create the * file name to be used. * @var string */ private $_postfix = ''; /** * Directory where to look for the files. The default is to look in the * current file. * * @var string */ private $_dir = './'; /** * Translate all HTML entities in the file to the corresponding HTML * entities before it is used as replacements. For example all '<' * will be translated to < before the content is inserted. * * @var boolean */ private $_translatehtml = true; /** * Sets the drectory where to look for the files to use for token replacement * * @param $translate * @internal param string $dir */ public function setTranslateHTML($translate) { $this->_translatehtml = (bool) $translate; } /** * Returns the drectory where to look for the files to use for token replacement */ public function getTranslateHTML() { return $this->_translatehtml; } /** * Sets the drectory where to look for the files to use for token replacement * * @param string $dir */ public function setDir($dir) { $this->_dir = (string) $dir; } /** * Returns the drectory where to look for the files to use for token replacement */ public function getDir() { return $this->_dir; } /** * Sets the prefix that is prepended to the token in order to create the file * name. For example if the token is 01 and the prefix is "example" then * the filename to look for will be "example01" * * @param string $prefix */ public function setPrefix($prefix) { $this->_prefix = (string) $prefix; } /* * Returns the prefix that is prepended to the token in order to create the file * name. For example if the token is 01 and the prefix is "example" then * the filename to look for will be "example01" */ /** * @return string */ public function getPrefix() { return $this->_prefix; } /** * Sets the postfix that is added to the token in order to create the file * name. For example if the token is 01 and the postfix is ".php" then * the filename to look for will be "01.php" * * @param string $postfix */ public function setPostfix($postfix) { $this->_postfix = (string) $postfix; } /** * Returns the postfix that is added to the token in order to create the file * name. For example if the token is 01 and the postfix is ".php" then * the filename to look for will be "01.php" */ public function getPostfix() { return $this->_postfix; } /** * Sets the "begin token" character. * * @param string $beginToken the character used to denote the beginning of a token. */ public function setBeginToken($beginToken) { $this->_beginToken = (string) $beginToken; } /** * Returns the "begin token" character. * * @return string The character used to denote the beginning of a token. */ public function getBeginToken() { return $this->_beginToken; } /** * Sets the "end token" character. * * @param string $endToken the character used to denote the end of a token */ public function setEndToken($endToken) { $this->_endToken = (string) $endToken; } /** * Returns the "end token" character. * * @return the character used to denote the beginning of a token */ public function getEndToken() { return $this->_endToken; } /** * Replace the token found with the appropriate file contents * @param array $matches Array of 1 el containing key to search for. * @return string Text with which to replace key or value of key if none is found. */ private function replaceTokenCallback($matches) { $filetoken = $matches[1]; // We look in all specified directories for the named file and use // the first directory which has the file. $dirs = explode(';', $this->_dir); $ndirs = count($dirs); $n = 0; $file = $dirs[$n] . $this->_prefix . $filetoken . $this->_postfix; while ($n < $ndirs && !is_readable($file)) { ++$n; } if (!is_readable($file) || $n >= $ndirs) { $this->log( "Can not read or find file \"$file\". Searched in directories: {$this->_dir}", Project::MSG_WARN ); //return $this->_beginToken . $filetoken . $this->_endToken; return "[Phing::Filters::ReplaceTokensWithFile: Can not find file " . '"' . $filetoken . $this->_postfix . '"' . "]"; } $buffer = file_get_contents($file); if ($this->_translatehtml) { $buffer = htmlentities($buffer); } if ($buffer === null) { $buffer = $this->_beginToken . $filetoken . $this->_endToken; $this->log("No corresponding file found for key \"$buffer\"", Project::MSG_WARN); } else { $this->log( "Replaced \"" . $this->_beginToken . $filetoken . $this->_endToken . "\" with content from file \"$file\"" ); } return $buffer; } /** * Returns stream with tokens having been replaced with appropriate values. * If a replacement value is not found for a token, the token is left in the stream. * * @param null $len * @return mixed filtered stream, -1 on EOF. */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } // read from next filter up the chain $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } // filter buffer $buffer = preg_replace_callback( "$" . preg_quote($this->_beginToken) . "([\w\.\-:\/]+?)" . preg_quote($this->_endToken) . "$", array($this, 'replaceTokenCallback'), $buffer ); return $buffer; } /** * Creates a new ReplaceTokensWithFile using the passed in * Reader for instantiation. * * @param Reader $reader * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new ReplaceTokensWithFile($reader); $newFilter->setProject($this->getProject()); $newFilter->setTranslateHTML($this->getTranslateHTML()); $newFilter->setDir($this->getDir()); $newFilter->setPrefix($this->getPrefix()); $newFilter->setPostfix($this->getPostfix()); $newFilter->setBeginToken($this->getBeginToken()); $newFilter->setEndToken($this->getEndToken()); $newFilter->setInitialized(true); return $newFilter; } /** * Initializes parameters * This method is only called when this filter is used through * a tag in build file. */ private function _initialize() { $params = $this->getParameters(); $n = count($params); if ($params !== null) { for ($i = 0; $i < $n; $i++) { if ($params[$i] !== null) { $name = $params[$i]->getName(); switch ($name) { case 'begintoken' : $this->_beginToken = $params[$i]->getValue(); break; case 'endtoken' : $this->_endToken = $params[$i]->getValue(); break; case 'dir': $this->_dir = $params[$i]->getValue(); break; case 'prefix': $this->_prefix = $params[$i]->getValue(); break; case 'postfix': $this->_postfix = $params[$i]->getValue(); break; case 'translatehtml': $this->_translatehtml = $params[$i]->getValue(); break; } } } } } } phing-2.17.4/filters/StripLineComments.php0000644000076500000240000001461614261771713017545 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * This filter strips line comments. * * Example: * *

 *   
 *   
 *   
 *   
 *   
 * 
* * Or: * *

 *   
 *   
 *   
 *   
 *   
 * 
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @version $Id: 8761015c0828acd83c3eeec2bac42e09125bd410 $ * @see BaseParamFilterReader * @package phing.filters */ class StripLineComments extends BaseParamFilterReader implements ChainableReader { /** Parameter name for the comment prefix. */ const COMMENTS_KEY = "comment"; /** Array that holds the comment prefixes. */ private $_comments = array(); /** * Returns stream only including * lines from the original stream which don't start with any of the * specified comment prefixes. * * @param null $len * @return mixed the resulting stream, or -1 * if the end of the resulting stream has been reached. * */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $lines = explode("\n", $buffer); $filtered = array(); $commentsSize = count($this->_comments); foreach ($lines as $line) { for ($i = 0; $i < $commentsSize; $i++) { $comment = $this->_comments[$i]->getValue(); if (StringHelper::startsWith($comment, ltrim($line))) { $line = null; break; } } if ($line !== null) { $filtered[] = $line; } } $filtered_buffer = implode("\n", $filtered); return $filtered_buffer; } /* * Adds a comment element to the list of prefixes. * * @return comment The comment element added to the * list of comment prefixes to strip. */ public function createComment() { $num = array_push($this->_comments, new Comment()); return $this->_comments[$num - 1]; } /* * Sets the list of comment prefixes to strip. * * @param comments A list of strings, each of which is a prefix * for a comment line. Must not be null. */ /** * @param $lineBreaks * @throws Exception */ public function setComments($lineBreaks) { if (!is_array($lineBreaks)) { throw new Exception("Excpected 'array', got something else"); } $this->_comments = $lineBreaks; } /* * Returns the list of comment prefixes to strip. * * @return array The list of comment prefixes to strip. */ /** * @return array */ public function getComments() { return $this->_comments; } /* * Creates a new StripLineComments using the passed in * Reader for instantiation. * * @param reader A Reader object providing the underlying stream. * Must not be null. * * @return a new filter based on this configuration, but filtering * the specified reader */ /** * @param Reader $reader * @return StripLineComments * @throws Exception */ public function chain(Reader $reader) { $newFilter = new StripLineComments($reader); $newFilter->setComments($this->getComments()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /* * Parses the parameters to set the comment prefixes. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0; $i < count($params); $i++) { if (self::COMMENTS_KEY === $params[$i]->getType()) { $comment = new Comment(); $comment->setValue($params[$i]->getValue()); array_push($this->_comments, $comment); } } } } } /** * The class that holds a comment representation. * * @package phing.filters */ class Comment { /** The prefix for a line comment. */ private $_value; /* * Sets the prefix for this type of line comment. * * @param string $value The prefix for a line comment of this type. * Must not be null. */ /** * @param $value */ public function setValue($value) { $this->_value = (string) $value; } /* * Returns the prefix for this type of line comment. * * @return string The prefix for this type of line comment. */ public function getValue() { return $this->_value; } } phing-2.17.4/filters/ConcatFilter.php0000644000076500000240000001551514261771713016502 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; include_once 'phing/system/io/PhingFile.php'; include_once 'phing/system/io/BufferedReader.php'; include_once 'phing/system/io/FileReader.php'; /** * Concats a file before and/or after the file. * * Example: * ``` * * * * * * * ``` * * Copies all php sources from `src` to `build` and adds the * content of `license.txt` add the beginning of each * file. * * @author Siad.ardroumli * @package phing.filters */ class ConcatFilter extends BaseParamFilterReader implements ChainableReader { /** * File to add before the content. * * @var PhingFile $prepend */ private $prepend; /** * File to add after the content. * * @var PhingFile $append */ private $append; /** * Reader for prepend-file. * @var BufferedReader */ private $prependReader; /** * Reader for append-file. * @var BufferedReader */ private $appendReader; /** * @param Reader $in */ public function __construct(Reader $in = null) { parent::__construct($in); } /** * Returns the next character in the filtered stream. If the desired * number of lines have already been read, the resulting stream is * effectively at an end. Otherwise, the next character from the * underlying stream is read and returned. * * @param int $len * @return int|string the next character in the resulting stream, or -1 * if the end of the resulting stream has been reached * * @throws IOException if the underlying stream throws an IOException * during reading * @throws BuildException */ public function read($len = 0) { // do the "singleton" initialization if (!$this->getInitialized()) { $this->initialize(); $this->setInitialized(true); } $ch = -1; // The readers return -1 if they end. So simply read the "prepend" // after that the "content" and at the end the "append" file. if ($this->prependReader !== null) { $ch = $this->prependReader->read(); if ($ch === -1) { // I am the only one so I have to close the reader $this->prependReader->close(); $this->prependReader = null; } } if ($ch === -1) { $ch = parent::read(); } if ($ch === -1 && $this->appendReader !== null) { $ch = $this->appendReader->read(); if ($ch === -1) { // I am the only one so I have to close the reader $this->appendReader->close(); $this->appendReader = null; } } return $ch; } /** * Scans the parameters list for the "lines" parameter and uses * it to set the number of lines to be returned in the filtered stream. * also scan for skip parameter. * * @throws BuildException */ private function initialize() { // get parameters $params = $this->getParameters(); if ($params !== null) { /** @var Parameter $param */ foreach ($params as $param) { if ('prepend' === $param->getName()) { $this->setPrepend(new PhingFile($param->getValue())); continue; } if ('append' === $param->getName()) { $this->setAppend(new PhingFile($param->getValue())); continue; } } } if ($this->prepend !== null) { if (!$this->prepend->isAbsolute()) { $this->prepend = new PhingFile($this->getProject()->getBasedir(), $this->prepend->getPath()); } $this->prependReader = new BufferedReader(new FileReader($this->prepend)); } if ($this->append !== null) { if (!$this->append->isAbsolute()) { $this->append = new PhingFile($this->getProject()->getBasedir(), $this->append->getPath()); } $this->appendReader = new BufferedReader(new FileReader($this->append)); } } /** * Creates a new ConcatReader using the passed in * Reader for instantiation. * * @param Reader $rdr A Reader object providing the underlying stream. * Must not be null. * * @return ConcatFilter a new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $rdr) { $newFilter = new ConcatFilter($rdr); $newFilter->setProject($this->getProject()); $newFilter->setPrepend($this->getPrepend()); $newFilter->setAppend($this->getAppend()); return $newFilter; } /** * Returns `prepend` attribute. * @return PhingFile prepend attribute */ public function getPrepend() { return $this->prepend; } /** * Sets `prepend` attribute. * @param PhingFile|string prepend new value */ public function setPrepend($prepend) { if ($prepend instanceof PhingFile) { $this->prepend = $prepend; } else { $this->prepend = new PhingFile($prepend); } } /** * Returns `append` attribute. * @return PhingFile append attribute */ public function getAppend() { return $this->append; } /** * Sets `append` attribute. * @param PhingFile|string append new value */ public function setAppend($append) { $this->append = $append; } } phing-2.17.4/filters/TailFilter.php0000644000076500000240000001166314261771713016164 0ustar mrookstaff. */ require_once 'phing/filters/BaseParamFilterReader.php'; /** * Reads the last n lines of a stream. (Default is last10 lines.) * * Example: * *
* * Or: * *

 *   
 * 
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @copyright 2003 seasonfive. All rights reserved * * @see BaseParamFilterReader * * @package phing.filters */ class TailFilter extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for the number of lines to be returned. * @var string */ const LINES_KEY = "lines"; /** * Number of lines to be returned in the filtered stream. * @var integer */ private $_lines = 10; /** * Array to hold lines. * @var array */ private $_lineBuffer = array(); /** * Returns the last n lines of a file. * @param int $len Num chars to read. * @return mixed The filtered buffer or -1 if EOF. */ public function read($len = null) { while (($buffer = $this->in->read($len)) !== -1) { // Remove the last "\n" from buffer for // prevent explode to add an empty cell at // the end of array $buffer = trim($buffer, "\n"); $lines = explode("\n", $buffer); if (count($lines) >= $this->_lines) { // Buffer have more (or same) number of lines than needed. // Fill lineBuffer with the last "$this->_lines" lasts ones. $off = count($lines) - $this->_lines; $this->_lineBuffer = array_slice($lines, $off); } else { // Some new lines ... // Prepare space for insert these new ones $this->_lineBuffer = array_slice($this->_lineBuffer, count($lines) - 1); $this->_lineBuffer = array_merge($this->_lineBuffer, $lines); } } if (empty($this->_lineBuffer)) { $ret = -1; } else { $ret = implode("\n", $this->_lineBuffer); $this->_lineBuffer = array(); } return $ret; } /** * Sets the number of lines to be returned in the filtered stream. * * @param integer $lines the number of lines to be returned in the filtered stream. */ public function setLines($lines) { $this->_lines = (int) $lines; } /** * Returns the number of lines to be returned in the filtered stream. * * @return integer The number of lines to be returned in the filtered stream. */ public function getLines() { return $this->_lines; } /** * Creates a new TailFilter using the passed in * Reader for instantiation. * * @param Reader $reader A Reader object providing the underlying stream. * Must not be null. * * @return TailFilter A new filter based on this configuration, but filtering * the specified reader. */ public function chain(Reader $reader) { $newFilter = new TailFilter($reader); $newFilter->setLines($this->getLines()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Scans the parameters list for the "lines" parameter and uses * it to set the number of lines to be returned in the filtered stream. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if (self::LINES_KEY == $params[$i]->getName()) { $this->_lines = (int) $params[$i]->getValue(); break; } } } } } phing-2.17.4/filters/PrefixLines.php0000644000076500000240000001050714261771713016351 0ustar mrookstaff. */ include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Attaches a prefix to every line. * * Example: *
* * Or: * *

 *  
 * 
* * @author Yannick Lecaillez * @author hans lellelid, hans@velum.net * @version $Id: 71f5cbabef2b2bfd436cd79187e0cecd172d10a2 $ * @see FilterReader * @package phing.filters */ class PrefixLines extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for the prefix. * @var string */ const PREFIX_KEY = "lines"; /** * The prefix to be used. * @var string */ private $_prefix = null; /** * Adds a prefix to each line of input stream and returns resulting stream. * * @param null $len * @return mixed buffer, -1 on EOF */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1) { return -1; } $lines = explode("\n", $buffer); $filtered = array(); foreach ($lines as $line) { $line = $this->_prefix . $line; $filtered[] = $line; } $filtered_buffer = implode("\n", $filtered); return $filtered_buffer; } /** * Sets the prefix to add at the start of each input line. * * @param string $prefix The prefix to add at the start of each input line. * May be null, in which case no prefix * is added. */ public function setPrefix($prefix) { $this->_prefix = (string) $prefix; } /** * Returns the prefix which will be added at the start of each input line. * * @return string The prefix which will be added at the start of each input line */ public function getPrefix() { return $this->_prefix; } /** * Creates a new PrefixLines filter using the passed in * Reader for instantiation. * * @param Reader $reader * @internal param A $object Reader object providing the underlying stream. * Must not be null. * * @return object A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new PrefixLines($reader); $newFilter->setPrefix($this->getPrefix()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Initializes the prefix if it is available from the parameters. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if (self::PREFIX_KEY == $params[$i]->getName()) { $this->_prefix = (string) $params[$i]->getValue(); break; } } } } } phing-2.17.4/filters/PhpArrayMapLines.php0000644000076500000240000001063514261771713017302 0ustar mrookstaff. */ include_once 'phing/BuildException.php'; include_once 'phing/filters/BaseParamFilterReader.php'; include_once 'phing/filters/ChainableReader.php'; /** * Applies a native php function to the original input. * * Example: *
* * Or: * *

 *  
 * 
* * @author Siad Ardroumli * @package phing.filters */ class PhpArrayMapLines extends BaseParamFilterReader implements ChainableReader { /** * Parameter name for the function. * @var string */ const FUNCTION_KEY = "function"; /** * The function to be used. * @var string */ private $function = null; /** * Applies a native php function to the original input and returns resulting stream. * * @param null $len * @return mixed buffer, -1 on EOF */ public function read($len = null) { if (!$this->getInitialized()) { $this->_initialize(); $this->checkAttributes(); $this->setInitialized(true); } $buffer = $this->in->read($len); if ($buffer === -1 || !function_exists($this->function)) { return -1; } $lines = explode("\n", $buffer); $filtered = array_map($this->function, $lines); $filtered_buffer = implode("\n", $filtered); return $filtered_buffer; } /** * Sets the function used by array_map. * * @param string $function The function used by array_map. */ public function setFunction($function) { $this->function = (string) $function; } /** * Returns the prefix which will be added at the start of each input line. * * @return string The prefix which will be added at the start of each input line */ public function getFunction() { return $this->function; } /** * Make sure that required attributes are set. * @throws BuildException - if any required attribs aren't set. */ protected function checkAttributes() { if (!$this->function) { throw new BuildException("You must specify a value for the 'function' attribute."); } } /** * Creates a new PhpArrayMapLines filter using the passed in * Reader for instantiation. * * @param Reader $reader Reader object providing the underlying stream. * Must not be null. * * @return PhpArrayMapLines A new filter based on this configuration, but filtering * the specified reader */ public function chain(Reader $reader) { $newFilter = new PhpArrayMapLines($reader); $newFilter->setFunction($this->getFunction()); $newFilter->setInitialized(true); $newFilter->setProject($this->getProject()); return $newFilter; } /** * Initializes the function if it is available from the parameters. */ private function _initialize() { $params = $this->getParameters(); if ($params !== null) { for ($i = 0, $_i = count($params); $i < $_i; $i++) { if (self::FUNCTION_KEY == $params[$i]->getName()) { $this->function = (string) $params[$i]->getValue(); break; } } } } } phing-2.17.4/tasks/ext/XmlLintTask.php0000644000076500000240000001456514261771713016620 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * A XML lint task. Checking syntax of one or more XML files against an XML Schema using the DOM extension. * * @author Knut Urdalen * @version $Id: d9b238ee17a88afe34f9db53a4c944c92ac27278 $ * @package phing.tasks.ext */ class XmlLintTask extends Task { protected $file; // the source file (from xml attribute) protected $schema; // the schema file (from xml attribute) protected $filesets = array(); // all fileset objects assigned to this task protected $useRNG = false; protected $haltonfailure = true; /** * File to be performed syntax check on * * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * XML Schema Description file to validate against * * @param PhingFile $schema */ public function setSchema(PhingFile $schema) { $this->schema = $schema; } /** * Use RNG instead of DTD schema validation * * @param bool $bool */ public function setUseRNG($bool) { $this->useRNG = (boolean) $bool; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets the haltonfailure attribute * * @param bool $haltonfailure * * @return void */ public function setHaltonfailure($haltonfailure) { $this->haltonfailure = (bool) $haltonfailure; } /** * Execute lint check against PhingFile or a FileSet. * * {@inheritdoc} * * @throws BuildException * * @return void */ public function main() { if (isset($this->schema) && !file_exists($this->schema->getPath())) { throw new BuildException("Schema file not found: " . $this->schema->getPath()); } if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } set_error_handler(array($this, 'errorHandler')); if ($this->file instanceof PhingFile) { $this->lint($this->file->getPath()); } else { // process filesets $project = $this->getProject(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($project); $files = $ds->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath(); foreach ($files as $file) { $this->lint($dir . DIRECTORY_SEPARATOR . $file); } } } restore_error_handler(); } /** * @param $message * * @return void * * @throws BuildException */ protected function logError($message) { if ($this->haltonfailure) { throw new BuildException($message); } else { $this->log($message, Project::MSG_ERR); } } /** * Performs validation * * @param string $file * * @return void */ protected function lint($file) { if (file_exists($file)) { if (is_readable($file)) { $dom = new DOMDocument(); if ($dom->load($file) === false) { $error = libxml_get_last_error(); $this->logError($file . ' is not well-formed (See messages above)'); } else { if (isset($this->schema)) { if ($this->useRNG) { if ($dom->relaxNGValidate($this->schema->getPath())) { $this->log($file . ' validated with RNG grammar', Project::MSG_INFO); } else { $this->logError($file . ' fails to validate (See messages above)'); } } else { if ($dom->schemaValidate($this->schema->getPath())) { $this->log($file . ' validated with schema', Project::MSG_INFO); } else { $this->logError($file . ' fails to validate (See messages above)'); } } } else { $this->log( $file . ' is well-formed (not validated due to missing schema specification)', Project::MSG_INFO ); } } } else { $this->logError('Permission denied to read file: ' . $file); } } else { $this->logError('File not found: ' . $file); } } /** * Local error handler to catch validation errors and log them through Phing * * @param int $level * @param string $message * @param string $file * @param int $line * @param mixed $context * * @return void */ public function errorHandler($level, $message, $file, $line, $context) { $matches = array(); preg_match('/^.*\(\): (.*)$/', $message, $matches); $this->log($matches[1], Project::MSG_ERR); } } phing-2.17.4/tasks/ext/svn/SvnListTask.php0000644000076500000240000001054414261771713017432 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Stores the output of a list command on a workingcopy or repositoryurl in a property. * This stems from the SvnLastRevisionTask. * * @author Anton Stöckl * @author Michiel Rook (SvnLastRevisionTask) * @version $Id: bb6bda1d445fc14e863a2c88b2d11acaebe757c0 $ * @package phing.tasks.ext.svn * @see VersionControl_SVN * @since 2.1.0 */ class SvnListTask extends SvnBaseTask { private $propertyName = "svn.list"; private $limit = null; private $orderDescending = false; /** * Sets the name of the property to use * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use */ public function getPropertyName() { return $this->propertyName; } /** * Sets whether to force compatibility with older SVN versions (< 1.2) * @deprecated * @param $force */ public function setForceCompatible($force) { } /** * Sets the max num of tags to display * @param $limit */ public function setLimit($limit) { $this->limit = (int) $limit; } /** * Sets whether to sort tags in descending order * @param $orderDescending */ public function setOrderDescending($orderDescending) { $this->orderDescending = (bool) $orderDescending; } /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('list'); if ($this->oldVersion) { $this->svn->setOptions(array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_XML)); $output = $this->run(array('--xml')); if (!($xmlObj = @simplexml_load_string($output))) { throw new BuildException("Failed to parse the output of 'svn list --xml'."); } $objects = $xmlObj->list->entry; $entries = array(); foreach ($objects as $object) { $entries[] = array( 'commit' => array( 'revision' => (string) $object->commit['revision'], 'author' => (string) $object->commit->author, 'date' => (string) $object->commit->date ), 'name' => (string) $object->name ); } } else { $output = $this->run(array()); $entries = $output['list'][0]['entry']; } if ($this->orderDescending) { $entries = array_reverse($entries); } $result = null; $count = 0; foreach ($entries as $entry) { if ($this->limit > 0 && $count >= $this->limit) { break; } $result .= (!empty($result)) ? "\n" : ''; $result .= $entry['commit']['revision'] . ' | ' . $entry['commit']['author'] . ' | ' . $entry['commit']['date'] . ' | ' . $entry['name']; $count++; } if (!empty($result)) { $this->project->setProperty($this->getPropertyName(), $result); } else { throw new BuildException("Failed to parse the output of 'svn list'."); } } } phing-2.17.4/tasks/ext/svn/SvnCopyTask.php0000644000076500000240000000377314261771713017437 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Copies a repository from the repository url to another * * @version $Id: 0b4894341e10f5f3ba44a669707b7727b58383f5 $ * @package phing.tasks.ext.svn * @since 2.3.0 */ class SvnCopyTask extends SvnBaseTask { private $message = ""; /** * Sets the message * @param $message */ public function setMessage($message) { $this->message = $message; } /** * Gets the message */ public function getMessage() { return $this->message; } /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('copy'); $this->log("Copying SVN repository from '" . $this->getRepositoryUrl() . "' to '" . $this->getToDir() . "'"); $options = array(); if (strlen($this->getMessage()) > 0) { $options['message'] = $this->getMessage(); } $this->run(array($this->getToDir()), $options); } } phing-2.17.4/tasks/ext/svn/SvnLastRevisionTask.php0000644000076500000240000000655314261771713021146 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Stores the number of the last revision of a workingcopy in a property * * @author Michiel Rook * @version $Id: 61bd055f46bd8430785610a76271250d2e30786e $ * @package phing.tasks.ext.svn * @see VersionControl_SVN * @since 2.1.0 */ class SvnLastRevisionTask extends SvnBaseTask { private $propertyName = "svn.lastrevision"; private $lastChanged = false; /** * Sets the name of the property to use * @param string $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use * @return string */ public function getPropertyName() { return $this->propertyName; } /** * Sets whether to force compatibility with older SVN versions (< 1.2) * * Retained for legacy reasons * @deprecated * @param $force */ public function setForceCompatible($force) { } /** * Sets whether to retrieve the last changed revision * @param $lastChanged */ public function setLastChanged($lastChanged) { $this->lastChanged = (bool) $lastChanged; } /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('info'); if ($this->oldVersion) { $output = $this->run(array('--xml')); if (!($xmlObj = @simplexml_load_string($output))) { throw new BuildException("Failed to parse the output of 'svn info --xml'."); } if ($this->lastChanged) { $found = (int) $xmlObj->entry->commit['revision']; } else { $found = (int) $xmlObj->entry['revision']; } } else { $output = $this->run(); if (empty($output) || !isset($output['entry'][0])) { throw new BuildException("Failed to parse the output of 'svn info'."); } if ($this->lastChanged) { $found = $output['entry'][0]['commit']['revision']; } else { $found = $output['entry'][0]['revision']; } } $this->project->setProperty($this->getPropertyName(), $found); } } phing-2.17.4/tasks/ext/svn/SvnUpdateTask.php0000644000076500000240000000417214261771713017741 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Updates a repository in local directory * * @author Andrew Eddie * @version $Id: e29c24db4d10667a89d1829fe80075fbf8e3292c $ * @package phing.tasks.ext.svn * @since 2.3.0 */ class SvnUpdateTask extends SvnBaseTask { /** * Which Revision to Export * * @todo check if version_control_svn supports constants * * @var string */ private $revision = 'HEAD'; /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('update'); $this->log( "Updating SVN repository at '" . $this->getToDir( ) . "'" . ($this->revision == 'HEAD' ? '' : " (revision: {$this->revision})") ); // revision $switches = array( 'r' => $this->revision, ); $this->run(array($this->getToDir()), $switches); } /** * @param $revision */ public function setRevision($revision) { $this->revision = $revision; } } phing-2.17.4/tasks/ext/svn/SvnExportTask.php0000644000076500000240000000417514261771713020003 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Exports/checks out a repository to a local directory * with authentication * * @author Michiel Rook * @author Andrew Eddie * @version $Id: d12b9c4d44e42e6a36e544fbb0f03c0bd64ec428 $ * @package phing.tasks.ext.svn * @since 2.2.0 */ class SvnExportTask extends SvnBaseTask { /** * Which Revision to Export * * @todo check if version_control_svn supports constants * * @var string */ private $revision = 'HEAD'; /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('export'); $this->log("Exporting SVN repository to '" . $this->getToDir() . "'"); $switches = array(); if (!empty($this->revision)) { $switches['r'] = $this->revision; } $this->run(array($this->getToDir()), $switches); } /** * @param $revision */ public function setRevision($revision) { $this->revision = $revision; } } phing-2.17.4/tasks/ext/svn/SvnCommitTask.php0000644000076500000240000000654014261771713017750 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Commits changes in a local working copy to the repository * * @author Johan Persson * @version $Id: eec7114955b928683994705ad4dc68fe246ef23f $ * @package phing.tasks.ext.svn * @since 2.4.0 */ class SvnCommitTask extends SvnBaseTask { /** * Commit message */ private $message = ''; /** * Property name where we store the revision number of the just * committed version. */ private $propertyName = "svn.committedrevision"; /** * Sets the commit message * @param $message */ public function setMessage($message) { $this->message = $message; } /** * Gets the commit message */ public function getMessage() { return $this->message; } /** * Sets the name of the property to use for returned revision * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use for returned revision */ public function getPropertyName() { return $this->propertyName; } /** * The main entry point * * @throws BuildException */ public function main() { if (trim($this->message) === '') { throw new BuildException('SVN Commit message can not be empty.'); } $this->setup('commit'); $this->log( "Committing SVN working copy at '" . $this->getWorkingCopy() . "' with message '" . $this->GetMessage() . "'" ); $output = $this->run(array(), array('message' => $this->GetMessage())); if (preg_match('/[\s]*Committed revision[\s]+([\d]+)/', $output, $matches)) { $this->project->setProperty($this->getPropertyName(), $matches[1]); } else { /** * If no new revision was committed set revision to "empty". Remember that * this is not necessarily an error. It could be that the specified working * copy is identical to the copy in the repository and in that case * there will be no update and no new revision number. */ $this->project->setProperty($this->getPropertyName(), ''); } } } phing-2.17.4/tasks/ext/svn/SvnBaseTask.php0000644000076500000240000002275214261771713017375 0ustar mrookstaff. */ include_once 'phing/Task.php'; /** * Base class for Subversion tasks * * @author Michiel Rook * @author Andrew Eddie * * @package phing.tasks.ext.svn * * @see VersionControl_SVN * @since 2.2.0 */ abstract class SvnBaseTask extends Task { /** * @var string */ private $workingCopy = ""; /** * @var string */ private $repositoryUrl = ""; /** * @var string */ private $svnPath = "/usr/bin/svn"; protected $svn = null; private $mode = ""; private $svnArgs = array(); private $svnSwitches = array(); private $toDir = ""; protected $fetchMode; protected $oldVersion = false; /** * Initialize Task. * This method includes any necessary SVN libraries and triggers * appropriate error if they cannot be found. This is not done in header * because we may want this class to be loaded w/o triggering an error. */ public function init() { include_once 'VersionControl/SVN.php'; $this->fetchMode = VERSIONCONTROL_SVN_FETCHMODE_ASSOC; if (!class_exists('VersionControl_SVN')) { throw new Exception("The SVN tasks depend on PEAR VersionControl_SVN package being installed."); } } /** * Sets the path to the workingcopy * @param $workingCopy */ public function setWorkingCopy($workingCopy) { $this->workingCopy = $workingCopy; } /** * Returns the path to the workingcopy */ public function getWorkingCopy() { return $this->workingCopy; } /** * Sets the path/URI to the repository * @param $repositoryUrl */ public function setRepositoryUrl($repositoryUrl) { $this->repositoryUrl = $repositoryUrl; } /** * Returns the path/URI to the repository */ public function getRepositoryUrl() { return $this->repositoryUrl; } /** * Sets the path to the SVN executable * @param $svnPath */ public function setSvnPath($svnPath) { $this->svnPath = $svnPath; } /** * Returns the path to the SVN executable */ public function getSvnPath() { return $this->svnPath; } // // Args // /** * Sets the path to export/checkout to * @param $toDir */ public function setToDir($toDir) { $this->toDir = $toDir; } /** * Returns the path to export/checkout to */ public function getToDir() { return $this->toDir; } // // Switches // /** * Sets the force switch * @param $value */ public function setForce($value) { $this->svnSwitches['force'] = $value; } /** * Returns the force switch */ public function getForce() { return isset($this->svnSwitches['force']) ? $this->svnSwitches['force'] : ''; } /** * Sets the username of the user to export * @param $value */ public function setUsername($value) { $this->svnSwitches['username'] = $value; } /** * Returns the username */ public function getUsername() { return isset($this->svnSwitches['username']) ? $this->svnSwitches['username'] : ''; } /** * Sets the password of the user to export * @param $value */ public function setPassword($value) { $this->svnSwitches['password'] = $value; } /** * Returns the password */ public function getPassword() { return isset($this->svnSwitches['password']) ? $this->svnSwitches['password'] : ''; } /** * Sets the no-auth-cache switch * @param $value */ public function setNoCache($value) { $this->svnSwitches['no-auth-cache'] = $value; } /** * Returns the no-auth-cache switch */ public function getNoCache() { return isset($this->svnSwitches['no-auth-cache']) ? $this->svnSwitches['no-auth-cache'] : ''; } /** * Sets the recursive switch * @deprecated * @param $value */ public function setRecursive($value) { } /** * Returns the recursive switch * @deprecated */ public function getRecursive() { } /** * Sets the depth switch * @param $value */ public function setDepth($value) { $this->svnSwitches['depth'] = $value; } /** * Returns the depth switch */ public function getDepth() { return isset($this->svnSwitches['depth']) ? $this->svnSwitches['depth'] : ''; } /** * Sets the ignore-externals switch * @param $value */ public function setIgnoreExternals($value) { $this->svnSwitches['ignore-externals'] = $value; } /** * Returns the ignore-externals switch */ public function getIgnoreExternals() { return isset($this->svnSwitches['ignore-externals']) ? $this->svnSwitches['ignore-externals'] : ''; } /** * Sets the trust-server-cert switch * @param $value */ public function setTrustServerCert($value) { $this->svnSwitches['trust-server-cert'] = $value; } /** * Returns the trust-server-cert switch */ public function getTrustServerCert() { return isset($this->svnSwitches['trust-server-cert']) ? $this->svnSwitches['trust-server-cert'] : ''; } /** * Creates a VersionControl_SVN class based on $mode * * @param string The SVN mode to use (info, export, checkout, ...) * @throws BuildException */ protected function setup($mode) { $this->mode = $mode; // Set up runtime options. Will be passed to all // subclasses. $options = array('fetchmode' => $this->fetchMode); if ($this->oldVersion) { $options['svn_path'] = $this->getSvnPath(); } else { $options['binaryPath'] = $this->getSvnPath(); } // Pass array of subcommands we need to factory $this->svn = VersionControl_SVN::factory($mode, $options); if (get_parent_class($this->svn) !== 'VersionControl_SVN_Command') { $this->oldVersion = true; $this->svn->use_escapeshellcmd = false; } if (!empty($this->repositoryUrl)) { $this->svnArgs = array($this->repositoryUrl); } else { if (!empty($this->workingCopy)) { if (is_dir($this->workingCopy)) { $this->svnArgs = array($this->workingCopy); } else { if ($mode == 'info') { if (is_file($this->workingCopy)) { $this->svnArgs = array($this->workingCopy); } else { throw new BuildException("'" . $this->workingCopy . "' is not a directory nor a file"); } } else { throw new BuildException("'" . $this->workingCopy . "' is not a directory"); } } } } } /** * Executes the constructed VersionControl_SVN instance * * @param array $args * @param array $switches * @throws BuildException * @internal param Additional $array arguments to pass to SVN. * @internal param Switches $array to pass to SVN. * @return string Output generated by SVN. */ protected function run($args = array(), $switches = array()) { $tempArgs = array_merge($this->svnArgs, $args); $tempSwitches = array_merge($this->svnSwitches, $switches); if ($this->oldVersion) { $svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN'); if ($output = $this->svn->run($tempArgs, $tempSwitches)) { return $output; } if (count($errs = $svnstack->getErrors())) { $err = current($errs); $errorMessage = $err['message']; if (isset($err['params']['errstr'])) { $errorMessage = $err['params']['errstr']; } throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $errorMessage); } } else { try { return $this->svn->run($tempArgs, $tempSwitches); } catch (Exception $e) { throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $e->getMessage()); } } } } phing-2.17.4/tasks/ext/svn/SvnSwitchTask.php0000644000076500000240000000447614261771713017767 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Switches a repository at a given local directory to a different location * * @author Dom Udall * @version $Id: f840cd73068d8b9cf90051b0be3101ee9f22d4fc $ * @package phing.tasks.ext.svn * @since 2.4.3 */ class SvnSwitchTask extends SvnBaseTask { /** * Which Revision to Export * * @todo check if version_control_svn supports constants * * @var string */ private $revision = 'HEAD'; /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('switch'); $this->log( "Switching SVN repository at '" . $this->getToDir() . "' to '" . $this->getRepositoryUrl() . "' " . ($this->getRevision() == 'HEAD' ? '' : " (revision: {$this->getRevision()})") ); // revision $switches = array( 'r' => $this->getRevision(), ); $this->run(array($this->getToDir()), $switches); } /** * @param $revision */ public function setRevision($revision) { $this->revision = $revision; } /** * @return string */ public function getRevision() { return $this->revision; } } phing-2.17.4/tasks/ext/svn/SvnLogTask.php0000644000076500000240000000650214261771713017237 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Stores the output of a log command on a workingcopy or repositoryurl in a property. * This stems from the SvnLastRevisionTask. * * @author Anton Stöckl * @author Michiel Rook (SvnLastRevisionTask) * @version $Id: 7e1ed209fca1c776aa105241110a78a65284f6ae $ * @package phing.tasks.ext.svn * @see VersionControl_SVN * @since 2.1.0 */ class SvnLogTask extends SvnBaseTask { private $propertyName = "svn.log"; private $limit = null; /** * Sets the name of the property to use * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use */ public function getPropertyName() { return $this->propertyName; } /** * Sets whether to force compatibility with older SVN versions (< 1.2) * @deprecated * @param $force */ public function setForceCompatible($force) { } /** * Sets the max num of log entries to get from svn * @param $limit */ public function setLimit($limit) { $this->limit = (int) $limit; } /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('log'); $switches = array(); if ($this->limit > 0) { $switches['limit'] = $this->limit; } $output = $this->run(array(), $switches); $result = null; if ($this->oldVersion) { foreach ($output as $line) { $result .= (!empty($result)) ? "\n" : ''; $result .= "{$line['REVISION']} | {$line['AUTHOR']} | {$line['DATE']} | {$line['MSG']}"; } } else { foreach ($output['logentry'] as $line) { $result .= (!empty($result)) ? "\n" : ''; $result .= "{$line['revision']} | {$line['author']} | {$line['date']} | {$line['msg']}"; } } if (!empty($result)) { $this->project->setProperty($this->getPropertyName(), $result); } else { throw new BuildException("Failed to parse the output of 'svn log'."); } } } phing-2.17.4/tasks/ext/svn/SvnInfoTask.php0000644000076500000240000000706214261771713017413 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Parses the output of 'svn info --xml' and * * @author Michiel Rook * * @package phing.tasks.ext.svn * * @see VersionControl_SVN * @since 2.4.9 */ class SvnInfoTask extends SvnBaseTask { private $propertyName = "svn.info"; private $element = 'url'; private $subElement = null; /** * Sets the name of the property to use * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use */ public function getPropertyName() { return $this->propertyName; } /** * Sets the name of the xml element to use. * * @param string $element * * @return void */ public function setElement($element) { $this->element = $element; } /** * Returns the name of the xml element to use. * * @return string */ public function getElement() { return $this->element; } /** * Sets the name of the xml sub element to use. * * @param $subElement * * @return void */ public function setSubElement($subElement) { $this->subElement = $subElement; } /** * Returns the name of the xml sub element to use. * * @return string */ public function getSubElement() { return $this->subElement; } /** * The main entry point. * * @return void * * @throws BuildException */ public function main() { $this->setup('info'); if ($this->oldVersion) { $output = $this->run(array('--xml', '--incremental')); if (!($xmlObj = @simplexml_load_string($output))) { throw new BuildException("Failed to parse the output of 'svn info --xml'."); } $object = $xmlObj->{$this->element}; if (!empty($this->subElement)) { $object = $object->{$this->subElement}; } } else { $output = $this->run(); if (empty($output) || !isset($output['entry'][0])) { throw new BuildException("Failed to parse the output of 'svn info'."); } $object = $output['entry'][0][$this->element]; if (!empty($this->subElement)) { $object = $object[$this->subElement]; } } $this->project->setProperty($this->getPropertyName(), (string) $object); } } phing-2.17.4/tasks/ext/svn/SvnCheckoutTask.php0000644000076500000240000000420714261771713020263 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; /** * Checks out a repository to a local directory * * @author Andrew Eddie * @version $Id: 34178e3af0b03b5da591c716f43bbc49a25cdcb4 $ * @package phing.tasks.ext.svn * @since 2.3.0 */ class SvnCheckoutTask extends SvnBaseTask { /** * Which Revision to Export * * @todo check if version_control_svn supports constants * * @var string */ private $revision = 'HEAD'; /** * The main entry point * * @throws BuildException */ public function main() { $this->setup('checkout'); $this->log( "Checking out SVN repository to '" . $this->getToDir( ) . "'" . ($this->revision == 'HEAD' ? '' : " (revision: {$this->revision})") ); // revision $switches = array( 'r' => $this->revision, ); $this->run(array($this->getToDir()), $switches); } /** * @param $revision */ public function setRevision($revision) { $this->revision = $revision; } } phing-2.17.4/tasks/ext/FileSizeTask.php0000644000076500000240000000653714261771713016743 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * fileHash * * Calculate either MD5 or SHA hash value of a specified file and retun the * value in a property * * @author Johan Persson * @version $Id: d4b97a2e512ffe10394e203d6a94c498e11ca986 $ * @package phing.tasks.ext */ class FileSizeTask extends Task { /** * Property for File * @var PhingFile file */ private $file; /** * Property where the file size will be stored * @var string $property */ private $propertyName = "filesize"; /** * Which file to calculate the file size of * @param PhingFile $file */ public function setFile($file) { $this->file = $file; } /** * Set the name of the property to store the file size * @param $property * @return void */ public function setPropertyName($property) { $this->propertyName = $property; } /** * Main-Method for the Task * * @return void * @throws BuildException */ public function main() { $this->checkFile(); $this->checkPropertyName(); $size = filesize($this->file); if ($size === false) { throw new BuildException(sprintf('[FileSize] Cannot determine size of file: %s', $this->file)); } // publish hash value $this->project->setProperty($this->propertyName, $size); } /** * checks file attribute * @return void * @throws BuildException */ private function checkFile() { // check File if ($this->file === null || strlen($this->file) == 0 ) { throw new BuildException('[FileSize] You must specify an input file.', $this->file); } if (!is_readable($this->file)) { throw new BuildException(sprintf( '[FileSize] Input file does not exist or is not readable: %s', $this->file )); } } /** * checks property attribute * @return void * @throws BuildException */ private function checkPropertyName() { if (is_null($this->propertyName) || strlen($this->propertyName) === 0 ) { throw new BuildException('[FileSize] Property name for publishing file size is not set'); } } } phing-2.17.4/tasks/ext/phpdoc/PhpDocumentor2Wrapper.php0000644000076500000240000001751114261771713022067 0ustar mrookstaff. */ /** * Wrapper around PhpDocumentor2 (so we retain * PHP 5.2 compatibility in the main task) * * @author Michiel Rook * @version $Id: 9f22f2863b649ddf3820399fd5738c58900b3a24 $ * @since 2.4.10 * @package phing.tasks.ext.phpdoc */ class PhpDocumentor2Wrapper { /** * Phing project instance * @var Project */ private $project = null; /** * List of filesets * @var FileSet[] */ private $filesets = array(); /** * Destination/target directory * @var PhingFile */ private $destDir = null; /** * name of the template to use * @var string */ private $template = "responsive-twig"; /** * Title of the project * @var string */ private $title = "API Documentation"; /** * Name of the default package * @var string */ private $defaultPackageName = "Default"; /** * Path to the phpDocumentor 2 source * @var string */ private $phpDocumentorPath = ""; /** * Path to the phpDocumentor .phar * @var string */ private $pharLocation = ''; /** * @var \phpDocumentor\Application */ private $app = null; /** * Sets project instance * * @param Project $project */ public function setProject($project) { $this->project = $project; } /** * Sets filesets array * * @param FileSet[] $filesets */ public function setFilesets($filesets) { $this->filesets = $filesets; } /** * Sets destination/target directory * @param PhingFile $destDir */ public function setDestDir(PhingFile $destDir) { $this->destDir = $destDir; } /** * Sets the template to use * @param string $template */ public function setTemplate($template) { $this->template = (string) $template; } /** * Sets the title of the project * @param string $title */ public function setTitle($title) { $this->title = (string) $title; } /** * Sets the default package name * @param string $defaultPackageName */ public function setDefaultPackageName($defaultPackageName) { $this->defaultPackageName = (string) $defaultPackageName; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Finds and initializes the phpDocumentor installation */ private function initializePhpDocumentor() { $phpDocumentorPath = ''; if (!empty($this->pharLocation)) { include_once 'phar://' . $this->pharLocation . '/vendor/autoload.php'; if (!class_exists('phpDocumentor\\Bootstrap')) { throw new BuildException( $this->pharLocation . ' does not look like a phpDocumentor 2 .phar' ); } } elseif (class_exists('Composer\\Autoload\\ClassLoader', false)) { if (!class_exists('phpDocumentor\\Bootstrap')) { throw new BuildException('You need to install phpDocumentor 2 or add your include path to your composer installation.'); } } else { $phpDocumentorPath = $this->findPhpDocumentorPath(); if (empty($phpDocumentorPath)) { throw new BuildException("Please make sure phpDocumentor 2 is installed and on the include_path."); } set_include_path($phpDocumentorPath . PATH_SEPARATOR . get_include_path()); require_once $phpDocumentorPath . '/phpDocumentor/Bootstrap.php'; } $this->app = \phpDocumentor\Bootstrap::createInstance()->initialize(); $this->phpDocumentorPath = $phpDocumentorPath; } /** * Build a list of files (from the fileset elements) * and call the phpDocumentor parser * * @return string */ private function parseFiles() { $parser = $this->app['parser']; $builder = $this->app['descriptor.builder']; $builder->createProjectDescriptor(); $projectDescriptor = $builder->getProjectDescriptor(); $projectDescriptor->setName($this->title); $paths = array(); // filesets foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $dir = $fs->getDir($this->project); $srcFiles = $ds->getIncludedFiles(); foreach ($srcFiles as $file) { $paths[] = $dir . FileSystem::getFileSystem()->getSeparator() . $file; } } $this->project->log("Will parse " . count($paths) . " file(s)", Project::MSG_VERBOSE); $files = new \phpDocumentor\Fileset\Collection(); $files->addFiles($paths); $mapper = new \phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper($this->app['descriptor.cache']); $mapper->garbageCollect($files); $mapper->populate($projectDescriptor); $parser->setPath($files->getProjectRoot()); $parser->setDefaultPackageName($this->defaultPackageName); $parser->parse($builder, $files); $mapper->save($projectDescriptor); return $mapper; } /** * Transforms the parsed files */ private function transformFiles() { $transformer = $this->app['transformer']; $compiler = $this->app['compiler']; $builder = $this->app['descriptor.builder']; $projectDescriptor = $builder->getProjectDescriptor(); $transformer->getTemplates()->load($this->template, $transformer); $transformer->setTarget($this->destDir->getAbsolutePath()); foreach ($compiler as $pass) { $pass->execute($projectDescriptor); } } /** * Runs phpDocumentor 2 */ public function run() { $this->initializePhpDocumentor(); $cache = $this->app['descriptor.cache']; $cache->getOptions()->setCacheDir($this->destDir->getAbsolutePath()); $this->parseFiles(); $this->project->log("Transforming...", Project::MSG_VERBOSE); $this->transformFiles(); } /** * Find the correct php documentor path * * @return null|string */ private function findPhpDocumentorPath() { $phpDocumentorPath = null; $directories = array('phpDocumentor', 'phpdocumentor'); foreach ($directories as $directory) { foreach (Phing::explodeIncludePath() as $path) { $testPhpDocumentorPath = $path . DIRECTORY_SEPARATOR . $directory . DIRECTORY_SEPARATOR . 'src'; if (file_exists($testPhpDocumentorPath)) { $phpDocumentorPath = $testPhpDocumentorPath; } } } return $phpDocumentorPath; } } phing-2.17.4/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php0000644000076500000240000002136214261771713022452 0ustar mrookstaff. */ require_once 'PhpDocumentor/phpDocumentor/Setup.inc.php'; /** * Phing subclass of the phpDocumentor_setup class provided with PhpDocumentor to work around limitations in PhpDocumentor API. * * This class is necessary because phpDocumentor_setup does not expose a complete API for setting configuration options. Because * this class must directly modify some "private" GLOBAL(!) configuration variables, it is liable to break if the PhpDocumentor * internal implementation changes. Obviously this is far from ideal, but there's also no solution given the inflexibility of the * PhpDocumentor design. * * @author Hans Lellelid @author hans * @version $Id: 2aea54f886dd745cddd249499e60c1027886ed4b $ * @package phing.tasks.ext.phpdoc */ class PhingPhpDocumentorSetup extends phpDocumentor_setup { /** * Constructs a new PhingPhpDocumentorSetup. * * @param null $configdir * @param object $task The task we're working with, so we can pass it on to the ErrorTracker * @internal param string $configDir Directory in which to look for configuration files. */ public function __construct($configdir, $task) { global $_phpDocumentor_cvsphpfile_exts, $_phpDocumentor_setting, $_phpDocumentor_phpfile_exts; $this->setup = new Io(); $this->render = new phpDocumentor_IntermediateParser("Default Title"); $GLOBALS['_phpDocumentor_install_dir'] = $configdir; $this->parseIni(); // These redundant-looking lines seem to actually make a difference. // See: http://phing.info/trac/ticket/150 $_phpDocumentor_phpfile_exts = $GLOBALS['_phpDocumentor_phpfile_exts']; $_phpDocumentor_cvsphpfile_exts = $GLOBALS['_phpDocumentor_cvsphpfile_exts']; if (tokenizer_ext) { $this->parse = new phpDocumentorTParser(); } else { $this->parse = new Parser(); } $this->setMemoryLimit(); include_once 'phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php'; // Inject our own error tracker to PhpDocumentor $GLOBALS['phpDocumentor_errors'] = new PhingPhpDocumentorErrorTracker(); $GLOBALS['phpDocumentor_errors']->setTask($task); } /** * Set whether to generate sourcecode for each file parsed. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param bool $b */ public function setGenerateSourcecode($b) { global $_phpDocumentor_setting; $_phpDocumentor_setting['sourcecode'] = (boolean) $b; } /** * Set an array of README/INSTALL/CHANGELOG file paths. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param array $files Absolute paths to files. */ public function setRicFiles($files) { global $_phpDocumentor_RIC_files; $_phpDocumentor_RIC_files = $files; } /** * Set comma-separated list of tags to ignore. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $tags */ public function setIgnoreTags($tags) { global $_phpDocumentor_setting; $ignoretags = explode(',', $tags); $ignoretags = array_map('trim', $ignoretags); $tags = array(); foreach ($ignoretags as $tag) { if (!in_array( $tag, array('@global', '@access', '@package', '@ignore', '@name', '@param', '@return', '@staticvar', '@var') ) ) { $tags[] = $tag; } } $_phpDocumentor_setting['ignoretags'] = $tags; } /** * Set whether to parse dirs as PEAR repos. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param bool $b */ public function setPear($b) { global $_phpDocumentor_setting; $_phpDocumentor_setting['pear'] = (boolean) $b; } /** * Set fullpath to directory to look in for examples. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $dir */ public function setExamplesDir($dir) { global $_phpDocumentor_setting; $_phpDocumentor_setting['examplesdir'] = $dir; } /** * Sets the default package name. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $name */ public function setDefaultPackageName($name) { $GLOBALS['phpDocumentor_DefaultPackageName'] = trim($name); } /** * Sets the default category name. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $name */ public function setDefaultCategoryName($name) { $GLOBALS['phpDocumentor_DefaultCategoryName'] = trim($name); } /** * Enables quiet mode. * * This method exists as a hack because the API exposed for this method in PhpDocumentor * doesn't work correctly. * * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * */ public function setQuietMode() { global $_phpDocumentor_setting; $_phpDocumentor_setting['quiet'] = true; parent::setQuietMode(); } /** * Control whether or not warnings will be shown for undocumented elements. * Useful for identifying classes and methods that haven't yet been * documented. * * @param bool $bEnable */ public function setUndocumentedelements($bEnable) { $this->render->setUndocumentedElementWarningsMode($bEnable); } /** * custom tags, will be recognized and put in tags[] instead of * unknowntags[] * * This method exists as a hack because the API exposed for this method in * PhpDocumentor doesn't work correctly. * * Note that because we are setting a "private" GLOBAL(!!) config var with * this value, this is subject to break if PhpDocumentor internals changes. * * @param string $sCustomtags */ public function setCustomtags($sCustomtags) { global $_phpDocumentor_setting; $_phpDocumentor_setting['customtags'] = $sCustomtags; } /** * Files to ignore * * @param string $sIgnore */ public function setIgnore($sIgnore) { global $_phpDocumentor_setting; $_phpDocumentor_setting['ignore'] = $sIgnore; } } phing-2.17.4/tasks/ext/phpdoc/PhpDocumentorExternalTask.php0000644000076500000240000001671114261771713022773 0ustar mrookstaff. */ require_once 'phing/tasks/ext/phpdoc/PhpDocumentorTask.php'; /** * Task to run phpDocumentor with an external process * * This classes uses the commandline phpdoc script to build documentation. * Use this task instead of the PhpDocumentorTask when you've a clash with the * Smarty libraries. * * @author Michiel Rook * @author Markus Fischer * @version $Id: b72762694ae5d5619ecebf9b66c08bd6ff868821 $ * @package phing.tasks.ext.phpdoc */ class PhpDocumentorExternalTask extends PhpDocumentorTask { /** * The path to the executable for phpDocumentor */ protected $programPath = 'phpdoc'; protected $sourcepath = null; /** * @var bool ignore symlinks to other files or directories */ protected $ignoresymlinks = false; /** * Sets the path to the phpDocumentor executable * @param $programPath */ public function setProgramPath($programPath) { $this->programPath = $programPath; } /** * Returns the path to the phpDocumentor executable */ public function getProgramPath() { return $this->programPath; } /** * Set the source path. A directory or a comma separate list of directories. * @param $sourcepath */ public function setSourcepath($sourcepath) { $this->sourcepath = $sourcepath; } /** * Ignore symlinks to other files or directories. * * @param bool $bSet */ public function setIgnoresymlinks($bSet) { $this->ignoresymlinks = $bSet; } /** * Main entrypoint of the task */ public function main() { $this->validate(); $arguments = join(' ', $this->constructArguments()); $this->log("Running phpDocumentor..."); exec($this->programPath . " " . $arguments, $output, $return); if ($return != 0) { throw new BuildException("Could not execute phpDocumentor: " . implode(' ', $output)); } foreach ($output as $line) { if (strpos($line, 'ERROR') !== false) { $this->log($line, Project::MSG_ERR); continue; } $this->log($line, Project::MSG_VERBOSE); } } /** * Constructs an argument string for phpDocumentor * @return array */ protected function constructArguments() { $aArgs = array(); if ($this->title) { $aArgs[] = '--title "' . $this->title . '"'; } if ($this->destdir) { $aArgs[] = '--target "' . $this->destdir->getAbsolutePath() . '"'; } if ($this->sourcepath) { $aArgs[] = '--directory "' . $this->sourcepath . '"'; } if ($this->output) { $aArgs[] = '--output ' . $this->output; } if ($this->linksource) { $aArgs[] = '--sourcecode on'; } if ($this->parseprivate) { $aArgs[] = '--parseprivate on'; } if ($this->ignore) { $aArgs[] = '--ignore ' . $this->ignore; } // append any files in filesets $filesToParse = array(); foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } if (count($filesToParse) > 0) { $aArgs[] = '--filename "' . join(',', $filesToParse) . '"'; } // append any files in filesets $ricFiles = array(); foreach ($this->projDocFilesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $ricFiles[] = $f->getAbsolutePath(); } } if (count($ricFiles) > 0) { $aArgs[] = '--readmeinstallchangelog "' . join(',', $ricFiles) . '"'; } if ($this->javadocDesc) { $aArgs[] = '--javadocdesc on'; } if ($this->quiet) { $aArgs[] = '--quiet on'; } if ($this->packages) { $aArgs[] = '--packageoutput "' . $this->packages . '"'; } if ($this->ignoreTags) { $aArgs[] = '--ignore-tags "' . $this->ignoreTags . '"'; } if ($this->defaultCategoryName) { $aArgs[] = '--defaultcategoryname "' . $this->defaultCategoryName . '"'; } if ($this->examplesDir) { $aArgs[] = '--examplesdir "' . $this->examplesDir->getAbsolutePath() . '"'; } if ($this->templateBase) { $aArgs[] = '--templatebase "' . $this->templateBase->getAbsolutePath() . '"'; } if ($this->pear) { $aArgs[] = '--pear on'; } if ($this->undocumentedelements) { $aArgs[] = '--undocumentedelements on'; } if ($this->customtags) { $aArgs[] = '--customtags "' . $this->customtags . '"'; } if ($this->ignoresymlinks) { $aArgs[] = '--ignoresymlinks on'; } return $aArgs; } /** * Override PhpDocumentorTask::init() because they're specific to the phpdoc * API which we don't use. */ public function init() { } /** * Validates that necessary minimum options have been set. Based on * PhpDocumentorTask::validate(). */ protected function validate() { if (!$this->destdir) { throw new BuildException("You must specify a destdir for phpdoc.", $this->getLocation()); } if (!$this->output) { throw new BuildException("You must specify an output format for " . "phpdoc (e.g. HTML:frames:default).", $this->getLocation()); } if (empty($this->filesets) && !$this->sourcepath) { throw new BuildException("You have not specified any files to " . "include ( or sourcepath attribute) for phpdoc.", $this->getLocation()); } if ($this->configdir) { $this->log( 'Ignoring unsupported configdir-Attribute', Project::MSG_VERBOSE ); } } } ; phing-2.17.4/tasks/ext/phpdoc/PhpDocumentor2Task.php0000644000076500000240000001111014261771713021336 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * PhpDocumentor2 Task (http://www.phpdoc.org) * Based on the DocBlox Task * * @author Michiel Rook * @version $Id: fff99666d63c88940f9b305c2822856fa00ab5ce $ * @since 2.4.10 * @package phing.tasks.ext.phpdoc */ class PhpDocumentor2Task extends Task { /** * List of filesets * @var FileSet[] */ private $filesets = array(); /** * Destination/target directory * @var PhingFile */ private $destDir = null; /** * name of the template to use * @var string */ private $template = "responsive-twig"; /** * Title of the project * @var string */ private $title = "API Documentation"; /** * Name of default package * @var string */ private $defaultPackageName = "Default"; /** * Path to the phpDocumentor .phar * @var string */ private $pharLocation = ''; /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets destination/target directory * @param PhingFile $destDir */ public function setDestDir(PhingFile $destDir) { $this->destDir = $destDir; } /** * Convenience setter (@see setDestDir) * @param PhingFile $output */ public function setOutput(PhingFile $output) { $this->destDir = $output; } /** * Sets the template to use * @param strings $template */ public function setTemplate($template) { $this->template = (string) $template; } /** * Sets the title of the project * @param strings $title */ public function setTitle($title) { $this->title = (string) $title; } /** * Sets the default package name * @param string $defaultPackageName */ public function setDefaultPackageName($defaultPackageName) { $this->defaultPackageName = (string) $defaultPackageName; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Forces phpDocumentor to be quiet * @deprecated * @param boolean $quiet */ public function setQuiet($quiet) { $this->project->log(__CLASS__ . ": the 'quiet' option has been deprecated", Project::MSG_WARN); } /** * Task entry point * @see Task::main() */ public function main() { if (empty($this->destDir)) { throw new BuildException("You must supply the 'destdir' attribute", $this->getLocation()); } if (empty($this->filesets)) { throw new BuildException("You have not specified any files to include ()", $this->getLocation()); } if (version_compare(PHP_VERSION, '5.3.0') < 0) { throw new BuildException("The phpdocumentor2 task requires PHP 5.3+"); } require_once 'phing/tasks/ext/phpdoc/PhpDocumentor2Wrapper.php'; $wrapper = new PhpDocumentor2Wrapper(); $wrapper->setProject($this->project); $wrapper->setFilesets($this->filesets); $wrapper->setDestDir($this->destDir); $wrapper->setTemplate($this->template); $wrapper->setTitle($this->title); $wrapper->setDefaultPackageName($this->defaultPackageName); $wrapper->setPharLocation($this->pharLocation); $wrapper->run(); } } phing-2.17.4/tasks/ext/phpdoc/PhpDocumentorTask.php0000644000076500000240000003243314261771713021267 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * Task to run PhpDocumentor. * * @author Hans Lellelid * @author Michiel Rook * @version $Id: 11e97cff8a9f2331750049c1c8fe4fb57f3cc962 $ * @package phing.tasks.ext.phpdoc */ class PhpDocumentorTask extends Task { /** * @var string Title for browser window / package index. */ protected $title; /** * @var PhingFile The target directory for output files. */ protected $destdir; /** * @var array FileSet[] Filesets for files to parse. */ protected $filesets = array(); /** * @var array FileSet[] Project documentation (README/INSTALL/CHANGELOG) files. */ protected $projDocFilesets = array(); /** * @var string Package output format. */ protected $output; /** * @var boolean Whether to generate sourcecode for each file parsed. */ protected $linksource = false; /** * @var boolean Whether to parse private members. */ protected $parsePrivate = false; /** * @var boolean Whether to use javadoc descriptions (more primitive). */ protected $javadocDesc = false; /** * @var PhingFile Base directory for locating template files. */ protected $templateBase; /** * @var boolean Wheter to suppress output. */ protected $quiet = false; /** * @var string Comma-separated list of packages to output. */ protected $packages; /** * @var string Comma-separated list of tags to ignore. */ protected $ignoreTags; /** * @var string Default package name. */ protected $defaultPackageName; /** * @var string Default category name. */ protected $defaultCategoryName; /** * @var PhingFile Directory in which to look for examples. */ protected $examplesDir; /** * @var PhingFile Directory in which to look for configuration files. */ protected $configDir; /** * @var boolean Whether to parse as a PEAR repository. */ protected $pear = false; /** * @var boolean Control whether or not warnings will be shown for * undocumented elements. Useful for identifying classes and * methods that haven't yet been documented. */ protected $undocumentedelements = false; /** * @var string custom tags, will be recognized and put in tags[] instead of * unknowntags[]. */ protected $customtags = ''; /** * @var string files to ignore */ protected $ignore = ''; /** * Set the title for the generated documentation * @param $title */ public function setTitle($title) { $this->title = $title; } /** * Set the destination directory for the generated documentation * @param PhingFile $destdir */ public function setDestdir(PhingFile $destdir) { $this->destdir = $destdir; } /** * Alias for {@link setDestdir()}. * @see setDestdir() * @param PhingFile $destdir */ public function setTarget(PhingFile $destdir) { $this->setDestdir($destdir); } /** * Set the output format (e.g. HTML:Smarty:PHP). * @param string $output */ public function setOutput($output) { $this->output = $output; } /** * Set whether to generate sourcecode for each file parsed * @param boolean */ public function setSourcecode($b) { $this->setLinksource($b); } /** * Set whether to generate sourcecode for each file parsed * @param boolean */ public function setLinksource($b) { $this->linksource = $b; } /** * Set whether to suppress output. * @param boolean $b */ public function setQuiet($b) { $this->quiet = $b; } /** * Should private members/classes be documented * @param boolean */ public function setParseprivate($parseprivate) { $this->parsePrivate = $parseprivate; } /** * Whether to use javadoc descriptions (more primitive). * @param boolean */ public function setJavadocdesc($javadoc) { $this->javadocDesc = $javadoc; } /** * Set (comma-separated) list of packages to output. * * @param string $packages */ public function setPackageoutput($packages) { $this->packages = $packages; } /** * Set (comma-separated) list of tags to ignore. * * @param string $tags */ public function setIgnoretags($tags) { $this->ignoreTags = $tags; } /** * Set a directory to search for examples in. * @param PhingFile $d */ public function setExamplesdir(PhingFile $d) { $this->examplesDir = $d; } /** * Set a directory to search for configuration files in. * @param PhingFile $d */ public function setConfigdir(PhingFile $d) { $this->configDir = $d; } /** * Sets the default package name. * @param string $name */ public function setDefaultpackagename($name) { $this->defaultPackageName = $name; } /** * Sets the default category name. * @param string $name */ public function setDefaultcategoryname($name) { $this->defaultCategoryName = $name; } /** * Set whether to parse as PEAR repository. * @param boolean $b */ public function setPear($b) { $this->pear = $b; } /** * Creates a FileSet. * @return FileSet */ public function createFileset() { $num = array_push($this->filesets, new FileSet()); return $this->filesets[$num - 1]; } /** * Creates a readme/install/changelog fileset. * @return FileSet */ public function createProjdocfileset() { $num = array_push($this->projDocFilesets, new FileSet()); return $this->projDocFilesets[$num - 1]; } /** * Control whether or not warnings will be shown for undocumented elements. * Useful for identifying classes and methods that haven't yet been * documented. * @param boolean $b */ public function setUndocumentedelements($b) { $this->undocumentedelements = $b; } /** * custom tags, will be recognized and put in tags[] instead of * unknowntags[]. * * @param string $sCustomtags */ public function setCustomtags($sCustomtags) { $this->customtags = $sCustomtags; } /** * Set base location of all templates for this parse. * * @param PhingFile $oTemplateBase * @internal param PhingFile $destdir */ public function setTemplateBase(PhingFile $oTemplateBase) { $this->templateBase = $oTemplateBase; } /** * Set files to ignore * @param string $sIgnore */ public function setIgnore($sIgnore) { $this->ignore = $sIgnore; } /** * Searches include_path for PhpDocumentor install and adjusts include_path appropriately. * @throws BuildException - if unable to find PhpDocumentor on include_path */ protected function findPhpDocumentorInstall() { $found = null; foreach (Phing::explodeIncludePath() as $path) { $testpath = $path . DIRECTORY_SEPARATOR . 'PhpDocumentor'; if (file_exists($testpath)) { $found = $testpath; break; } } if (!$found) { throw new BuildException("PhpDocumentor task depends on PhpDocumentor being installed and on include_path.", $this->getLocation( )); } // otherwise, adjust the include_path to path to include the PhpDocumentor directory ... set_include_path(get_include_path() . PATH_SEPARATOR . $found); include_once "phpDocumentor/Setup.inc.php"; if (!class_exists('phpDocumentor_setup')) { throw new BuildException("Error including PhpDocumentor setup class file."); } } /** * Main entrypoint of the task * Loads the necessary environment for running PhpDoc, then runs PhpDoc * * @throws BuildException - if the phpdoc classes can't be loaded. */ public function main() { $this->findPhpDocumentorInstall(); include_once 'phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php'; $this->validate(); $configdir = $this->configDir ? $this->configDir->getAbsolutePath() : null; $phpdoc = new PhingPhpDocumentorSetup($configdir, $this); $this->setPhpDocumentorOptions($phpdoc); //$phpdoc->readCommandLineSettings(); $phpdoc->setupConverters($this->output); $phpdoc->createDocs(); } /** * Validates that necessary minimum options have been set. * @throws BuildException if validation doesn't pass */ protected function validate() { if (!$this->destdir) { throw new BuildException("You must specify a destdir for phpdoc.", $this->getLocation()); } if (!$this->output) { throw new BuildException("You must specify an output format for phpdoc (e.g. HTML:frames:default).", $this->getLocation( )); } if (empty($this->filesets)) { throw new BuildException("You have not specified any files to include () for phpdoc.", $this->getLocation( )); } } /** * Sets the options on the passed-in phpdoc setup object. * @param PhingPhpDocumentorSetup $phpdoc */ protected function setPhpDocumentorOptions(PhingPhpDocumentorSetup $phpdoc) { // Title MUST be set first ... (because it re-initializes the internal state of the PhpDocu renderer) if ($this->title) { $phpdoc->setTitle($this->title); } if ($this->parsePrivate) { $phpdoc->setParsePrivate(); } if ($this->javadocDesc) { $phpdoc->setJavadocDesc(); } if ($this->quiet) { $phpdoc->setQuietMode(); } if ($this->destdir) { $phpdoc->setTargetDir($this->destdir->getAbsolutePath()); } if ($this->packages) { $phpdoc->setPackageOutput($this->packages); } if ($this->templateBase) { $phpdoc->setTemplateBase($this->templateBase->getAbsolutePath()); } if ($this->linksource) { $phpdoc->setGenerateSourcecode($this->linksource); } if ($this->examplesDir) { $phpdoc->setExamplesDir($this->examplesDir->getAbsolutePath()); } if ($this->ignoreTags) { $phpdoc->setIgnoreTags($this->ignoreTags); } if ($this->defaultPackageName) { $phpdoc->setDefaultPackageName($this->defaultPackageName); } if ($this->defaultCategoryName) { $phpdoc->setDefaultCategoryName($this->defaultCategoryName); } if ($this->pear) { $phpdoc->setPear($this->pear); } if ($this->ignore) { $phpdoc->setIgnore($this->ignore); } // append any files in filesets $filesToParse = array(); foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } //print_r(implode(",", $filesToParse)); $phpdoc->setFilesToParse(implode(",", $filesToParse)); // append any files in filesets $ricFiles = array(); foreach ($this->projDocFilesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $ricFiles[] = $f->getName(); } } $phpdoc->setRicFiles($ricFiles); if ($this->undocumentedelements) { $phpdoc->setUndocumentedelements($this->undocumentedelements); } if ($this->customtags) { $phpdoc->setCustomtags($this->customtags); } } } phing-2.17.4/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php0000644000076500000240000000667514261771713023771 0ustar mrookstaff. */ require_once 'PhpDocumentor/phpDocumentor/Errors.inc'; /** * Phing subclass of the ErrorTracker class provided with PhpDocumentor to work around limitations in PhpDocumentor API. * * This class is necessary because PhpDocumentor does directly output errors and * warnings occurred during testing for undocumented elements to stdout. * This class is injected globally to force PhpDocumentor to use phing's logging * mechanism. * * Obviously this is far from ideal, but there's also no solution given the inflexibility of the * PhpDocumentor design. * * @author Timo A. Hummel @author felicitus * @version $Id: 33771f28a2886e13a8d3c38864d6758311c3e18d $ * @package phing.tasks.ext.phpdoc */ class PhingPhpDocumentorErrorTracker extends ErrorTracker { /** * @var object Reference to the task we're called with */ private $task; /** * Outputs a warning. This is an almost 1:1 copy from PhpDocumentor, * we're just processing the warning text and send it to phing's logger. * * @param $num integer Number of parameters * @return nothing */ public function addWarning($num) { $a = array('', '', '', ''); if (func_num_args() > 1) { for ($i = 1; $i < func_num_args(); $i++) { $a[$i - 1] = func_get_arg($i); } } $message = sprintf($GLOBALS['phpDocumentor_warning_descrip'][$num], $a[0], $a[1], $a[2], $a[3]); $this->task->log($message, Project::MSG_WARN); } /** * Outputs an error. This is an almost 1:1 copy from PhpDocumentor, * we're just processing the error text and send it to phing's logger. * * @param $num integer Number of parameters * @return nothing */ public function addError($num) { $a = array('', '', '', ''); if (func_num_args() > 1) { for ($i = 1; $i < func_num_args(); $i++) { $a[$i - 1] = func_get_arg($i); } } $message = sprintf($GLOBALS['phpDocumentor_error_descrip'][$num], $a[0], $a[1], $a[2], $a[3]); $this->task->log($message, Project::MSG_ERR); } /** * Sets the task we're working with. This is necessary since we need to be * able to call the method "log". * * @param object $task The task we're working with * @return nothing */ public function setTask($task) { $this->task = $task; } } phing-2.17.4/tasks/ext/phpcpd/PHPCPDFormatterElement.php0000644000076500000240000001024714261771713022031 0ustar mrookstaff. */ require_once 'phing/system/io/PhingFile.php'; /** * A wrapper for the implementations of PHPCPDResultFormatter. * * @package phing.tasks.ext.phpcpd * @author Benjamin Schultz * @version $Id: c430c57cb2db4bff221d0bcf96ed4396b738da6d $ */ class PHPCPDFormatterElement { /** * The report result formatter. * * @var PHPCPDResultFormatter */ protected $formatter = null; /** * The type of the formatter. * * @var string */ protected $type = ''; /** * Whether to use file (or write output to phing log). * * @var boolean */ protected $useFile = true; /** * Output file for formatter. * * @var PhingFile */ protected $outfile = null; /** * The parent task * * @var PHPCPDTask */ private $parentTask; /** * Construct a new PHPCPDFormatterElement with parent task. * * @param PHPCPDTask $parentTask */ public function __construct(PHPCPDTask $parentTask) { $this->parentTask = $parentTask; } /** * Sets the formatter type. * * @param string $type Type of the formatter * * @throws BuildException */ public function setType($type) { $this->type = $type; switch ($this->type) { case 'pmd': if ($this->useFile === false) { throw new BuildException('Formatter "' . $this->type . '" can only print the result to an file'); } include_once 'phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php'; $this->formatter = new PMDPHPCPDResultFormatter(); break; case 'default': include_once 'phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php'; $this->formatter = new DefaultPHPCPDResultFormatter(); break; default: throw new BuildException('Formatter "' . $this->type . '" not implemented'); } } /** * Get the formatter type * * @return string */ public function getType() { return $this->type; } /** * Set whether to write formatter results to file or not. * * @param boolean $useFile True or false. */ public function setUseFile($useFile) { $this->useFile = StringHelper::booleanValue($useFile); } /** * Return whether to write formatter results to file or not. * * @return boolean */ public function getUseFile() { return $this->useFile; } /** * Sets the output file for the formatter results. * * @param PhingFile $outfile The output file */ public function setOutfile(PhingFile $outfile) { $this->outfile = $outfile; } /** * Get the output file. * * @return PhingFile */ public function getOutfile() { return $this->outfile; } /** * Returns the report formatter. * * @return PHPCPDResultFormatter */ public function getFormatter() { return $this->formatter; } } phing-2.17.4/tasks/ext/phpcpd/PHPCPDTask.php0000644000076500000240000002324714261771713017462 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php'; /** * Runs PHP Copy & Paste Detector. Checking PHP files for duplicated code. * Refactored original PhpCpdTask provided by * Timo Haberkern * * @package phing.tasks.ext.phpcpd * @author Benjamin Schultz * @version $Id: 99ac61885f274b13a79c125b92a133b65db3b726 $ */ class PHPCPDTask extends Task { /** * A php source code filename or directory * * @var PhingFile */ protected $file = null; /** * All fileset objects assigned to this task * * @var FileSet[] */ protected $filesets = array(); /** * Minimum number of identical lines. * * @var integer */ protected $minLines = 5; /** * Minimum number of identical tokens. * * @var integer */ protected $minTokens = 70; /** * Allow for fuzzy matches. * * @var boolean */ protected $fuzzy = false; /** * List of valid file extensions for analyzed files. * * @var array */ protected $allowedFileExtensions = array('php'); /** * List of exclude directory patterns. * * @var array */ protected $ignorePatterns = array('.git', '.svn', 'CVS', '.bzr', '.hg'); /** * The format for the report * * @var string */ protected $format = 'default'; /** * Formatter elements. * * @var PHPCPDFormatterElement[] */ protected $formatters = array(); /** * @var bool */ protected $oldVersion = false; /** * @var string */ private $pharLocation = ""; /** * Set the input source file or directory. * * @param PhingFile $file The input source file or directory. */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Nested creator, adds a set of files (nested fileset attribute). * * @param FileSet $fs List of files to scan */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets the minimum number of identical lines (default: 5). * * @param integer $minLines Minimum number of identical lines */ public function setMinLines($minLines) { $this->minLines = $minLines; } /** * Sets the minimum number of identical tokens (default: 70). * * @param integer $minTokens Minimum number of identical tokens */ public function setMinTokens($minTokens) { $this->minTokens = $minTokens; } /** * Sets the fuzzy match (default: false). * * @param boolean $fuzzy fuzzy match */ public function setFuzzy($fuzzy) { $this->fuzzy = $fuzzy; } /** * Sets a list of filename extensions for valid php source code files. * * @param string $fileExtensions List of valid file extensions. */ public function setAllowedFileExtensions($fileExtensions) { $this->allowedFileExtensions = array(); $token = ' ,;'; $ext = strtok($fileExtensions, $token); while ($ext !== false) { $this->allowedFileExtensions[] = $ext; $ext = strtok($token); } } /** * Sets a list of ignore patterns that is used to exclude directories from the source analysis. * * @param string $ignorePatterns List of ignore patterns. */ public function setIgnorePatterns($ignorePatterns) { $this->ignorePatterns = array(); $token = ' ,;'; $pattern = strtok($ignorePatterns, $token); while ($pattern !== false) { $this->ignorePatterns[] = $pattern; $pattern = strtok($token); } } /** * Sets the output format * * @param string $format Format of the report */ public function setFormat($format) { $this->format = $format; } /** * Create object for nested formatter element. * * @return PHPCPDFormatterElement */ public function createFormatter() { $num = array_push($this->formatters, new PHPCPDFormatterElement($this)); return $this->formatters[$num - 1]; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * @throws BuildException if the phpcpd classes can't be loaded */ private function loadDependencies() { if (!empty($this->pharLocation)) { // hack to prevent PHPCPD from starting in CLI mode and halting Phing eval("namespace SebastianBergmann\PHPCPD\CLI; class Application { public function run() {} }"); ob_start(); include $this->pharLocation; ob_end_clean(); if (class_exists('\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy')) { return; } } if (class_exists('Composer\\Autoload\\ClassLoader', false) && class_exists( '\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy' ) ) { return; } if ($handler = @fopen('SebastianBergmann/PHPCPD/autoload.php', 'r', true)) { fclose($handler); @include_once 'SebastianBergmann/PHPCPD/autoload.php'; if (version_compare(PHP_VERSION, '5.3.0') < 0) { throw new BuildException('The PHPCPD task now requires PHP 5.3+'); } return; } if ($handler = @fopen('PHPCPD/Autoload.php', 'r', true)) { fclose($handler); @include_once 'PHPCPD/Autoload.php'; $this->oldVersion = true; return; } throw new BuildException( 'PHPCPDTask depends on PHPCPD being installed and on include_path.', $this->getLocation() ); } /** * Executes PHPCPD against PhingFile or a FileSet * * @throws BuildException */ public function main() { $this->loadDependencies(); if (!isset($this->file) && count($this->filesets) == 0) { throw new BuildException('Missing either a nested fileset or attribute "file" set'); } if (count($this->formatters) == 0) { // turn legacy format attribute into formatter $fmt = new PHPCPDFormatterElement($this); $fmt->setType($this->format); $fmt->setUseFile(false); $this->formatters[] = $fmt; } $this->validateFormatters(); $filesToParse = array(); if ($this->file instanceof PhingFile) { $filesToParse[] = $this->file->getPath(); } else { // append any files in filesets foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } } $this->log('Processing files...'); if ($this->oldVersion) { $detectorClass = 'PHPCPD_Detector'; $strategyClass = 'PHPCPD_Detector_Strategy_Default'; } else { $detectorClass = '\\SebastianBergmann\\PHPCPD\\Detector\\Detector'; $strategyClass = '\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy'; } $detector = new $detectorClass(new $strategyClass()); $clones = $detector->copyPasteDetection( $filesToParse, $this->minLines, $this->minTokens, $this->fuzzy ); $this->log('Finished copy/paste detection'); foreach ($this->formatters as $fe) { $formatter = $fe->getFormatter(); $formatter->processClones( $clones, $this->project, $fe->getUseFile(), $fe->getOutfile() ); } } /** * Validates the available formatters * * @throws BuildException */ protected function validateFormatters() { foreach ($this->formatters as $fe) { if ($fe->getType() == '') { throw new BuildException('Formatter missing required "type" attribute.'); } if ($fe->getUsefile() && $fe->getOutfile() === null) { throw new BuildException('Formatter requires "outfile" attribute when "useFile" is true.'); } } } } phing-2.17.4/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php0000644000076500000240000000602314261771713025223 0ustar mrookstaff. */ require_once 'phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php'; /** * Prints plain text output of phpcpd run * * @package phing.tasks.ext.phpcpd.formatter * @author Benjamin Schultz * @version $Id: 20db9b04d2f5ea6acc7db0f00d83daa6b8580cec $ */ class DefaultPHPCPDResultFormatter extends PHPCPDResultFormatter { /** * Processes a list of clones. * * @param CodeCloneMap $clones * @param Project $project * @param boolean $useFile * @param PhingFile|null $outFile */ public function processClones($clones, Project $project, $useFile = false, $outFile = null) { if (get_class($clones) == 'SebastianBergmann\PHPCPD\CodeCloneMap') { if (class_exists('SebastianBergmann\PHPCPD\Log\Text')) { $this->processClonesNew($clones, $useFile, $outFile); return; } $logger = new \SebastianBergmann\PHPCPD\TextUI\ResultPrinter(); } else { $logger = new PHPCPD_TextUI_ResultPrinter(); } // default format goes to logs, no buffering ob_start(); $logger->printResult($clones, $project->getBaseDir(), true); $output = ob_get_contents(); ob_end_clean(); if (!$useFile || empty($outFile)) { echo $output; } else { file_put_contents($outFile->getPath(), $output); } } /** * Wrapper for PHPCPD 2.0 * * @param CodeCloneMap $clones * @param boolean $useFile * @param PhingFile|null $outFile */ private function processClonesNew($clones, $useFile = false, $outFile = null) { if ($useFile) { $resource = fopen($outFile->getPath(), "w"); } else { $resource = fopen("php://output", "w"); } $output = new \Symfony\Component\Console\Output\StreamOutput($resource); $logger = new \SebastianBergmann\PHPCPD\Log\Text(); $logger->printResult($output, $clones); } } phing-2.17.4/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php0000644000076500000240000000402314261771713024255 0ustar mrookstaff. */ require_once 'phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php'; /** * Prints PMD-XML output of phpcpd run * * @author Benjamin Schultz * * @package phing.tasks.ext.phpcpd.formatter */ class PMDPHPCPDResultFormatter extends PHPCPDResultFormatter { /** * Processes a list of clones. * * @param PHPCPD_CloneMap|CodeCloneMap $clones * @param Project $project * @param boolean $useFile * @param PhingFile|null $outFile * * @throws BuildException */ public function processClones($clones, Project $project, $useFile = false, $outFile = null) { if (!$useFile || empty($outFile)) { throw new BuildException('Output filename required for this formatter'); } if (get_class($clones) == 'PHPCPD_CloneMap') { $logger = new PHPCPD_Log_XML_PMD($outFile); } else { $logger = new \SebastianBergmann\PHPCPD\Log\PMD($outFile); } $logger->processClones($clones); } } phing-2.17.4/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php0000644000076500000240000000314314261771713023716 0ustar mrookstaff. */ /** * This abstract class describes classes that format the results of a PHPCPD run. * * @package phing.tasks.ext.phpcpd.formatter * @author Benjamin Schultz * @version $Id: e8921b5a15fd23ce437471250c7161884560e202 $ */ abstract class PHPCPDResultFormatter { /** * Processes a list of clones. * * @param object $clones * @param Project $project * @param boolean $useFile * @param PhingFile|null $outFile */ abstract public function processClones($clones, Project $project, $useFile = false, $outFile = null); } phing-2.17.4/tasks/ext/inifile/IniFileRemove.php0000644000076500000240000000304514261771713020511 0ustar mrookstaff * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * Class for collecting details for removing keys or sections from an ini file * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ class IniFileRemove { /** * Property * * @var string */ protected $property = null; /** * Section * * @var string */ protected $section = null; /** * Set Section name * * @param string $section Name of section in ini file * * @return void */ public function setSection($section) { $this->section = $section; } /** * Set Property/Key name * * @param string $property ini key name * * @return void */ public function setProperty($property) { $this->property = $property; } /** * Get Property * * @return string */ public function getProperty() { return $this->property; } /** * Get Section * * @return string */ public function getSection() { return $this->section; } } phing-2.17.4/tasks/ext/inifile/IniFileSet.php0000644000076500000240000000447114261771713020013 0ustar mrookstaff * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * InifileSet * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link InifileSet.php */ class IniFileSet { /** * Property * * @var string */ protected $property = null; /** * Section * * @var string */ protected $section = null; /** * Value * * @var mixed */ protected $value = null; /** * Operation * * @var mixed */ protected $operation = null; /** * Set Operation * * @param string $operation +/- * * @return void */ public function setOperation($operation) { $this->operation = $operation; } /** * Get Operation * * @return void */ public function getOperation() { return $this->operation; } /** * Set Section name * * @param string $section Name of section in ini file * * @return void */ public function setSection($section) { $this->section = trim($section); } /** * Set Property * * @param string $property property/key name * * @return void */ public function setProperty($property) { $this->property = $property; } /** * Set Value * * @param string $value Value to set for key in ini file * * @return void */ public function setValue($value) { $this->value = $value; } /** * Get Property * * @return string */ public function getProperty() { return $this->property; } /** * Get Value * * @return string */ public function getValue() { return $this->value; } /** * Get Section * * @return string */ public function getSection() { return $this->section; } } phing-2.17.4/tasks/ext/inifile/IniFileConfig.php0000644000076500000240000001165314261771713020465 0ustar mrookstaff * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * Class for reading/writing ini config file * * This preserves comments etc, unlike parse_ini_file and is based heavily on * a solution provided at: * stackoverflow.com/questions/9594238/good-php-classes-that-manipulate-ini-files * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ class IniFileConfig { /** * Lines of ini file * * @var array */ protected $lines = array(); /** * Read ini file * * @param string $file filename * * @return void */ public function read($file) { $this->lines = array(); $section = ''; foreach (file($file) as $line) { if (preg_match('/^\s*(;.*)?$/', $line)) { // comment or whitespace $this->lines[] = array( 'type' => 'comment', 'data' => $line, 'section' => $section ); } elseif (preg_match('/^\s?\[(.*)\]/', $line, $match)) { // section $section = $match[1]; $this->lines[] = array( 'type' => 'section', 'data' => $line, 'section' => $section ); } elseif (preg_match('/^\s*(.*?)\s*=\s*(.*?)\s*$/', $line, $match)) { // entry $this->lines[] = array( 'type' => 'entry', 'data' => $line, 'section' => $section, 'key' => $match[1], 'value' => $match[2] ); } } } /** * Get value of given key in specified section * * @param string $section Section * @param string $key Key * * @return void */ public function get($section, $key) { foreach ($this->lines as $line) { if ($line['type'] != 'entry') { continue; } if ($line['section'] != $section) { continue; } if ($line['key'] != $key) { continue; } return $line['value']; } throw new RuntimeException('Missing Section or Key'); } /** * Set key to value in specified section * * @param string $section Section * @param string $key Key * @param string $value Value * * @return void */ public function set($section, $key, $value) { foreach ($this->lines as &$line) { if ($line['type'] != 'entry') { continue; } if ($line['section'] != $section) { continue; } if ($line['key'] != $key) { continue; } $line['value'] = $value; $line['data'] = $key . " = " . $value . PHP_EOL; return; } throw new RuntimeException('Missing Section or Key'); } /** * Remove key/section from file. * * If key is not specified, then the entire section will be removed. * * @param string $section Section to manipulate/remove * @param string $key Name of key to remove, might be null/empty * * @return void */ public function remove($section, $key) { if ($section == '') { throw new RuntimeException("Section not set."); } if (is_null($key) || ($key == '')) { // remove entire section foreach ($this->lines as $linenum => $line) { if ($line['section'] == $section) { unset($this->lines[$linenum]); } } } else { foreach ($this->lines as $linenum => $line) { if (($line['section'] == $section) && (isset($line['key'])) && ($line['key'] == $key) ) { unset($this->lines[$linenum]); } } } } /** * Write contents out to file * * @param string $file filename * * @return void */ public function write($file) { if (file_exists($file) && !is_writable($file)) { throw new RuntimeException("$file is not writable"); } $fp = fopen($file, 'w'); foreach ($this->lines as $line) { fwrite($fp, $line['data']); } fclose($fp); } } phing-2.17.4/tasks/ext/inifile/IniFileTask.php0000644000076500000240000002222514261771713020157 0ustar mrookstaff * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ require_once 'IniFileSet.php'; require_once 'IniFileRemove.php'; require_once 'IniFileConfig.php'; /** * InifileTask * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link InifileTask.php */ class InifileTask extends Task { /** * Source file * * @var string|null */ protected $source = null; /** * Dest file * * @var string|null */ protected $dest = null; /** * Whether to halt phing on error. * * @var bool */ protected $haltonerror = false; /** * Sets * * @var array */ protected $sets = array(); /** * Removals * * @var array */ protected $removals = array(); /** * IniFileConfig instance * * @var IniFileConfig */ protected $ini = null; /** * Taskname for logger * @var string */ protected $taskName = 'IniFile'; /** * Check file to be read from * * @param string $readFile Filename * * @return void */ public function checkReadFile($readFile) { if (is_null($readFile)) { return false; } if (!file_exists($readFile)) { $msg = "$readFile does not exist."; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } if (!is_readable($readFile)) { $msg = "$readFile is not readable."; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } $this->ini->read($readFile); $this->log("Read from $readFile"); return true; } /** * Check file to write to * * @param string $writeFile Filename * * @return void */ public function checkWriteFile($writeFile) { if (file_exists($writeFile) && !is_writable($writeFile)) { $msg = "$writeFile is not writable"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } return true; } /** * The main entry point method. * * @return void */ public function main() { $this->ini = new IniFileConfig(); $readFile = null; $writeFile = null; if (!is_null($this->source) && is_null($this->dest)) { $readFile = $this->source; } elseif (!is_null($this->dest) && is_null($this->source)) { $readFile = $this->dest; } else { $readFile = $this->source; } if (!is_null($this->dest)) { $writeFile = $this->dest; } elseif (!is_null($this->source)) { $writeFile = $this->source; } else { $writeFile = $this->dest; } if ($readFile === null && $writeFile === null) { $msg = "Neither source nor dest is set"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return; } if (!$this->checkReadFile($readFile)) { return; } if (!$this->checkWriteFile($writeFile)) { return; } $this->enumerateSets(); $this->enumerateRemoves(); try { $this->ini->write($writeFile); $this->log("Wrote to $writeFile"); } catch (Exception $ex) { $msg = $ex->getMessage(); if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); } } /** * Work through all Set commands. * * @return void */ public function enumerateSets() { foreach ($this->sets as $set) { $value = $set->getValue(); $key = $set->getProperty(); $section = $set->getSection(); $operation = $set->getOperation(); if ($value !== null) { try { $this->ini->set($section, $key, $value); $this->log( "[$section] $key set to $value", Project::MSG_DEBUG ); } catch (Exception $ex) { $this->log( "Error setting value for section '" . $section . "', key '" . $key ."'" ); $this->log($ex->getMessage(), Project::MSG_DEBUG); } } elseif ($operation !== null) { $v = $this->ini->get($section, $key); // value might be wrapped in quotes with a semicolon at the end if (!is_numeric($v)) { if (preg_match('/^"(\d*)";?$/', $v, $match)) { $v = $match[1]; } elseif (preg_match("/^'(\d*)';?$/", $v, $match)) { $v = $match[1]; } else { $this->log( "Value $v is not numeric. Skipping $operation operation." ); continue; } } if ($operation == '+') { ++$v; } elseif ($operation == '-') { --$v; } else { if (($operation != '-') && ($operation != '+')) { $msg = "Unrecognised operation $operation"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); } } try { $this->ini->set($section, $key, $v); $this->log( "[$section] $key set to $v", Project::MSG_DEBUG ); } catch (Exception $ex) { $this->log( "Error setting value for section '" . $section . "', key '" . $key ."'" ); $this->log($ex->getMessage(), Project::MSG_DEBUG); } } else { $this->log( "Set: value and operation are both not set", Project::MSG_ERR ); } } } /** * Work through all Remove commands. * * @return void */ public function enumerateRemoves() { foreach ($this->removals as $remove) { $key = $remove->getProperty(); $section = $remove->getSection(); if ($section == '') { $this->log( "Remove: section must be set", Project::MSG_ERR ); continue; } $this->ini->remove($section, $key); if (($section != '') && ($key != '')) { $this->log( "$key in section [$section] has been removed.", Project::MSG_DEBUG ); } elseif (($section != '') && ($key == '')) { $this->log("[$section] has been removed.", Project::MSG_DEBUG); } } } /** * Set Source property * * @param string $source Name of originating ini file to parse * * @return void */ public function setSource($source) { $this->source = $source; } /** * Set Dest property * * @param string $dest Destination filename to write ini contents to. * * @return void */ public function setDest($dest) { $this->dest = $dest; } /** * Set haltonerror attribute. * * @param string $halt 'yes', or '1' to halt. * * @return void */ public function setHaltonerror($halt) { $doHalt = false; if (strtolower($halt) == 'yes' || $halt == 1) { $doHalt = true; } $this->haltonerror = $doHalt; } /** * Create a Set method * * @return IniFileSet */ public function createSet() { $set = new IniFileSet(); $this->sets[] = $set; return $set; } /** * Create a Remove method * * @return IniFileRemove */ public function createRemove() { $remove = new IniFileRemove(); $this->removals[] = $remove; return $remove; } } phing-2.17.4/tasks/ext/WikiPublishTask.php0000644000076500000240000002444414261771713017460 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * Publish Wiki document using Wiki API. * * @author Piotr Lewandowski * @package phing.tasks.ext */ class WikiPublishTask extends Task { /** * Wiki API url * * @var string */ private $apiUrl; /** * Wiki API user name * * @var string */ private $apiUser; /** * Wiki API password * * @var string */ private $apiPassword; /** * Wiki document Id. Document can be identified by title instead. * * @var int */ private $id; /** * Wiki document title * * @var string */ private $title; /** * Wiki document content * * @var string */ private $content; /** * Publishing mode (append, prepend, overwrite). * * @var string */ private $mode = 'append'; /** * Publish modes map * @var array */ private $modeMap = array( 'overwrite' => 'text', 'append' => 'appendtext', 'prepend' => 'prependtext', ); /** * Curl handler * * @var resource */ private $curl; /** * Wiki api edit token * * @var string */ private $apiEditToken; /** * Temporary cookies file * * @var string */ private $cookiesFile; /** * @param string $apiPassword */ public function setApiPassword($apiPassword) { $this->apiPassword = $apiPassword; } /** * @return string */ public function getApiPassword() { return $this->apiPassword; } /** * @param string $apiUrl */ public function setApiUrl($apiUrl) { $this->apiUrl = $apiUrl; } /** * @return string */ public function getApiUrl() { return $this->apiUrl; } /** * @param string $apiUser */ public function setApiUser($apiUser) { $this->apiUser = $apiUser; } /** * @return string */ public function getApiUser() { return $this->apiUser; } /** * @param int $id */ public function setId($id) { $this->id = $id; } /** * @return int */ public function getId() { return $this->id; } /** * @param string $mode * @throws BuildException */ public function setMode($mode) { if (false === isset($this->modeMap[$mode])) { throw new BuildException('Mode is invalid (' . $mode . ', should be one of ' . implode( ',', array_keys($this->modeMap) ) . ')'); } $this->mode = $mode; } /** * @return string */ public function getMode() { return $this->mode; } /** * @param string $title */ public function setTitle($title) { $this->title = $title; } /** * @return string */ public function getTitle() { return $this->title; } /** * @param string $content */ public function setContent($content) { $this->content = $content; } /** * @return string */ public function getContent() { return $this->content; } /** * Prepare CURL object * * @throws BuildException */ public function init() { $this->cookiesFile = tempnam(sys_get_temp_dir(), 'WikiPublish.' . uniqid() . '.cookies'); $this->curl = curl_init(); if (false === is_resource($this->curl)) { throw new BuildException('Curl init failed (' . $this->apiUrl . ')'); } curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookiesFile); curl_setopt($this->curl, CURLOPT_COOKIEFILE, $this->cookiesFile); } /** * The main entry point method */ public function main() { $this->validateAttributes(); $this->callApiLogin(); $this->callApiEdit(); } /** * Close curl connection and clean up */ public function __destruct() { if (null !== $this->curl && is_resource($this->curl)) { curl_close($this->curl); } if (null !== $this->cookiesFile && file_exists($this->cookiesFile)) { unlink($this->cookiesFile); } } /** * Validates attributes coming in from XML * * @throws BuildException */ private function validateAttributes() { if (null === $this->apiUrl) { throw new BuildException('Wiki apiUrl is required'); } if (null === $this->id && null === $this->title) { throw new BuildException('Wiki page id or title is required'); } } /** * Call Wiki webapi login action * * @param string|null $token * * @throws BuildException */ private function callApiLogin($token = null) { $postData = array('lgname' => $this->apiUser, 'lgpassword' => $this->apiPassword); if (null !== $token) { $postData['lgtoken'] = $token; } $result = $this->callApi('action=login', $postData); try { $this->checkApiResponseResult('login', $result); } catch (BuildException $e) { if (null !== $token) { throw $e; } // if token is required then call login again with token $this->checkApiResponseResult('login', $result, 'NeedToken'); if (isset($result['login']) && isset($result['login']['token'])) { $this->callApiLogin($result['login']['token']); } else { throw $e; } } } /** * Call Wiki webapi edit action */ private function callApiEdit() { $this->callApiTokens(); $result = $this->callApi('action=edit&token=' . urlencode($this->apiEditToken), $this->getApiEditData()); $this->checkApiResponseResult('edit', $result); } /** * Return prepared data for Wiki webapi edit action * * @return array */ private function getApiEditData() { $result = array( 'minor' => '', ); if (null !== $this->title) { $result['title'] = $this->title; } if (null !== $this->id) { $result['pageid'] = $this->id; } $result[$this->modeMap[$this->mode]] = $this->content; return $result; } /** * Call Wiki webapi tokens action * * @throws BuildException */ private function callApiTokens() { $result = $this->callApi('action=tokens&type=edit'); if (false == isset($result['tokens']) || false == isset($result['tokens']['edittoken'])) { throw new BuildException('Wiki token not found'); } $this->apiEditToken = $result['tokens']['edittoken']; } /** * Call Wiki webapi * * @param string $queryString * @param array|null $postData * * @return array * @throws BuildException */ protected function callApi($queryString, $postData = null) { $this->setPostData($postData); $url = $this->apiUrl . '?' . $queryString . '&format=php'; curl_setopt($this->curl, CURLOPT_URL, $url); $response = curl_exec($this->curl); $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); if (200 !== $responseCode) { throw new BuildException('Wiki webapi call failed (http response ' . $responseCode . ')'); } $result = @unserialize($response); if (false === $result) { throw new BuildException('Couldn\'t unserialize Wiki webapi response'); } return $result; } /** * Set POST data for curl call * * @param array|null $data */ private function setPostData($data = null) { if (null === $data) { curl_setopt($this->curl, CURLOPT_POST, false); return; } $postData = ''; foreach ($data as $key => $value) { $postData .= urlencode($key) . '=' . urlencode($value) . '&'; } if ($postData != '') { curl_setopt($this->curl, CURLOPT_POST, true); curl_setopt($this->curl, CURLOPT_POSTFIELDS, substr($postData, 0, -1)); } } /** * Validate Wiki webapi response * * @param string $action * @param array $response * @param string $expect * * @throws BuildException */ private function checkApiResponseResult($action, $response, $expect = 'Success') { if (isset($response['error'])) { throw new BuildException( 'Wiki response error (action: ' . $action . ', error code: ' . $response['error']['code'] . ')'); } if (false == isset($response[$action]) || false == isset($response[$action]['result'])) { throw new BuildException('Wiki response result not found (action: ' . $action . ')'); } if ($response[$action]['result'] !== $expect) { throw new BuildException( 'Unexpected Wiki response result ' . $response[$action]['result'] . ' (expected: ' . $expect . ')'); } } } phing-2.17.4/tasks/ext/JslLintTask.php0000644000076500000240000002547314261771713016610 0ustar mrookstaff. */ require_once 'phing/Task.php'; require_once 'phing/util/DataStore.php'; /** * A Javascript lint task. Checks syntax of Javascript files. * Javascript lint (http://www.javascriptlint.com) must be in the system path. * This class is based on Knut Urdalen's PhpLintTask. * * @author Stefan Priebsch * * @package phing.tasks.ext */ class JslLintTask extends Task { /** @var PhingFile */ protected $file; // the source file (from xml attribute) /** @var array */ protected $filesets = array(); // all fileset objects assigned to this task /** @var bool $showWarnings */ protected $showWarnings = true; /** @var bool */ protected $haltOnFailure = false; /** * @var bool */ protected $haltOnWarning = false; /** * @var bool */ protected $hasErrors = false; /** * @var bool */ protected $hasWarnings = false; /** @var array $badFiles */ private $badFiles = array(); /** @var DataStore */ private $cache = null; /** @var PhingFile */ private $conf = null; /** @var string */ private $executable = "jsl"; /** @var PhingFile */ protected $tofile = null; /** * Sets the flag if warnings should be shown * * @param boolean $show */ public function setShowWarnings($show) { $this->showWarnings = StringHelper::booleanValue($show); } /** * The haltonfailure property * * @param boolean $aValue */ public function setHaltOnFailure($aValue) { $this->haltOnFailure = $aValue; } /** * The haltonwarning property * * @param boolean $aValue */ public function setHaltOnWarning($aValue) { $this->haltOnWarning = $aValue; } /** * File to be performed syntax check on * * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Whether to store last-modified times in cache * * @param PhingFile $file */ public function setCacheFile(PhingFile $file) { $this->cache = new DataStore($file); } /** * jsl config file * * @param PhingFile $file */ public function setConfFile(PhingFile $file) { $this->conf = $file; } /** * @param string $path * * @throws BuildException */ public function setExecutable($path) { $this->executable = $path; if (!@file_exists($path)) { throw new BuildException("JavaScript Lint executable '{$path}' not found"); } } /** * @return string */ public function getExecutable() { return $this->executable; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * File to save error messages to * * @param PhingFile $tofile */ public function setToFile(PhingFile $tofile) { $this->tofile = $tofile; } /** * Execute lint check against PhingFile or a FileSet */ public function main() { if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } if (empty($this->executable)) { throw new BuildException("Missing the 'executable' attribute"); } if ($this->file instanceof PhingFile) { $this->lint($this->file->getPath()); } else { // process filesets $project = $this->getProject(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($project); $files = $ds->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath(); foreach ($files as $file) { $this->lint($dir . DIRECTORY_SEPARATOR . $file); } } } // write list of 'bad files' to file (if specified) if ($this->tofile) { $writer = new FileWriter($this->tofile); foreach ($this->badFiles as $file => $messages) { foreach ($messages as $msg) { $writer->write($file . "=" . $msg . PHP_EOL); } } $writer->close(); } if ($this->haltOnFailure && $this->hasErrors) { throw new BuildException('Syntax error(s) in JS files:' . implode( ', ', array_keys($this->badFiles) )); } if ($this->haltOnWarning && $this->hasWarnings) { throw new BuildException('Syntax warning(s) in JS files:' . implode( ', ', array_keys($this->badFiles) )); } } /** * Performs the actual syntax check * * @param string $file * * @throws BuildException * * @return bool|void */ protected function lint($file) { $command = $this->executable . ' -output-format ' . escapeshellarg( 'file:__FILE__;line:__LINE__;message:__ERROR__' ) . ' '; if (isset($this->conf)) { $command .= '-conf ' . escapeshellarg($this->conf->getPath()) . ' '; } $command .= '-process '; if (file_exists($file)) { if (is_readable($file)) { if ($this->cache) { $lastmtime = $this->cache->get($file); if ($lastmtime >= filemtime($file)) { $this->log("Not linting '" . $file . "' due to cache", Project::MSG_DEBUG); return false; } } $messages = array(); exec($command . '"' . $file . '"', $messages, $return); if ($return > 100) { throw new BuildException("Could not execute Javascript Lint executable '{$this->executable}'"); } $summary = $messages[sizeof($messages) - 1]; preg_match('/(\d+)\serror/', $summary, $matches); $errorCount = (count($matches) > 1 ? $matches[1] : 0); preg_match('/(\d+)\swarning/', $summary, $matches); $warningCount = (count($matches) > 1 ? $matches[1] : 0); $errors = array(); $warnings = array(); if ($errorCount > 0 || $warningCount > 0) { $last = false; foreach ($messages as $message) { $matches = array(); if (preg_match('/^(\.*)\^$/', $message)) { $column = strlen($message); if ($last == 'error') { $errors[count($errors) - 1]['column'] = $column; } else { if ($last == 'warning') { $warnings[count($warnings) - 1]['column'] = $column; } } $last = false; } if (!preg_match('/^file:(.+);line:(\d+);message:(.+)$/', $message, $matches)) { continue; } $msg = $matches[3]; $data = array('filename' => $matches[1], 'line' => $matches[2], 'message' => $msg); if (preg_match('/^.*error:.+$/i', $msg)) { $errors[] = $data; $last = 'error'; } else { if (preg_match('/^.*warning:.+$/i', $msg)) { $warnings[] = $data; $last = 'warning'; } } } } if ($this->showWarnings && $warningCount > 0) { $this->log($file . ': ' . $warningCount . ' warnings detected', Project::MSG_WARN); foreach ($warnings as $warning) { $this->log( '- line ' . $warning['line'] . (isset($warning['column']) ? ' column ' . $warning['column'] : '') . ': ' . $warning['message'], Project::MSG_WARN ); } $this->hasWarnings = true; } if ($errorCount > 0) { $this->log($file . ': ' . $errorCount . ' errors detected', Project::MSG_ERR); if (!isset($this->badFiles[$file])) { $this->badFiles[$file] = array(); } foreach ($errors as $error) { $message = 'line ' . $error['line'] . (isset($error['column']) ? ' column ' . $error['column'] : '') . ': ' . $error['message']; $this->log('- ' . $message, Project::MSG_ERR); array_push($this->badFiles[$file], $message); } $this->hasErrors = true; } else { if (!$this->showWarnings || $warningCount == 0) { $this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE); if ($this->cache) { $this->cache->put($file, filemtime($file)); } } } } else { throw new BuildException('Permission denied: ' . $file); } } else { throw new BuildException('File not found: ' . $file); } } } phing-2.17.4/tasks/ext/pearpackage/Fileset.php0000644000076500000240000001676714261771713020252 0ustar mrookstaff. */ include_once 'phing/system/io/PhingFile.php'; /** * Builds list of files for PEAR_PackageFileManager using a Phing FileSet. * * Some code here is taken from PEAR_PackageFileManager_File -- getting results from flat * array into the assoc array expected from getFileList(). * * @author Greg Beaver * @author Hans Lellelid * @package phing.tasks.ext.pearpackage * @version $Id: 4287f56d47c2d793bc22417402f8c37daf3745f3 $ */ class PEAR_PackageFileManager_Fileset { /** * Current Phing Project. * @var Project */ private $project; /** * FileSets to use. * @var array FileSet[] */ private $filesets = array(); /** * Set up the FileSet filelist generator * * 'project' and 'filesets' are the only options that this class uses. * * @param PEAR_PackageFileManager * @param array */ public function __construct($options) { if (!is_array($options)) { $options = $options->getOptions(); } $this->project = $options['phing_project']; $this->filesets = $options['phing_filesets']; } /** * Generate the section * of the package file. * * This function performs the backend generation of the array * containing all files in this package * @return array structure of all files to include */ public function getFileList() { $allfiles = array(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $files = $ds->getIncludedFiles(); // We need to store these files keyed by the basedir from DirectoryScanner // so that we can resolve the fullpath of the file later. if (isset($allfiles[$ds->getBasedir()])) { $allfiles[$ds->getBasedir()] = array_merge($allfiles[$ds->getBasedir()], $files); } else { $allfiles[$ds->getBasedir()] = $files; } } $struc = array(); foreach ($allfiles as $basedir => $files) { foreach ($files as $file) { // paths are relative to $basedir above $path = strtr(dirname($file), DIRECTORY_SEPARATOR, '/'); if (!$path || $path == '.') { $path = '/'; // for array index } $parts = explode('.', basename($file)); $ext = array_pop($parts); if (strlen($ext) == strlen($file)) { $ext = ''; } $f = new PhingFile($basedir, $file); $struc[$path][] = array( 'file' => basename($file), 'ext' => $ext, 'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)), 'fullpath' => $f->getAbsolutePath() ); } } uksort($struc, 'strnatcasecmp'); foreach ($struc as $key => $ind) { usort($ind, array($this, 'sortfiles')); $struc[$key] = $ind; } $tempstruc = $struc; $struc = array('/' => $tempstruc['/']); $bv = 0; foreach ($tempstruc as $key => $ind) { $save = $key; if ($key != '/') { $struc['/'] = $this->setupDirs($struc['/'], explode('/', $key), $tempstruc[$key]); } } uksort($struc['/'], array($this, 'mystrucsort')); return $struc; } /** * Recursively move contents of $struc into associative array * * The contents of $struc have many indexes like 'dir/subdir/subdir2'. * This function converts them to * array('dir' => array('subdir' => array('subdir2'))) * @param array $struc is array('dir' => array of files in dir, * 'dir/subdir' => array of files in dir/subdir,...) * @param $dir * @param $contents * @internal param array $array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2') * @return array same as struc but with array('dir' => * array(file1,file2,'subdir' => array(file1,...))) */ private function setupDirs($struc, $dir, $contents) { if (!count($dir)) { foreach ($contents as $dir => $files) { if (is_string($dir)) { if (strpos($dir, '/')) { $test = true; $a = $contents[$dir]; unset($contents[$dir]); $b = explode('/', $dir); $c = array_shift($b); if (isset($contents[$c])) { $contents[$c] = $this->setDir($contents[$c], $this->setupDirs(array(), $b, $a)); } else { $contents[$c] = $this->setupDirs(array(), $b, $a); } } } } return $contents; } $me = array_shift($dir); if (!isset($struc[$me])) { $struc[$me] = array(); } $struc[$me] = $this->setupDirs($struc[$me], $dir, $contents); return $struc; } /** * Recursively add all the subdirectories of $contents to $dir without erasing anything in * $dir * @param array * @param array * @return array processed $dir */ public function setDir($dir, $contents) { while (list($one, $two) = each($contents)) { if (isset($dir[$one])) { $dir[$one] = $this->setDir($dir[$one], $contents[$one]); } else { $dir[$one] = $two; } } return $dir; } /** * Sorting functions for the file list * @param string * @param string * @return int */ private function sortfiles($a, $b) { return strnatcasecmp($a['file'], $b['file']); } /** * @param $a * @param $b * @return int */ private function mystrucsort($a, $b) { if (is_numeric($a) && is_string($b)) { return 1; } if (is_numeric($b) && is_string($a)) { return -1; } if (is_numeric($a) && is_numeric($b)) { if ($a > $b) { return 1; } if ($a < $b) { return -1; } if ($a == $b) { return 0; } } return strnatcasecmp($a, $b); } } phing-2.17.4/tasks/ext/ExportPropertiesTask.php0000644000076500000240000000751114261771713020560 0ustar mrookstaff. */ require_once "phing/Task.php"; /** * Saves currently defined properties into a specified file * * @author Andrei Serdeliuc * @extends Task * @version $Id: 6c960e196084540721a620b8fe1c97c642f69d40 $ * @package phing.tasks.ext */ class ExportPropertiesTask extends Task { /** * Array of project properties * * (default value: null) * * @var array */ private $_properties = null; /** * Target file for saved properties * * (default value: null) * * @var string */ private $_targetFile = null; /** * Exclude properties starting with these prefixes * * @var array */ private $_disallowedPropertyPrefixes = array( 'host.', 'phing.', 'os.', 'php.', 'line.', 'env.', 'user.' ); /** * setter for _targetFile * * @param string $file * @throws BuildException * @return bool */ public function setTargetFile($file) { if (!is_dir(dirname($file))) { throw new BuildException("Parent directory of target file doesn't exist"); } if (!is_writable(dirname($file)) && (file_exists($file) && !is_writable($file))) { throw new BuildException("Target file isn't writable"); } $this->_targetFile = $file; return true; } /** * setter for _disallowedPropertyPrefixes * * @param $prefixes * @internal param string $file * @return bool */ public function setDisallowedPropertyPrefixes($prefixes) { $this->_disallowedPropertyPrefixes = explode(",", $prefixes); return true; } public function main() { // Sets the currently declared properties $this->_properties = $this->getProject()->getProperties(); if (is_array($this->_properties) && !empty($this->_properties) && null !== $this->_targetFile) { $propertiesString = ''; foreach ($this->_properties as $propertyName => $propertyValue) { if (!$this->isDisallowedPropery($propertyName)) { $propertiesString .= $propertyName . "=" . $propertyValue . PHP_EOL; } } if (!file_put_contents($this->_targetFile, $propertiesString)) { throw new BuildException('Failed writing to ' . $this->_targetFile); } } } /** * Checks if a property name is disallowed * * @param string $propertyName * @return bool */ protected function isDisallowedPropery($propertyName) { foreach ($this->_disallowedPropertyPrefixes as $property) { if (substr($propertyName, 0, strlen($property)) == $property) { return true; } } return false; } } phing-2.17.4/tasks/ext/PackageAsPathTask.php0000644000076500000240000000370014261771713017652 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * Convert dot-notation packages to relative paths. * * @author Hans Lellelid * @version $Id: 7fee76167437d1ca7bdca2fef13aafc08811085f $ * @package phing.tasks.ext */ class PackageAsPathTask extends Task { /** The package to convert. */ protected $pckg; /** The property to store the conversion in. */ protected $name; /** * Executes the package to patch converstion and stores it * in the user property name. */ public function main() { $this->project->setUserProperty($this->name, strtr($this->pckg, '.', '/')); } /** * @param string $pckg the package to convert */ public function setPackage($pckg) { $this->pckg = $pckg; } /** * @param string $name the property to store the path in */ public function setName($name) { $this->name = $name; } } phing-2.17.4/tasks/ext/CapsuleTask.php0000644000076500000240000003635014261771713016621 0ustar mrookstaff. */ include_once 'phing/Task.php'; include_once 'phing/BuildException.php'; include_once 'phing/lib/Capsule.php'; include_once 'phing/util/StringHelper.php'; /** * A phing task for generating output by using Capsule. * * This is based on the interface to TexenTask from Apache's Velocity engine. * * @author Hans Lellelid * * @package phing.tasks.ext */ class CapsuleTask extends Task { /** * Capsule "template" engine. * @var Capsule */ protected $context; /** * Any vars assigned via the build file. * @var array AssignedVar[] */ protected $assignedVars = array(); /** * This is the control template that governs the output. * It may or may not invoke the services of worker * templates. * @var string */ protected $controlTemplate; /** * This is where Velocity will look for templates * using the file template loader. * @var string */ protected $templatePath; /** * This is where texen will place all the output * that is a product of the generation process. * @var string */ protected $outputDirectory; /** * This is the file where the generated text * will be placed. * @var string */ protected $outputFile; /** *

* These are properties that are fed into the * initial context from a properties file. This * is simply a convenient way to set some values * that you wish to make available in the context. *

*

* These values are not critical, like the template path * or output path, but allow a convenient way to * set a value that may be specific to a particular * generation task. *

*

* For example, if you are generating scripts to allow * user to automatically create a database, then * you might want the $databaseName * to be placed * in the initial context so that it is available * in a script that might look something like the * following: *

     * #!bin/sh
     *
     * echo y | mysqladmin create $databaseName
     * 
* The value of $databaseName isn't critical to * output, and you obviously don't want to change * the ant task to simply take a database name. * So initial context values can be set with * properties file. * * @var array */ protected $contextProperties; // ----------------------------------------------------------------------- // The following getters & setters are used by phing to set properties // specified in the XML for the capsule task. // ----------------------------------------------------------------------- /** * [REQUIRED] Set the control template for the * generating process. * @param string $controlTemplate * @return void */ public function setControlTemplate($controlTemplate) { $this->controlTemplate = $controlTemplate; } /** * Get the control template for the * generating process. * @return string */ public function getControlTemplate() { return $this->controlTemplate; } /** * [REQUIRED] Set the path where Velocity will look * for templates using the file template * loader. * @param $templatePath * @return void */ public function setTemplatePath($templatePath) { $resolvedPath = ""; $tok = strtok($templatePath, ","); while ($tok) { // resolve relative path from basedir and leave // absolute path untouched. $fullPath = $this->project->resolveFile($tok); $cpath = $fullPath->getCanonicalPath(); if ($cpath === false) { $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); } else { $resolvedPath .= $cpath; } $tok = strtok(","); if ($tok) { $resolvedPath .= ","; } } $this->templatePath = $resolvedPath; } /** * Get the path where Velocity will look * for templates using the file template * loader. * @return string */ public function getTemplatePath() { return $this->templatePath; } /** * [REQUIRED] Set the output directory. It will be * created if it doesn't exist. * @param PhingFile $outputDirectory * @return void * @throws Exception */ public function setOutputDirectory(PhingFile $outputDirectory) { try { if (!$outputDirectory->exists()) { $this->log( "Output directory does not exist, creating: " . $outputDirectory->getPath(), Project::MSG_VERBOSE ); if (!$outputDirectory->mkdirs()) { throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); } } $this->outputDirectory = $outputDirectory->getCanonicalPath(); } catch (IOException $ioe) { throw new BuildException($ioe); } } /** * Get the output directory. * @return string */ public function getOutputDirectory() { return $this->outputDirectory; } /** * [REQUIRED] Set the output file for the * generation process. * @param string $outputFile (TODO: change this to File) * @return void */ public function setOutputFile($outputFile) { $this->outputFile = $outputFile; } /** * Get the output file for the * generation process. * @return string */ public function getOutputFile() { return $this->outputFile; } /** * Set the context properties that will be * fed into the initial context be the * generating process starts. * @param string $file * @throws BuildException * @return void */ public function setContextProperties($file) { $sources = explode(",", $file); $this->contextProperties = new Properties(); // Always try to get the context properties resource // from a file first. Templates may be taken from a JAR // file but the context properties resource may be a // resource in the filesystem. If this fails than attempt // to get the context properties resource from the // classpath. for ($i = 0, $sourcesLength = count($sources); $i < $sourcesLength; $i++) { $source = new Properties(); try { // resolve relative path from basedir and leave // absolute path untouched. $fullPath = $this->project->resolveFile($sources[$i]); $this->log("Using contextProperties file: " . $fullPath->toString()); $source->load($fullPath); } catch (Exception $e) { throw new BuildException("Context properties file " . $sources[$i] . " could not be found in the file system!"); } $keys = $source->keys(); foreach ($keys as $key) { $name = $key; $value = $this->project->replaceProperties($source->getProperty($name)); $this->contextProperties->setProperty($name, $value); } } } /** * Get the context properties that will be * fed into the initial context be the * generating process starts. * @return Properties */ public function getContextProperties() { return $this->contextProperties; } /** * Creates an "AssignedVar" class. */ public function createAssign() { $a = new AssignedVar(); $this->assignedVars[] = $a; return $a; } // --------------------------------------------------------------- // End of XML setters & getters // --------------------------------------------------------------- /** * Creates a Smarty object. * * @return Capsule initialized (cleared) Smarty context. * @throws Exception the execute method will catch * and rethrow as a BuildException */ public function initControlContext() { $this->context->clear(); foreach ($this->assignedVars as $var) { $this->context->put($var->getName(), $var->getValue()); } return $this->context; } /** * Execute the input script with Velocity * * @throws BuildException * BuildExceptions are thrown when required attributes are missing. * Exceptions thrown by Velocity are rethrown as BuildExceptions. */ public function main() { // Make sure the template path is set. if (empty($this->templatePath)) { throw new BuildException("The template path needs to be defined!"); } // Make sure the control template is set. if ($this->controlTemplate === null) { throw new BuildException("The control template needs to be defined!"); } // Make sure the output directory is set. if ($this->outputDirectory === null) { throw new BuildException("The output directory needs to be defined!"); } // Make sure there is an output file. if ($this->outputFile === null) { throw new BuildException("The output file needs to be defined!"); } // Setup Smarty runtime. // Smarty uses one object to store properties and to store // the context for the template (unlike Velocity). We setup this object, calling it // $this->context, and then initControlContext simply zeros out // any assigned variables. $this->context = new Capsule(); if ($this->templatePath !== null) { $this->log("Using templatePath: " . $this->templatePath); $this->context->setTemplatePath($this->templatePath); } // Make sure the output directory exists, if it doesn't // then create it. $outputDir = new PhingFile($this->outputDirectory); if (!$outputDir->exists()) { $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath()); $outputDir->mkdirs(); } $this->context->setOutputDirectory($outputDir->getAbsolutePath()); $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; $this->log("Generating to file " . $path); //$writer = new FileWriter($path); // The generator and the output path should // be placed in the init context here and // not in the generator class itself. $c = $this->initControlContext(); // Set any variables that need to always // be loaded $this->populateInitialContext($c); // Feed all the options into the initial // control context so they are available // in the control/worker templates. if ($this->contextProperties !== null) { foreach ($this->contextProperties->keys() as $property) { $value = $this->contextProperties->getProperty($property); // Special exception (from Texen) // for properties ending in file.contents: // in that case we dump the contents of the file // as the "value" for the Property. if (preg_match('/file\.contents$/', $property)) { // pull in contents of file specified $property = substr($property, 0, strpos($property, "file.contents") - 1); // reset value, and then // read in the contents of the file into that var $value = ""; $f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath()); if ($f->exists()) { $fr = new FileReader($f); $fr->readInto($value); } } // if ends with file.contents if (StringHelper::isBoolean($value)) { $value = StringHelper::booleanValue($value); } $c->put($property, $value); } // foreach property } // if contextProperties !== null try { $this->log("Parsing control template: " . $this->controlTemplate); $c->parse($this->controlTemplate, $path); } catch (Exception $ioe) { throw new BuildException("Cannot write parsed template: " . $ioe->getMessage()); } $this->cleanup(); } /** * Place useful objects into the initial context. * * * @param Capsule $context The context to populate, as retrieved from * {@link #initControlContext()}. * @return void * @throws Exception Error while populating context. The {@link * #main()} method will catch and rethrow as a * BuildException. */ protected function populateInitialContext(Capsule $context) { $this->context->put("now", strftime("%c", time())); $this->context->put("task", $this); } /** * A hook method called at the end of {@link #execute()} which can * be overridden to perform any necessary cleanup activities (such * as the release of database connections, etc.). By default, * does nothing. * * @return void */ protected function cleanup() { } } /** * An "inner" class for holding assigned var values. * May be need to expand beyond name/value in the future. * * @package phing.tasks.ext */ class AssignedVar { private $name; private $value; /** * @param string $v */ public function setName($v) { $this->name = $v; } /** * @param mixed $v */ public function setValue($v) { $this->value = $v; } /** * @return string */ public function getName() { return $this->name; } /** * @return mixed */ public function getValue() { return $this->value; } } phing-2.17.4/tasks/ext/phpcs/PhpCodeSnifferTask_Wrapper.php0000644000076500000240000000254314261771713022676 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * Wrapper to disable PHPCS's destructor * * @author Michiel Rook * @version $Id: 0165de67f7d92e363d668430c692ab7f3658dec6 $ * @package phing.tasks.ext */ class PhpCodeSnifferTask_Wrapper extends PHP_CodeSniffer { public function __destruct() { // override destructor } } phing-2.17.4/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php0000644000076500000240000000630514261771713023225 0ustar mrookstaff. */ /** * Remove from cache files where contains errors * * @category PHP * @package PHP_CodeSniffer * @author Rui Filipe Da Cunha Alves */ class PHP_CodeSniffer_Reports_PhingRemoveFromCache implements PHP_CodeSniffer_Report { /** * Cache data storage * @var DataStore */ protected static $cache; /** * Set cache object * * @param DataStore $cache */ public static function setCache($cache) { self::$cache = $cache; } /** * Remove file from cache if contains errors * * @param array $report Prepared report data. * @param PHP_CodeSniffer_File $phpcsFile The file being reported on. * @param boolean $showSources Show sources? * @param int $width Maximum allowed line width. * * @return boolean */ public function generateFileReport( $report, PHP_CodeSniffer_File $phpcsFile, $showSources = false, $width = 80 ) { if (!self::$cache || ($report['errors'] === 0 && $report['warnings'] === 0)) { // Nothing to do return false; } self::$cache->remove($report['filename']); return false; } /** * Do nothing * * @param string $cachedData Any partial report data that was returned from * generateFileReport during the run. * @param int $totalFiles Total number of files processed during the run. * @param int $totalErrors Total number of errors found during the run. * @param int $totalWarnings Total number of warnings found during the run. * @param int $totalFixable Total number of problems that can be fixed. * @param boolean $showSources Show sources? * @param int $width Maximum allowed line width. * @param boolean $toScreen Is the report being printed to screen? * * @return void */ public function generate( $cachedData, $totalFiles, $totalErrors, $totalWarnings, $totalFixable, $showSources = false, $width = 80, $toScreen = true ) { // Do nothing } } phing-2.17.4/tasks/ext/SymlinkTask.php0000644000076500000240000001727314261771713016656 0ustar mrookstaff. */ require_once "phing/Task.php"; /** * Generates symlinks based on a target / link combination. * Can also symlink contents of a directory, individually * * Single target symlink example: * * * * * Symlink entire contents of directory * * This will go through the contents of "/my/shared/library/*" * and create a symlink for each entry into ${project.basedir}/library/ * * * * * * * * * @author Andrei Serdeliuc * @extends Task * @version $ID$ * @package phing.tasks.ext */ class SymlinkTask extends Task { /** * What we're symlinking from * * (default value: null) * * @var string */ private $_target = null; /** * Symlink location * * (default value: null) * * @var string */ private $_link = null; /** * Collection of filesets * Used when linking contents of a directory * * (default value: array()) * * @var array */ private $_filesets = array(); /** * Whether to override the symlink if it exists but points * to a different location * * (default value: false) * * @var boolean */ private $_overwrite = false; /** * Whether to create relative symlinks * * @var boolean */ private $relative = false; /** * setter for _target * * @param string $target * @return void */ public function setTarget($target) { $this->_target = $target; } /** * setter for _link * * @param string $link * @return void */ public function setLink($link) { $this->_link = $link; } /** * creator for _filesets * * @return FileSet */ public function createFileset() { $num = array_push($this->_filesets, new FileSet()); return $this->_filesets[$num - 1]; } /** * setter for _overwrite * * @param boolean $overwrite * @return void */ public function setOverwrite($overwrite) { $this->_overwrite = $overwrite; } /** * @param boolean $relative */ public function setRelative($relative) { $this->relative = $relative; } /** * getter for _target * * @throws BuildException * @return string */ public function getTarget() { if ($this->_target === null) { throw new BuildException('Target not set'); } return $this->_target; } /** * getter for _link * * @throws BuildException * @return string */ public function getLink() { if ($this->_link === null) { throw new BuildException('Link not set'); } return $this->_link; } /** * getter for _filesets * * @return array */ public function getFilesets() { return $this->_filesets; } /** * getter for _overwrite * * @return boolean */ public function getOverwrite() { return $this->_overwrite; } /** * @return boolean */ public function isRelative() { return $this->relative; } /** * Generates an array of directories / files to be linked * If _filesets is empty, returns getTarget() * * @throws BuildException * @return array|string */ protected function getMap() { $fileSets = $this->getFilesets(); // No filesets set // We're assuming single file / directory if (empty($fileSets)) { return $this->getTarget(); } $targets = array(); foreach ($fileSets as $fs) { if (!($fs instanceof FileSet)) { continue; } // We need a directory to store the links if (!is_dir($this->getLink())) { throw new BuildException('Link must be an existing directory when using fileset'); } if ($this->isRelative()) { $fromDir = $fs->getDir($this->getProject())->getPath(); } else { $fromDir = $fs->getDir($this->getProject())->getAbsolutePath(); } if (!is_dir($fromDir)) { $this->log('Directory doesn\'t exist: ' . $fromDir, Project::MSG_WARN); continue; } $fsTargets = array(); $ds = $fs->getDirectoryScanner($this->getProject()); $fsTargets = array_merge( $fsTargets, $ds->getIncludedDirectories(), $ds->getIncludedFiles() ); // Add each target to the map foreach ($fsTargets as $target) { if (!empty($target)) { $targets[$target] = $fromDir . DIRECTORY_SEPARATOR . $target; } } } return $targets; } /** * Main entry point for task * * @return bool */ public function main() { $map = $this->getMap(); // Single file symlink if (is_string($map)) { return $this->symlink($map, $this->getLink()); } // Multiple symlinks foreach ($map as $name => $targetPath) { $this->symlink($targetPath, $this->getLink() . DIRECTORY_SEPARATOR . $name); } return true; } /** * Create the actual link * * @param string $target * @param string $link * @return bool */ protected function symlink($target, $link) { $fs = FileSystem::getFileSystem(); if (is_link($link) && @readlink($link) == $target) { $this->log('Link exists: ' . $link, Project::MSG_INFO); return true; } if (file_exists($link) || is_link($link)) { if (!$this->getOverwrite()) { $this->log('Not overwriting existing link ' . $link, Project::MSG_ERR); return false; } if (is_link($link) || is_file($link)) { $fs->unlink($link); $this->log('Link removed: ' . $link, Project::MSG_INFO); } else { $fs->rmdir($link, true); $this->log('Directory removed: ' . $link, Project::MSG_INFO); } } $this->log('Linking: ' . $target . ' to ' . $link, Project::MSG_INFO); return $fs->symlink($target, $link); } } phing-2.17.4/tasks/ext/PhpCodeSnifferTask.php0000644000076500000240000005677114261771713020075 0ustar mrookstaff. */ require_once 'phing/Task.php'; /** * A PHP code sniffer task. Checking the style of one or more PHP source files. * * @author Dirk Thomas * @version $Id: 1cb309b7992d03271825878803e5cabb757b9d63 $ * @package phing.tasks.ext */ class PhpCodeSnifferTask extends Task { /** * A php source code filename or directory * * @var PhingFile */ protected $file; // the source file (from xml attribute) /** * All fileset objects assigned to this task * * @var FileSet[] */ protected $filesets = array(); // all fileset objects assigned to this task // parameters for php code sniffer protected $standards = array('Generic'); protected $sniffs = array(); protected $showWarnings = true; protected $showSources = false; protected $reportWidth = 80; protected $verbosity = 0; protected $tabWidth = 0; protected $allowedFileExtensions = array('php', 'inc', 'js', 'css'); protected $allowedTypes = array(); protected $ignorePatterns = false; protected $noSubdirectories = false; protected $configData = array(); protected $encoding = 'iso-8859-1'; // parameters to customize output protected $showSniffs = false; protected $format = 'full'; /** * @var PhpCodeSnifferTask_FormatterElement[] */ protected $formatters = array(); /** * Holds the type of the doc generator * * @var string */ protected $docGenerator = ''; /** * Holds the outfile for the documentation * * @var PhingFile */ protected $docFile = null; private $haltonerror = false; private $haltonwarning = false; private $skipversioncheck = false; private $propertyName = null; /** * Cache data storage * @var DataStore */ protected $cache; /** * Load the necessary environment for running PHP_CodeSniffer. * * @return void */ public function init() { } /** * File to be performed syntax check on * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets the coding standard to test for * * @param string $standards The coding standards * * @return void */ public function setStandard($standards) { $this->standards = array(); $token = ' ,;'; $ext = strtok($standards, $token); while ($ext !== false) { $this->standards[] = $ext; $ext = strtok($token); } } /** * Sets the sniffs which the standard should be restricted to * @param string $sniffs */ public function setSniffs($sniffs) { $token = ' ,;'; $sniff = strtok($sniffs, $token); while ($sniff !== false) { $this->sniffs[] = $sniff; $sniff = strtok($token); } } /** * Sets the type of the doc generator * * @param string $generator HTML or Text * * @return void */ public function setDocGenerator($generator) { $this->docGenerator = $generator; } /** * Sets the outfile for the documentation * * @param PhingFile $file The outfile for the doc * * @return void */ public function setDocFile(PhingFile $file) { $this->docFile = $file; } /** * Sets the flag if warnings should be shown * @param boolean $show */ public function setShowWarnings($show) { $this->showWarnings = StringHelper::booleanValue($show); } /** * Sets the flag if sources should be shown * * @param boolean $show Whether to show sources or not * * @return void */ public function setShowSources($show) { $this->showSources = StringHelper::booleanValue($show); } /** * Sets the width of the report * * @param int $width How wide the screen reports should be. * * @return void */ public function setReportWidth($width) { $this->reportWidth = (int) $width; } /** * Sets the verbosity level * @param int $level */ public function setVerbosity($level) { $this->verbosity = (int) $level; } /** * Sets the tab width to replace tabs with spaces * @param int $width */ public function setTabWidth($width) { $this->tabWidth = (int) $width; } /** * Sets file encoding * @param string $encoding */ public function setEncoding($encoding) { $this->encoding = $encoding; } /** * Sets the allowed file extensions when using directories instead of specific files * @param array $extensions */ public function setAllowedFileExtensions($extensions) { $this->allowedFileExtensions = array(); $token = ' ,;'; $ext = strtok($extensions, $token); while ($ext !== false) { $this->allowedFileExtensions[] = $ext; $ext = strtok($token); } } /** * Sets the allowed types for the PHP_CodeSniffer::suggestType() * @param array $types */ public function setAllowedTypes($types) { $this->allowedTypes = array(); $token = ' ,;'; $type = strtok($types, $token); while ($type !== false) { $this->allowedTypes[] = $type; $type = strtok($token); } } /** * Sets the ignore patterns to skip files when using directories instead of specific files * @param $patterns * @internal param array $extensions */ public function setIgnorePatterns($patterns) { $this->ignorePatterns = array(); $token = ' ,;'; $pattern = strtok($patterns, $token); while ($pattern !== false) { $this->ignorePatterns[$pattern] = 'relative'; $pattern = strtok($token); } } /** * Sets the flag if subdirectories should be skipped * @param boolean $subdirectories */ public function setNoSubdirectories($subdirectories) { $this->noSubdirectories = StringHelper::booleanValue($subdirectories); } /** * Creates a config parameter for this task * * @return Parameter The created parameter */ public function createConfig() { $num = array_push($this->configData, new Parameter()); return $this->configData[$num - 1]; } /** * Sets the flag if the used sniffs should be listed * @param boolean $show */ public function setShowSniffs($show) { $this->showSniffs = StringHelper::booleanValue($show); } /** * Sets the output format * @param string $format */ public function setFormat($format) { $this->format = $format; } /** * Create object for nested formatter element. * @return PhpCodeSnifferTask_FormatterElement */ public function createFormatter() { $num = array_push( $this->formatters, new PhpCodeSnifferTask_FormatterElement() ); return $this->formatters[$num - 1]; } /** * Sets the haltonerror flag * @param boolean $value */ public function setHaltonerror($value) { $this->haltonerror = $value; } /** * Sets the haltonwarning flag * @param boolean $value */ public function setHaltonwarning($value) { $this->haltonwarning = $value; } /** * Sets the skipversioncheck flag * @param boolean $value */ public function setSkipVersionCheck($value) { $this->skipversioncheck = $value; } /** * Sets the name of the property to use * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use */ public function getPropertyName() { return $this->propertyName; } /** * Whether to store last-modified times in cache * * @param PhingFile $file */ public function setCacheFile(PhingFile $file) { $this->cache = new DataStore($file); } /** * Return the list of files to parse * * @return string[] list of absolute files to parse */ protected function getFilesToParse() { $filesToParse = array(); if ($this->file instanceof PhingFile) { $filesToParse[] = $this->file->getPath(); } else { // append any files in filesets foreach ($this->filesets as $fs) { $dir = $fs->getDir($this->project)->getAbsolutePath(); foreach ($fs->getDirectoryScanner($this->project)->getIncludedFiles() as $filename) { $fileAbsolutePath = $dir . DIRECTORY_SEPARATOR . $filename; if ($this->cache) { $lastMTime = $this->cache->get($fileAbsolutePath); $currentMTime = filemtime($fileAbsolutePath); if ($lastMTime >= $currentMTime) { continue; } else { $this->cache->put($fileAbsolutePath, $currentMTime); } } $filesToParse[] = $fileAbsolutePath; } } } return $filesToParse; } /** * Executes PHP code sniffer against PhingFile or a FileSet */ public function main() { if (!class_exists('PHP_CodeSniffer')) { @include_once 'PHP/CodeSniffer.php'; if (!class_exists('PHP_CodeSniffer')) { throw new BuildException("This task requires the PHP_CodeSniffer package installed and available on the include path", $this->getLocation( )); } } /** * Determine PHP_CodeSniffer version number */ if (!$this->skipversioncheck) { if (defined('PHP_CodeSniffer::VERSION')) { preg_match('/\d\.\d\.\d/', PHP_CodeSniffer::VERSION, $version); } else { preg_match('/\d\.\d\.\d/', shell_exec('phpcs --version'), $version); } if (version_compare($version[0], '1.2.2') < 0) { throw new BuildException( 'PhpCodeSnifferTask requires PHP_CodeSniffer version >= 1.2.2', $this->getLocation() ); } } if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } if (count($this->formatters) == 0) { // turn legacy format attribute into formatter $fmt = new PhpCodeSnifferTask_FormatterElement(); $fmt->setType($this->format); $fmt->setUseFile(false); $this->formatters[] = $fmt; } $fileList = $this->getFilesToParse(); $cwd = getcwd(); // Save command line arguments because it confuses PHPCS (version 1.3.0) $oldArgs = $_SERVER['argv']; $_SERVER['argv'] = array(); $_SERVER['argc'] = 0; include_once 'phing/tasks/ext/phpcs/PhpCodeSnifferTask_Wrapper.php'; $codeSniffer = new PhpCodeSnifferTask_Wrapper($this->verbosity, $this->tabWidth, $this->encoding); $codeSniffer->setAllowedFileExtensions($this->allowedFileExtensions); if ($this->allowedTypes) { PhpCodeSnifferTask_Wrapper::$allowedTypes = $this->allowedTypes; } if (is_array($this->ignorePatterns)) { $codeSniffer->setIgnorePatterns($this->ignorePatterns); } foreach ($this->configData as $configData) { $codeSniffer->setConfigData($configData->getName(), $configData->getValue(), true); } /* * Verifying if standard is installed only after setting config data. * Custom standard paths could be provided via installed_paths config parameter. */ foreach($this->standards as $standard) { if (PHP_CodeSniffer::isInstalledStandard($standard) === false) { // They didn't select a valid coding standard, so help them // out by letting them know which standards are installed. $installedStandards = PHP_CodeSniffer::getInstalledStandards(); $numStandards = count($installedStandards); $errMsg = ''; if ($numStandards === 0) { $errMsg = 'No coding standards are installed.'; } else { $lastStandard = array_pop($installedStandards); if ($numStandards === 1) { $errMsg = 'The only coding standard installed is ' . $lastStandard; } else { $standardList = implode(', ', $installedStandards); $standardList .= ' and ' . $lastStandard; $errMsg = 'The installed coding standards are ' . $standardList; } } throw new BuildException( 'ERROR: the "' . $standard . '" coding standard is not installed. ' . $errMsg, $this->getLocation() ); } } if (!$this->showWarnings) { $codeSniffer->cli->warningSeverity = 0; } // nasty integration hack $values = $codeSniffer->cli->getDefaults(); $_SERVER['argv'] = array('t'); $_SERVER['argc'] = 1; foreach ($this->formatters as $fe) { if ($fe->getUseFile()) { $_SERVER['argv'][] = '--report-' . $fe->getType() . '=' . $fe->getOutfile(); } else { $_SERVER['argv'][] = '--report-' . $fe->getType(); } $_SERVER['argc']++; } if ($this->cache) { require_once 'phing/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php'; PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache($this->cache); // add a fake report to remove from cache $_SERVER['argv'][] = '--report-phingRemoveFromCache='; $_SERVER['argc']++; } $codeSniffer->process($fileList, $this->standards, $this->sniffs, $this->noSubdirectories); $_SERVER['argv'] = array(); $_SERVER['argc'] = 0; if ($this->cache) { PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache(null); $this->cache->commit(); } $this->printErrorReport($codeSniffer); // generate the documentation if ($this->docGenerator !== '' && $this->docFile !== null) { ob_start(); $codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator); $output = ob_get_contents(); ob_end_clean(); // write to file $outputFile = $this->docFile->getPath(); $check = file_put_contents($outputFile, $output); if ($check === false) { throw new BuildException('Error writing doc to ' . $outputFile); } } elseif ($this->docGenerator !== '' && $this->docFile === null) { $codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator); } if ($this->haltonerror && $codeSniffer->reporting->totalErrors > 0) { throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalErrors . ' error' . ($codeSniffer->reporting->totalErrors > 1 ? 's' : '')); } if ($this->haltonwarning && $codeSniffer->reporting->totalWarnings > 0) { throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalWarnings . ' warning' . ($codeSniffer->reporting->totalWarnings > 1 ? 's' : '')); } $_SERVER['argv'] = $oldArgs; $_SERVER['argc'] = count($oldArgs); chdir($cwd); } /** * Prints the error report. * * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing * the errors. */ protected function printErrorReport($phpcs) { $sniffs = $phpcs->getSniffs(); $sniffStr = ''; foreach ($sniffs as $sniff) { if (is_string($sniff)) { $sniffStr .= '- ' . $sniff . PHP_EOL; } else { $sniffStr .= '- ' . get_class($sniff) . PHP_EOL; } } $this->project->setProperty($this->getPropertyName(), (string) $sniffStr); if ($this->showSniffs) { $this->log('The list of used sniffs (#' . count($sniffs) . '): ' . PHP_EOL . $sniffStr, Project::MSG_INFO); } // process output $reporting = $phpcs->reporting; foreach ($this->formatters as $fe) { $reportFile = null; if ($fe->getUseFile()) { $reportFile = $fe->getOutfile(); //ob_start(); } // Crude check, but they broke backwards compatibility // with a minor version release. if (PHP_CodeSniffer::VERSION >= '2.2.0') { $cliValues = array('colors' => false); $reporting->printReport($fe->getType(), $this->showSources, $cliValues, $reportFile, $this->reportWidth); } else { $reporting->printReport($fe->getType(), $this->showSources, $reportFile, $this->reportWidth); } // reporting class uses ob_end_flush(), but we don't want // an output if we use a file if ($fe->getUseFile()) { //ob_end_clean(); } } } /** * Outputs the results with a custom format * * @param array $report Packaged list of all errors in each file */ protected function outputCustomFormat($report) { $files = $report['files']; foreach ($files as $file => $attributes) { $errors = $attributes['errors']; $warnings = $attributes['warnings']; $messages = $attributes['messages']; if ($errors > 0) { $this->log( $file . ': ' . $errors . ' error' . ($errors > 1 ? 's' : '') . ' detected', Project::MSG_ERR ); $this->outputCustomFormatMessages($messages, 'ERROR'); } else { $this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE); } if ($warnings > 0) { $this->log( $file . ': ' . $warnings . ' warning' . ($warnings > 1 ? 's' : '') . ' detected', Project::MSG_WARN ); $this->outputCustomFormatMessages($messages, 'WARNING'); } } $totalErrors = $report['totals']['errors']; $totalWarnings = $report['totals']['warnings']; $this->log(count($files) . ' files were checked', Project::MSG_INFO); if ($totalErrors > 0) { $this->log($totalErrors . ' error' . ($totalErrors > 1 ? 's' : '') . ' detected', Project::MSG_ERR); } else { $this->log('No syntax errors detected', Project::MSG_INFO); } if ($totalWarnings > 0) { $this->log($totalWarnings . ' warning' . ($totalWarnings > 1 ? 's' : '') . ' detected', Project::MSG_INFO); } } /** * Outputs the messages of a specific type for one file * @param array $messages * @param string $type */ protected function outputCustomFormatMessages($messages, $type) { foreach ($messages as $line => $messagesPerLine) { foreach ($messagesPerLine as $column => $messagesPerColumn) { foreach ($messagesPerColumn as $message) { $msgType = $message['type']; if ($type == $msgType) { $logLevel = Project::MSG_INFO; if ($msgType == 'ERROR') { $logLevel = Project::MSG_ERR; } else { if ($msgType == 'WARNING') { $logLevel = Project::MSG_WARN; } } $text = $message['message']; $string = $msgType . ' in line ' . $line . ' column ' . $column . ': ' . $text; $this->log($string, $logLevel); } } } } } } //end phpCodeSnifferTask /** * @package phing.tasks.ext */ class PhpCodeSnifferTask_FormatterElement extends DataType { /** * Type of output to generate * @var string */ protected $type = ""; /** * Output to file? * @var bool */ protected $useFile = true; /** * Output file. * @var string */ protected $outfile = ""; /** * Validate config. */ public function parsingComplete() { if (empty($this->type)) { throw new BuildException("Format missing required 'type' attribute."); } if ($this->useFile && empty($this->outfile)) { throw new BuildException("Format requires 'outfile' attribute when 'useFile' is true."); } } /** * @param $type */ public function setType($type) { $this->type = $type; } /** * @return string */ public function getType() { return $this->type; } /** * @param $useFile */ public function setUseFile($useFile) { $this->useFile = $useFile; } /** * @return bool */ public function getUseFile() { return $this->useFile; } /** * @param $outfile */ public function setOutfile($outfile) { $this->outfile = $outfile; } /** * @return string */ public function getOutfile() { return $this->outfile; } } //end FormatterElement phing-2.17.4/tasks/ext/PearPackageTask.php0000644000076500000240000003464614261771713017376 0ustar mrookstaff. */ require_once 'phing/tasks/system/MatchingTask.php'; include_once 'phing/types/FileSet.php'; /** * A task to create PEAR package.xml file. * * This class uses the PEAR_PackageFileMaintainer class to perform the work. * * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o * requiring changes to this class. We've accomplished this by having generic