Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for creating custom attributes in the parsing phase. #1237

Merged
merged 3 commits into from
Jan 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions classes/phing/IntrospectionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ public function setAttribute(Project $project, $element, $attributeName, &$value
$as = "set" . strtolower($attributeName);

if (!isset($this->attributeSetters[$as])) {
if ($element instanceof DynamicAttribute) {
$element->setDynamicAttribute($attributeName, (string) $value);
return;
}
$msg = $this->getElementName($project, $element) . " doesn't support the '$attributeName' attribute.";
throw new BuildException($msg);
}
Expand Down
36 changes: 36 additions & 0 deletions classes/phing/parser/DynamicAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

/**
* Enables a task to control unknown attributes.
*
* @author Siad Ardroumli <siad.ardroumli@gmail.com>
* @package phing.parser
*/
interface DynamicAttribute
{
/**
* Set a named attribute to the given value.
*
* @param string $name the name of the attribute
* @param string $value the new value of the attribute
* @throws BuildException when any error occurs
*/
public function setDynamicAttribute(string $name, string $value): void;
}
28 changes: 28 additions & 0 deletions classes/phing/parser/DynamicConfigurator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

/**
* Enables a task to control unknown attributes and elements.
*
* @author Siad Ardroumli <siad.ardroumli@gmail.com>
* @package phing.parser
*/
interface DynamicConfigurator extends DynamicAttribute, CustomChildCreator
{
}
60 changes: 60 additions & 0 deletions classes/phing/tasks/system/DynamicTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

/**
*
* @author Siad Ardroumli <siad.ardroumli@gmail.com>
* @package phing.tasks.system
*/
class DynamicTask extends Task implements DynamicConfigurator
{
public function main()
{
}

public function setDynamicAttribute(string $name, string $value): void
{
$this->getProject()->setNewProperty($name, $value);
}

public function customChildCreator($name, Project $project)
{
return new class ($project) implements DynamicConfigurator {
/**
* @var Project
*/
private $project;

public function __construct(Project $project)
{
$this->project = $project;
}

public function setDynamicAttribute(string $name, string $value): void
{
$this->project->setNewProperty($name, $value);
}

public function customChildCreator($name, Project $project)
{
return null;
}
};
}
}
48 changes: 48 additions & 0 deletions test/classes/phing/tasks/system/DynamicTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

/**
* Tests dynamics
*
* @author Siad Ardroumli
* @package phing.tasks.system
*/
class DynamicTest extends BuildFileTest
{
public function setUp(): void
{
$this->configureProject(
PHING_TEST_BASE
. "/etc/tasks/system/DynamicTest.xml"
);
}

public function testSimple()
{
$this->executeTarget('simple');

/** @var Project $project */
$project = $this->getProject();

$this->assertSame('1', $project->getProperty('prop1'));
$this->assertSame('2', $project->getProperty('prop2'));
$this->assertSame('3', $project->getProperty('prop3'));
$this->assertSame('4', $project->getProperty('prop4'));
}
}
19 changes: 19 additions & 0 deletions test/etc/tasks/system/DynamicTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="dynamic-test" default="simple">

<path id="testclasses">
<pathelement path="${php.classpath}"/>
</path>

<target name="simple">
<taskdef name="dyna"
classname="phing.tasks.system.DynamicTask">
<classpath refid="testclasses"/>
</taskdef>
<dyna prop1="1" prop2="2">
<sub prop3="3"/>
<anything prop4="4"/>
</dyna>
</target>

</project>