mirror of
https://github.com/Universal-Omega/PortableInfobox.git
synced 2024-11-15 11:59:56 +00:00
DAT-3199 unit tests fixed
This commit is contained in:
parent
859a0ee81b
commit
dbef0b9915
|
@ -48,6 +48,7 @@ $wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxDataBag' ] = $
|
||||||
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' ] = $dir . 'services/Helpers/PortableInfoboxRenderServiceHelper.php';
|
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper' ] = $dir . 'services/Helpers/PortableInfoboxRenderServiceHelper.php';
|
||||||
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxClassification' ] = $dir . 'services/Helpers/PortableInfoboxClassification.php';
|
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxClassification' ] = $dir . 'services/Helpers/PortableInfoboxClassification.php';
|
||||||
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper' ] = $dir . 'services/Helpers/PortableInfoboxTemplatesHelper.php';
|
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper' ] = $dir . 'services/Helpers/PortableInfoboxTemplatesHelper.php';
|
||||||
|
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\PagePropsProxy' ] = $dir . 'services/Helpers/PagePropsProxy.php';
|
||||||
|
|
||||||
// controller classes
|
// controller classes
|
||||||
$wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php';
|
$wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php';
|
||||||
|
|
15
services/Helpers/PagePropsProxy.php
Normal file
15
services/Helpers/PagePropsProxy.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Wikia\PortableInfobox\Helpers;
|
||||||
|
|
||||||
|
class PagePropsProxy {
|
||||||
|
|
||||||
|
public function get( $id, $property ) {
|
||||||
|
return \Wikia::getProps( $id, $property );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set( $id, $data ) {
|
||||||
|
\Wikia::setProps( $id, $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ class PortableInfoboxTemplatesHelper {
|
||||||
*
|
*
|
||||||
* @param $title \Title
|
* @param $title \Title
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed false when no infoboxes found, Array with infoboxes on success
|
||||||
*/
|
*/
|
||||||
public function parseInfoboxes( $title ) {
|
public function parseInfoboxes( $title ) {
|
||||||
// for templates we need to check for include tags
|
// for templates we need to check for include tags
|
||||||
|
@ -42,7 +42,8 @@ class PortableInfoboxTemplatesHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $parser->getOutput()->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME );
|
return json_decode( $parser->getOutput()
|
||||||
|
->getProperty( \PortableInfoboxDataService::INFOBOXES_PROPERTY_NAME ), true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Wikia\PortableInfobox\Helpers\PagePropsProxy;
|
||||||
use Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper;
|
use Wikia\PortableInfobox\Helpers\PortableInfoboxTemplatesHelper;
|
||||||
use Wikia\PortableInfobox\Parser\Nodes\NodeInfobox;
|
use Wikia\PortableInfobox\Parser\Nodes\NodeInfobox;
|
||||||
|
|
||||||
|
@ -8,34 +9,47 @@ class PortableInfoboxDataService {
|
||||||
const IMAGE_FIELD_TYPE = 'image';
|
const IMAGE_FIELD_TYPE = 'image';
|
||||||
const INFOBOXES_PROPERTY_NAME = 'infoboxes';
|
const INFOBOXES_PROPERTY_NAME = 'infoboxes';
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Title $title
|
|
||||||
*/
|
|
||||||
protected $title;
|
protected $title;
|
||||||
protected $templateHelper;
|
protected $templateHelper;
|
||||||
|
protected $propsProxy;
|
||||||
protected $cache;
|
protected $cache;
|
||||||
protected $cachekey;
|
protected $cachekey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $title Title
|
* @param $title Title
|
||||||
* @param $helper
|
*
|
||||||
|
* @internal param $helper
|
||||||
*/
|
*/
|
||||||
protected function __construct( $title, $helper ) {
|
protected function __construct( $title ) {
|
||||||
$this->title = $title;
|
$this->title = $title !== null ? $title : new Title();
|
||||||
$this->templateHelper = $helper ? $helper : new PortableInfoboxTemplatesHelper();
|
$this->templateHelper = new PortableInfoboxTemplatesHelper();
|
||||||
$this->cachekey = wfMemcKey( $title->getArticleID(), self::INFOBOXES_PROPERTY_NAME );
|
$this->propsProxy = new PagePropsProxy();
|
||||||
|
$this->cachekey = wfMemcKey( $this->title->getArticleID(), self::INFOBOXES_PROPERTY_NAME );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function newFromTitle( $title, $helper = null ) {
|
public static function newFromTitle( $title ) {
|
||||||
return new PortableInfoboxDataService( $title, $helper );
|
return new PortableInfoboxDataService( $title );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function newFromPageID( $pageid, $helper = null ) {
|
public static function newFromPageID( $pageid ) {
|
||||||
return new PortableInfoboxDataService( Title::newFromID( $pageid ), $helper );
|
return new PortableInfoboxDataService( Title::newFromID( $pageid ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set internal helpers methods
|
||||||
|
public function setTemplatesHelper( $helper ) {
|
||||||
|
$this->templateHelper = $helper;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPagePropsProxy( $proxy ) {
|
||||||
|
$this->propsProxy = $proxy;
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns infobox data
|
* Returns infobox data, terminal method
|
||||||
*
|
*
|
||||||
* @return array in format [ 'data' => [], 'sources' => [] ] or [] will be returned
|
* @return array in format [ 'data' => [], 'sources' => [] ] or [] will be returned
|
||||||
*/
|
*/
|
||||||
|
@ -44,15 +58,16 @@ class PortableInfoboxDataService {
|
||||||
$hidden = $this->templateHelper->parseInfoboxes( $this->title );
|
$hidden = $this->templateHelper->parseInfoboxes( $this->title );
|
||||||
if ( $hidden ) {
|
if ( $hidden ) {
|
||||||
$this->delete();
|
$this->delete();
|
||||||
$this->set( json_decode( $hidden, true ) );
|
$this->set( $hidden );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
$result = $this->get();
|
||||||
|
|
||||||
return $this->get();
|
return $result !== null ? $result : [ ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get image list from infobox data
|
* Get image list from infobox data, terminal method
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
@ -79,6 +94,8 @@ class PortableInfoboxDataService {
|
||||||
* Save infobox data, permanently
|
* Save infobox data, permanently
|
||||||
*
|
*
|
||||||
* @param NodeInfobox $raw infobox parser output
|
* @param NodeInfobox $raw infobox parser output
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function save( NodeInfobox $raw ) {
|
public function save( NodeInfobox $raw ) {
|
||||||
if ( $raw ) {
|
if ( $raw ) {
|
||||||
|
@ -86,6 +103,8 @@ class PortableInfoboxDataService {
|
||||||
$stored[] = [ 'data' => $raw->getRenderData(), 'sources' => $raw->getSource() ];
|
$stored[] = [ 'data' => $raw->getRenderData(), 'sources' => $raw->getSource() ];
|
||||||
$this->set( $stored );
|
$this->set( $stored );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +113,8 @@ class PortableInfoboxDataService {
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$this->clear();
|
$this->clear();
|
||||||
unset( $this->cache );
|
unset( $this->cache );
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,6 +125,8 @@ class PortableInfoboxDataService {
|
||||||
global $wgMemc;
|
global $wgMemc;
|
||||||
$wgMemc->delete( $this->cachekey );
|
$wgMemc->delete( $this->cachekey );
|
||||||
unset( $this->cache );
|
unset( $this->cache );
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// soft cache handlers
|
// soft cache handlers
|
||||||
|
@ -128,7 +151,7 @@ class PortableInfoboxDataService {
|
||||||
// first try memcache, then go to props
|
// first try memcache, then go to props
|
||||||
$data = $wgMemc->get( $this->cachekey );
|
$data = $wgMemc->get( $this->cachekey );
|
||||||
if ( $data === false ) {
|
if ( $data === false ) {
|
||||||
$data = json_decode( Wikia::getProps( $id, self::INFOBOXES_PROPERTY_NAME ), true );
|
$data = json_decode( $this->propsProxy->get( $id, self::INFOBOXES_PROPERTY_NAME ), true );
|
||||||
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
|
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +166,7 @@ class PortableInfoboxDataService {
|
||||||
if ( $id ) {
|
if ( $id ) {
|
||||||
global $wgMemc;
|
global $wgMemc;
|
||||||
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
|
$wgMemc->set( $this->cachekey, $data, WikiaResponse::CACHE_STANDARD );
|
||||||
Wikia::setProps( $id, [ self::INFOBOXES_PROPERTY_NAME => json_encode( $data ) ] );
|
$this->propsProxy->set( $id, [ self::INFOBOXES_PROPERTY_NAME => json_encode( $data ) ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +175,7 @@ class PortableInfoboxDataService {
|
||||||
if ( $id ) {
|
if ( $id ) {
|
||||||
global $wgMemc;
|
global $wgMemc;
|
||||||
$wgMemc->set( $this->cachekey, '', WikiaResponse::CACHE_STANDARD );
|
$wgMemc->set( $this->cachekey, '', WikiaResponse::CACHE_STANDARD );
|
||||||
Wikia::setProps( $id, [ self::INFOBOXES_PROPERTY_NAME => '' ] );
|
$this->propsProxy->set( $id, [ self::INFOBOXES_PROPERTY_NAME => '' ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Wikia\PortableInfobox\Parser\Nodes\NodeFactory;
|
||||||
|
|
||||||
class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
|
class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
|
@ -7,86 +9,177 @@ class PortableInfoboxDataServiceTest extends PHPUnit_Framework_TestCase {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getInfoboxData() {
|
/**
|
||||||
$data =
|
* @param $id
|
||||||
[
|
* @param int $ns
|
||||||
[ // INFOBOX 1
|
*
|
||||||
'data' => [
|
* @return Title
|
||||||
[
|
*/
|
||||||
"type" => "data",
|
protected function prepareTitle( $id = 0, $ns = NS_MAIN ) {
|
||||||
"data" => [
|
$title = new Title();
|
||||||
"value" => "AAAA",
|
$title->mArticleID = $id;
|
||||||
"label" => "BBBB"
|
$title->mNamespace = $ns;
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"type" => "image",
|
|
||||||
"data" => [
|
|
||||||
"key" => "Test.jpg",
|
|
||||||
"alt" => null,
|
|
||||||
"caption" => null,
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"type" => "image",
|
|
||||||
"data" => [
|
|
||||||
"key" => "Test2.jpg",
|
|
||||||
"alt" => null,
|
|
||||||
"caption" => null
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[ // INFOBOX 2
|
|
||||||
'data' => [
|
|
||||||
[
|
|
||||||
"type" => "image",
|
|
||||||
"data" => [
|
|
||||||
"key" => "Test2.jpg",
|
|
||||||
"alt" => null,
|
|
||||||
"caption" => null
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
return $data;
|
return $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEmptyData() {
|
||||||
|
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle() )
|
||||||
|
// empty page props
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
|
||||||
|
->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( [ ], $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoadFromProps() {
|
||||||
|
$data = '[{"data": [], "sources": []}]';
|
||||||
|
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
|
// purge memc so we can rerun tests
|
||||||
|
->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) )
|
||||||
|
->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( json_decode( $data, true ), $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSave() {
|
||||||
|
$markup = '<infobox><data source="test"><default>{{{test2}}}</default></data></infobox>';
|
||||||
|
$infoboxNode = NodeFactory::newFromXML( $markup, [ 'test' => 1 ] );
|
||||||
|
|
||||||
|
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
|
->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
|
||||||
|
->save( $infoboxNode )
|
||||||
|
->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( [ [ 'data' => [ [ 'type' => 'data', 'data' => [ 'label' => null, 'value' => 1 ] ] ],
|
||||||
|
'sources' => [ 'test', 'test2' ] ] ], $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTemplate() {
|
||||||
|
$data = [ [ 'data' => [ ], 'sources' => [ ] ] ];
|
||||||
|
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1, NS_TEMPLATE ) )
|
||||||
|
->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) )
|
||||||
|
->setTemplatesHelper( new TemplateHelperDummy( $data ) )
|
||||||
|
->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( $data, $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDelete() {
|
||||||
|
$data = '[{"data": [], "sources": []}]';
|
||||||
|
$result = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
|
// purge memc so we can rerun tests
|
||||||
|
->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) )
|
||||||
|
->delete()
|
||||||
|
->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( '', $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPurge() {
|
||||||
|
$data = '[{"data": [], "sources": []}]';
|
||||||
|
$service = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
|
// purge memc so we can rerun tests
|
||||||
|
->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => $data ] ) );
|
||||||
|
|
||||||
|
// this should load data from props to memc
|
||||||
|
$result = $service->getData();
|
||||||
|
|
||||||
|
$service->purge()
|
||||||
|
->setPagePropsProxy( new PagePropsProxyDummy( [ ] ) );
|
||||||
|
$purged = $service->getData();
|
||||||
|
|
||||||
|
$this->assertEquals( [ json_decode( $data, true ), [ ] ], [ $result, $purged ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testImageListRemoveDuplicates() {
|
public function testImageListRemoveDuplicates() {
|
||||||
$mock = $this->getMockBuilder( 'PortableInfoboxDataService' )
|
$images = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
->disableOriginalConstructor()
|
->purge()
|
||||||
->setMethods( [ 'getData' ] )
|
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => json_encode( $this->getInfoboxData() ) ] ) )
|
||||||
->getMock();
|
->getImages();
|
||||||
$mock->expects( $this->any() )->method( 'getData' )->will( $this->returnValue( $this->getInfoboxData() ) );
|
|
||||||
|
|
||||||
$images = $mock->getImages();
|
$this->assertEquals( count( $images ), 2 );
|
||||||
$this->assertTrue( count( $images ) === 2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testImageListFetchImages() {
|
public function testImageListFetchImages() {
|
||||||
$mock = $this->getMockBuilder( 'PortableInfoboxDataService' )
|
$images = PortableInfoboxDataService::newFromTitle( $this->prepareTitle( 1 ) )
|
||||||
->disableOriginalConstructor()
|
->purge()
|
||||||
->setMethods( [ 'getData' ] )
|
->setPagePropsProxy( new PagePropsProxyDummy( [ '1infoboxes' => json_encode( $this->getInfoboxData() ) ] ) )
|
||||||
->getMock();
|
->getImages();
|
||||||
$mock->expects( $this->any() )->method( 'getData' )->will( $this->returnValue( $this->getInfoboxData() ) );
|
|
||||||
|
|
||||||
$images = $mock->getImages();
|
$this->assertEquals( [ 'Test.jpg', 'Test2.jpg' ], $images );
|
||||||
$this->assertTrue( in_array( "Test.jpg", $images ), "Test.jpg should be in images array" );
|
|
||||||
$this->assertTrue( in_array( "Test2.jpg", $images ), "Test2.jpg should be in images array" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTitleNullConstructor() {
|
public function testTitleNullConstructor() {
|
||||||
$service = PortableInfoboxDataService::newFromTitle(null);
|
$service = PortableInfoboxDataService::newFromTitle( null );
|
||||||
$result = $service->getData();
|
$result = $service->getData();
|
||||||
$this->assertEquals( [], $result );
|
$this->assertEquals( [ ], $result );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructor() {
|
public function testConstructor() {
|
||||||
$service = PortableInfoboxDataService::newFromPageID(null);
|
$service = PortableInfoboxDataService::newFromPageID( null );
|
||||||
$result = $service->getData();
|
$result = $service->getData();
|
||||||
$this->assertEquals( [], $result );
|
$this->assertEquals( [ ], $result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getInfoboxData() {
|
||||||
|
return [ [ 'data' => [ [ "type" => "data",
|
||||||
|
"data" => [
|
||||||
|
"value" => "AAAA",
|
||||||
|
"label" => "BBBB"
|
||||||
|
]
|
||||||
|
], [ "type" => "image",
|
||||||
|
"data" => [
|
||||||
|
"key" => "Test.jpg",
|
||||||
|
"alt" => null,
|
||||||
|
"caption" => null,
|
||||||
|
]
|
||||||
|
], [ "type" => "image",
|
||||||
|
"data" => [
|
||||||
|
"key" => "Test2.jpg",
|
||||||
|
"alt" => null,
|
||||||
|
"caption" => null
|
||||||
|
] ] ] ],
|
||||||
|
[ 'data' => [ [ "type" => "image",
|
||||||
|
"data" => [
|
||||||
|
"key" => "Test2.jpg",
|
||||||
|
"alt" => null,
|
||||||
|
"caption" => null
|
||||||
|
] ] ] ] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TemplateHelperDummy {
|
||||||
|
|
||||||
|
public function __construct( $hidden = false ) {
|
||||||
|
$this->hidden = $hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseInfoboxes( $title ) {
|
||||||
|
return $this->hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PagePropsProxyDummy {
|
||||||
|
|
||||||
|
public function __construct( $data ) {
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get( $id, $property ) {
|
||||||
|
$prop = $this->data[ $id . $property ];
|
||||||
|
|
||||||
|
return $prop !== null ? $prop : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set( $id, $data ) {
|
||||||
|
foreach ( $data as $property => $value ) {
|
||||||
|
$this->data[ $id . $property ] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue