Skip to content

Instantly share code, notes, and snippets.

@dewwwald
Last active August 12, 2016 07:34
Show Gist options
  • Save dewwwald/89adb7b659103eecb37beb7643649992 to your computer and use it in GitHub Desktop.
Save dewwwald/89adb7b659103eecb37beb7643649992 to your computer and use it in GitHub Desktop.
CakePhp Component: write arrays to database and back, with tests.
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
class DatabaseArrayComponent extends Component
{
public function decode_array ($string, $level = 0)
{
preg_match('/\%'.($level).'(.*)\/\%'.($level).'/', $string, $matches);
$config = array();
$main = $matches[1];
$thisLevel = preg_replace('/(\%'.($level+1).')([a-zA-Z0-9: ,\/\.&]*)(\/\%'.($level+1).')/', '$1', $main);
$items = explode('&', $thisLevel);
preg_match_all('/(\%'.($level+1).'[a-zA-Z0-9: ,\/\.&]*\/\%'.($level+1).')/', $string, $subMatches);
$sub_config = array();
foreach ($subMatches[0] as $subMatch)
{
if (isset($subMatch[0]))
{
$sub_config[] = $this->decode_array($subMatch, $level+1);
}
}
$sub_config = array_reverse($sub_config);
// var_dump($sub_config);
$count = count($items);
foreach ($items as $item) {
$attribute = explode(':', $item, 2);
if (stripos($attribute[1], '%'.($level+1)) !== false)
{
$config[$attribute[0]] = array_pop($sub_config);
}
else if ($count > 0)
{
$config[$attribute[0]] = $attribute[1];
}
$count--;
}
return $config;
}
public function encode_array ($fields, $level = 0)
{
$str = "";
foreach($fields as $key => $value)
{
if(is_array($value))
{
$tmp = $this->encode_array($value, $level+1);
}
else
{
$tmp = $value;
}
$str .= $key.":".$tmp."&";
}
$str = substr($str,0,strlen($str)-1);
return '%'.$level.$str.'/%'.$level;
}
}
<?php
namespace App\Test\TestCase\Controller\Component;
use App\Controller\Component\AnimationConfigParserComponent;
use Cake\Controller\Controller;
use Cake\Controller\ComponentRegistry;
use Cake\Network\Request;
use Cake\Network\Response;
use Cake\TestSuite\TestCase;
class DatabaseArrayComponentTest extends TestCase
{
public $component = null;
public $controller = null;
public function setUp()
{
parent::setUp();
// Setup our component and fake test controller
// $request = new Request();
// $response = new Response();
$this->controller = $this->getMockBuilder('Cake\Controller\Controller')
->setMethods(null)
->getMock();
$registry = new ComponentRegistry($this->controller);
$this->component = new AnimationConfigParserComponent($registry);
}
public function testEncode_array()
{
$this->assertEquals('%0image:%1value:config/bla/ba.com&type:string/%1&time:%1value:100&type:int/%1&age:testing extras/%0', $this->component->encode_array([
'image'=> [
'value' => 'config/bla/ba.com',
'type' => 'string'
],
'time' => [
'value'=> 100,
'type' => 'int'
],
'age' => 'testing extras'
]));
$this->assertEquals(
"%0images:%1name:Images&type:imageArray&value:33,34,35/%1&timer:%1name:Animation Time&type:timeline&value:50/%1/%0",
$this->component->encode_array([
"images" => [
"name"=> "Images",
"type"=> "imageArray",
"value" => "33,34,35"
],
"timer" => [
"name" => "Animation Time",
"type"=> "timeline",
"value"=> "50"
]
]));
$this->assertEquals("%0images:%1name:Images&type:imageArray/%1&timer:%1name:Animation Time&type:timeline/%1/%0", $this->component->encode_array(["images" => ["name" => "Images", "type"=> "imageArray"], "timer" => ["name" => "Animation Time", "type"=> "timeline"]]));
$this->assertEquals('%0image:/%0', $this->component->encode_array(['image'=>'']));
}
public function testDecode_array()
{
$this->assertEquals([
'image'=> [
'value' => 'config/bla/ba.com',
'type' => 'string'
],
'time' => [
'value'=> 100,
'type' => 'int'
],
'age' => 'testing extras'
],
$this->component->decode_array('%0image:%1value:config/bla/ba.com&type:string/%1&time:%1value:100&type:int/%1&age:testing extras/%0')
);
$this->assertEquals([
"images" => [
"name"=> "Images",
"type"=> "imageArray",
"value" => "33,34,35"
],
"timer" => [
"name" => "Animation Time",
"type"=> "timeline",
"value"=> "50"
]
], $this->component->decode_array("%0images:%1name:Images&type:imageArray&value:33,34,35/%1&timer:%1name:Animation Time&type:timeline&value:50/%1/%0"));
$this->assertEquals(
[
"images" => [
"name" => "Images",
"type"=> "imageArray"
],
"timer" => [
"name" => "Animation Time",
"type"=> "timeline"
]
],
$this->component->decode_array("%0images:%1name:Images&type:imageArray/%1&timer:%1name:Animation Time&type:timeline/%1/%0")
);
$this->assertEquals([
'image'=> [
'value' => 'config/bla/ba.com',
'type' => 'string'
],
'time' => [
'value'=> 100,
'type' => 'int'
]
],
$this->component->decode_array('%0image:%1value:config/bla/ba.com&type:string/%1&time:%1value:100&type:int/%1/%0')
);
$this->assertEquals(
['image'=>'config/bla/ba.com', 'time' => '100'],
$this->component->decode_array('%0image:config/bla/ba.com&time:100/%0')
);
$this->assertEquals(
['image'=>''],
$this->component->decode_array('%0image:/%0')
);
}
public function tearDown()
{
parent::tearDown();
// Clean up after we're done
unset($this->component, $this->controller);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment