<commit_before><?php
/**
 * PHPTAL templating engine
 *
 * PHP Version 5
 *
 * @category HTML
 * @package  PHPTAL
 * @author   <NAME> <<EMAIL>>
 * @author   <NAME> <<EMAIL>>
 * @license  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
 * @version  SVN: $Id$
 * @link     http://phptal.org/
 */

require_once 'PHPTAL/Dom/Defs.php';
require_once 'PHPTAL/Dom/Attr.php';

/**
 * For backwards compatibility only. Do not use!
 * @deprecated
 */
interface PHPTAL_Php_Tree
{
}

/**
 * Document Tag representation.
 *
 * @package PHPTAL
 * @subpackage Dom
 */
class PHPTAL_Dom_Element extends PHPTAL_Dom_Node implements PHPTAL_Php_Tree
{
    protected $qualifiedName, $namespace_uri;
    private $attribute_nodes = array();
    protected $replaceAttributes = array();
    protected $contentAttributes = array();
    protected $surroundAttributes = array();
    public $headFootDisabled = false;
    public $headPrintCondition = false;
    public $footPrintCondition = false;
    public $hidden = false;

    // W3C DOM interface
    public $childNodes = array();
    public $parentNode;

    /**
     * @param string $qname           qualified name of the element, e.g. "tal:block"
     * @param string $namespace_uri   namespace of this element
     * @param array  $attribute_nodes array of PHPTAL_Dom_Attr elements
     * @param object $xmlns           object that represents namespaces/prefixes known in element's context
     */
    public function __construct($qname, $namespace_uri, array $attribute_nodes, PHPTAL_Dom_XmlnsState $xmlns)
    {
        $this->qualifiedName = $qname;
        $this->attribute_nodes = $attribute_nodes;
        $this->namespace_uri = $namespace_uri;
        $this->xmlns = $xmlns;

        // implements inheritance of element's namespace to tal attributes (<metal: use-macro>)
        foreach ($attribute_nodes as $index => $attr) {
            // it'll work only when qname == localname, which is good
            if ($this->xmlns->isValidAttributeNS($namespace_uri, $attr->getQualifiedName())) {
                $this->attribute_nodes[$index] = new PHPTAL_Dom_Attr($attr->getQualifiedName(), $namespace_uri, $attr->getValueEscaped(), $attr->getEncoding());
            }
        }

        if ($this->xmlns->isHandledNamespace($this->namespace_uri)) {
            $this->headFootDisabled = true;
        }

        $talAttributes = $this->separateAttributes();
        $this->orderTalAttributes($talAttributes);
    }

    /**
     * returns object that represents namespaces known in element's context
     */
    public function getXmlnsState()
    {
        return $this->xmlns;
    }

    /**
     * Replace <script> foo &gt; bar </script>
     * with <script>/*<![CDATA[* / foo > bar /*]]>* /</script>
     * This avoids gotcha in text/html.
     *
     * Note that PHPTAL_Dom_CDATASection::generate() does reverse operation, if needed!
     *
     * @return void
     */
    private function replaceTextWithCDATA()
    {
        $isCDATAelement = PHPTAL_Dom_Defs::getInstance()->isCDATAElementInHTML($this->getNamespaceURI(), $this->getLocalName());

        if (!$isCDATAelement) {
            return;
        }

        $valueEscaped = ''; // sometimes parser generates split text nodes. "normalisation" is needed.
        $value = '';
        foreach ($this->childNodes as $node) {
            // leave it alone if there is CDATA, comment, or anything else.
            if (!$node instanceOf PHPTAL_Dom_Text) return;

            $value .= $node->getValue();
            $valueEscaped .= $node->getValueEscaped();

            $encoding = $node->getEncoding(); // encoding of all nodes is the same
        }

        // only add cdata if there are entities
        // and there's no ${structure} (because it may rely on cdata syntax)
        if (false === strpos($valueEscaped,'&') || preg_match('/<\?|\${structure/', $value)) {
            return;
        }

        $this->childNodes = array();

        // appendChild sets parent
        $this->appendChild(new PHPTAL_Dom_Text('/*', $encoding));
        $this->appendChild(new PHPTAL_Dom_CDATASection('*/'.$value.'/*', $encoding));
        $this->appendChild(new PHPTAL_Dom_Text('*/', $encoding));
    }

    /**
     * support <?php ?> inside attributes
     */
    private function replacePHPAttributes()
    {
        foreach ($this->attribute_nodes as $attr) {
            $split = preg_split("/<\?(php|=|)(.*?)\?>/", $attr->getValueEscaped(), null, PREG_SPLIT_DELIM_CAPTURE);
            if (count($split)==1) continue;

            $new_value = '';
            for($i=0; $i < count($split); $i += 3) {
                if (strlen($split[$i])) {
                    $new_value .= 'echo \''.str_replace('\'', '\\\'', $split[$i]).'\';';
                }

                if (isset($split[$i+2])) {
                    if ($split[$i+1] === '=') $new_value .= 'echo ';
                    $new_value .= rtrim($split[$i+2], "; \n\r").';';
                }
            }
            $attr->overwriteValueWithCode($new_value);
        }
    }

    public function appendChild(PHPTAL_Dom_Node $child)
    {
        $child->parentNode = $this;
        $this->childNodes[] = $child;
    }
    
    public function removeChild(PHPTAL_Dom_Node $child)
    {
        foreach ($this->childNodes as $k => $node) {
            if ($child === $node) {
                $child->parentNode = null;
                array_splice($this->childNodes,$k,1);
                return;
            }
        }
        throw new PHPTAL_Exception("Given node is not child of ".$this->getQualifiedName());
    }
    
    public function replaceChild(PHPTAL_Dom_Node $newElement, PHPTAL_Dom_Node $oldElement)
    {
        foreach ($this->childNodes as $k => $node) {
            if ($node === $oldElement) {
                $oldElement->parentNode = null;
                $newElement->parentNode = $this;
                $this->childNodes[$k] = $newElement;
                return;
            }
        }
        throw new PHPTAL_Exception("Given node is not child of ".$this->getQualifiedName());<commit_msg>Made appendChild move element if necessary<commit_after><?php
/**
 * PHPTAL templating engine
 *
 * PHP Version 5
 *
 * @category HTML
 * @package  PHPTAL
 * @author   <NAME> <<EMAIL>>
 * @author   <NAME> <<EMAIL>>
 * @license  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
 * @version  SVN: $Id$
 * @link     http://phptal.org/
 */

require_once 'PHPTAL/Dom/Defs.php';
require_once 'PHPTAL/Dom/Attr.php';

/**
 * For backwards compatibility only. Do not use!
 * @deprecated
 */
interface PHPTAL_Php_Tree
{
}

/**
 * Document Tag representation.
 *
 * @package PHPTAL
 * @subpackage Dom
 */
class PHPTAL_Dom_Element extends PHPTAL_Dom_Node implements PHPTAL_Php_Tree
{
    protected $qualifiedName, $namespace_uri;
    private $attribute_nodes = array();
    protected $replaceAttributes = array();
    protected $contentAttributes = array();
    protected $surroundAttributes = array();
    public $headFootDisabled = false;
    public $headPrintCondition = false;
    public $footPrintCondition = false;
    public $hidden = false;

    // W3C DOM interface
    public $childNodes = array();
    public $parentNode;

    /**
     * @param string $qname           qualified name of the element, e.g. "tal:block"
     * @param string $namespace_uri   namespace of this element
     * @param array  $attribute_nodes array of PHPTAL_Dom_Attr elements
     * @param object $xmlns           object that represents namespaces/prefixes known in element's context
     */
    public function __construct($qname, $namespace_uri, array $attribute_nodes, PHPTAL_Dom_XmlnsState $xmlns)
    {
        $this->qualifiedName = $qname;
        $this->attribute_nodes = $attribute_nodes;
        $this->namespace_uri = $namespace_uri;
        $this->xmlns = $xmlns;

        // implements inheritance of element's namespace to tal attributes (<metal: use-macro>)
        foreach ($attribute_nodes as $index => $attr) {
            // it'll work only when qname == localname, which is good
            if ($this->xmlns->isValidAttributeNS($namespace_uri, $attr->getQualifiedName())) {
                $this->attribute_nodes[$index] = new PHPTAL_Dom_Attr($attr->getQualifiedName(), $namespace_uri, $attr->getValueEscaped(), $attr->getEncoding());
            }
        }

        if ($this->xmlns->isHandledNamespace($this->namespace_uri)) {
            $this->headFootDisabled = true;
        }

        $talAttributes = $this->separateAttributes();
        $this->orderTalAttributes($talAttributes);
    }

    /**
     * returns object that represents namespaces known in element's context
     */
    public function getXmlnsState()
    {
        return $this->xmlns;
    }

    /**
     * Replace <script> foo &gt; bar </script>
     * with <script>/*<![CDATA[* / foo > bar /*]]>* /</script>
     * This avoids gotcha in text/html.
     *
     * Note that PHPTAL_Dom_CDATASection::generate() does reverse operation, if needed!
     *
     * @return void
     */
    private function replaceTextWithCDATA()
    {
        $isCDATAelement = PHPTAL_Dom_Defs::getInstance()->isCDATAElementInHTML($this->getNamespaceURI(), $this->getLocalName());

        if (!$isCDATAelement) {
            return;
        }

        $valueEscaped = ''; // sometimes parser generates split text nodes. "normalisation" is needed.
        $value = '';
        foreach ($this->childNodes as $node) {
            // leave it alone if there is CDATA, comment, or anything else.
            if (!$node instanceOf PHPTAL_Dom_Text) return;

            $value .= $node->getValue();
            $valueEscaped .= $node->getValueEscaped();

            $encoding = $node->getEncoding(); // encoding of all nodes is the same
        }

        // only add cdata if there are entities
        // and there's no ${structure} (because it may rely on cdata syntax)
        if (false === strpos($valueEscaped,'&') || preg_match('/<\?|\${structure/', $value)) {
            return;
        }

        $this->childNodes = array();

        // appendChild sets parent
        $this->appendChild(new PHPTAL_Dom_Text('/*', $encoding));
        $this->appendChild(new PHPTAL_Dom_CDATASection('*/'.$value.'/*', $encoding));
        $this->appendChild(new PHPTAL_Dom_Text('*/', $encoding));
    }

    /**
     * support <?php ?> inside attributes
     */
    private function replacePHPAttributes()
    {
        foreach ($this->attribute_nodes as $attr) {
            $split = preg_split("/<\?(php|=|)(.*?)\?>/", $attr->getValueEscaped(), null, PREG_SPLIT_DELIM_CAPTURE);
            if (count($split)==1) continue;

            $new_value = '';
            for($i=0; $i < count($split); $i += 3) {
                if (strlen($split[$i])) {
                    $new_value .= 'echo \''.str_replace('\'', '\\\'', $split[$i]).'\';';
                }

                if (isset($split[$i+2])) {
                    if ($split[$i+1] === '=') $new_value .= 'echo ';
                    $new_value .= rtrim($split[$i+2], "; \n\r").';';
                }
            }
            $attr->overwriteValueWithCode($new_value);
        }
    }

    public function appendChild(PHPTAL_Dom_Node $child)
    {
        if ($child->parentNode) $child->parentNode->removeChild($child);
        $child->parentNode = $this;
        $this->childNodes[] = $child;
    }
    
    public function removeChild(PHPTAL_Dom_Node $child)
    {
        foreach ($this->childNodes as $k => $node) {
            if ($child === $node) {
                $child->parentNode = null;
                array_splice($this->childNodes,$k,1);
                return;
            }
        }
        throw new PHPTAL_Exception("Given node is not child of ".$this->getQualifiedName());
    }
    
    public function replaceChild(PHPTAL_Dom_Node $newElement, PHPTAL_Dom_Node $oldElement)
    {
        foreach ($this->childNodes as $k => $node) {
            if ($node === $oldElement) {
                $oldElement->parentNode = null;
                $newElement->parentNode = $this;
                $this->childNodes[$k] = $newElement;
                return;
            }
        }
        throw new PHPTAL_Exception("Given node is not child of ".$this->getQualifiedName());
{'fraction_non_alphanumeric': 0.14336801040312094, 'fraction_numerical': 0.0014629388816644994, 'mean_word_length': 2.3383071079761257, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 128, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2204922', 'n_tokens_mistral': 3646, 'n_tokens_neox': 3550, 'n_words': 841}