Skip to content

Commit d0c2d12

Browse files
committed
#73 Refactor & fix
1 parent be33cfe commit d0c2d12

File tree

4 files changed

+110
-61
lines changed

4 files changed

+110
-61
lines changed

main/UI/View/JsonPView.class.php

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
class JsonPView extends JsonView
1717
{
18+
/**
19+
* Javascript valid function name pattern
20+
*/
21+
const CALLBACK_PATTERN = '/^[\$A-Z_][0-9A-Z_\$]*$/i';
22+
1823
/**
1924
* @static
2025
* @return JsonPView
@@ -37,7 +42,19 @@ public static function create()
3742
*/
3843
public function setCallback($callback)
3944
{
40-
$this->callback = $callback;
45+
$realCallbackName = null;
46+
47+
if(is_scalar($callback))
48+
$realCallbackName = $callback;
49+
elseif($callback instanceof Stringable)
50+
$realCallbackName = $callback->toString();
51+
else
52+
throw new WrongArgumentException('undefined type of callback, gived "'.gettype($callback).'"');
53+
54+
if(!preg_match(static::CALLBACK_PATTERN, $realCallbackName))
55+
throw new WrongArgumentException('invalid function name, you should set valid javascript function name! gived "'.$realCallbackName.'"');
56+
57+
$this->callback = $realCallbackName;
4158

4259
return $this;
4360
}
@@ -48,23 +65,11 @@ public function setCallback($callback)
4865
*/
4966
public function toString(/* Model */ $model = null)
5067
{
51-
$callback = null;
52-
53-
if(is_scalar($this->callback))
54-
$callback = $this->callback;
55-
elseif($this->callback instanceof Stringable)
56-
$callback = $this->callback->toString();
57-
else
58-
throw new WrongArgumentException('undefined type of callback, gived "'.gettype($this->callback).'"');
59-
60-
Assert::isNotEmpty($callback, 'callback can not be empty!');
61-
62-
if(!preg_match('/^[\$A-Z_][0-9A-Z_\$]*$/i', $callback))
63-
throw new WrongArgumentException('invalid function name, you should set valid javascript function name! gived "'.$callback.'"');
68+
Assert::isNotEmpty($this->callback, 'callback can not be empty!');
6469

6570
$json = parent::toString($model);
6671

67-
return $callback.'('.$json.');';
72+
return $this->callback.'('.$json.');';
6873
}
6974

7075
}

main/UI/View/JsonXssView.class.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@
1515

1616
class JsonXssView extends JsonPView
1717
{
18+
/**
19+
* Javascript valid function name pattern
20+
*/
21+
const CALLBACK_PATTERN = '/^[\$A-Z_][0-9A-Z_\$\.]*$/i';
22+
23+
/**
24+
* Default prefix
25+
* @var string
26+
*/
27+
protected $prefix = 'window.';
28+
29+
/**
30+
* Default callback
31+
* @var string
32+
*/
33+
protected $callback = 'name';
1834

1935
/**
2036
* @static
@@ -25,6 +41,21 @@ public static function create()
2541
return new self();
2642
}
2743

44+
/**
45+
* @param $value
46+
* @return JsonXssView
47+
* @throws WrongArgumentException
48+
*/
49+
public function setPrefix($value)
50+
{
51+
if(!preg_match(static::CALLBACK_PATTERN, $value))
52+
throw new WrongArgumentException('invalid prefix name, you should set valid javascript function name! gived "'.$value.'"');
53+
54+
$this->prefix = $value;
55+
56+
return $this;
57+
}
58+
2859
/**
2960
* @param Model $model
3061
* @return string
@@ -39,16 +70,16 @@ public function toString(/* Model */ $model = null)
3970
$this->setHexQuot(true);
4071
$this->setHexTag(true);
4172

42-
$jsonp = parent::toString($model);
73+
$json = JsonView::toString($model);
4374

44-
$jsonp = str_ireplace(
75+
$json = str_ireplace(
4576
array('u0022', 'u0027'),
4677
array('\u0022', '\u0027'),
47-
$jsonp
78+
$json
4879
);
4980

5081
$result = '<script type="text/javascript">'."\n";
51-
$result.="\t".$jsonp."\n";
82+
$result.="\t".$this->prefix.$this->callback.'=\''.$json.'\';'."\n";
5283
$result.='</script>'."\n";
5384

5485
return $result;

test/main/JsonPViewTest.class.php

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,47 @@ final class JsonPViewTest extends TestCase
1616

1717
public function testMain()
1818
{
19-
$this->execCallback('myCallback');
19+
$model = Model::create()->set('array', $this->array);
20+
$data = array('array' => $this->array);
21+
$callback = 'myFunc';
22+
23+
//setup
24+
$view = JsonPView::create();
2025

2126
try{
22-
$this->execCallback(''); // empty js callback function name
27+
// empty js callback function name
28+
$view->toString($model);
2329

2430
$this->fail('empty callback javascript function name expected!');
2531
} catch(WrongArgumentException $e) {}
2632

2733
try{
28-
$this->execCallback('34_callback'); // invalid javascript function name
34+
$view->setCallback('34_callback'); // invalid javascript function name
2935

3036
$this->fail('invalid javascript function name expected!');
3137
} catch(WrongArgumentException $e) {}
3238

33-
}
39+
$view->setCallback($callback);
3440

35-
protected function execCallback($callback)
36-
{
37-
Assert::isScalar($callback);
41+
$this->assertEquals($this->makeString($callback, $data), $view->toString($model) );
3842

39-
$model = Model::create()->set('array', $this->array);
40-
$data = array('array' => $this->array);
43+
$simpleStringableObject = SimpleStringableObject::create()->setString($callback);
4144

42-
//setup
43-
$view = JsonPView::create()->setCallback($callback);
45+
$view->setCallback($simpleStringableObject);
4446

45-
//execution and check
46-
$this->assertEquals(
47-
$callback.'('.json_encode(
48-
$data
49-
).');',
50-
$view->toString($model)
51-
);
52-
53-
//setup from stringable object
54-
$view = JsonPView::create()->setCallback(
55-
SimpleStringableObject::create()->setString($callback)
56-
);
57-
58-
//execution and check
59-
$this->assertEquals(
60-
$callback.'('.json_encode(
61-
$data
62-
).');',
63-
$view->toString($model)
64-
);
47+
$this->assertEquals($this->makeString($callback, $data), $view->toString($model) );
48+
}
6549

50+
/**
51+
* @param $callback
52+
* @param $data
53+
* @return string
54+
*/
55+
protected function makeString($callback, $data)
56+
{
57+
return $callback.'('.json_encode(
58+
$data
59+
).');';
6660
}
6761

6862
}

test/main/JsonXssViewTest.class.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,40 @@ final class JsonXssViewTest extends TestCase
1515

1616
public function testMain()
1717
{
18-
$callback = 'myCallback';
18+
$prefix = 'window.';
19+
$callback = 'name';
1920

2021
$model = Model::create()->set('array', $this->array);
2122
$data = array('array' => $this->array);
2223

2324
//setup
24-
$view = JsonXssView::create()->setCallback($callback);
25+
$view = JsonXssView::create();
2526

26-
//execution and check
27-
$this->assertEquals(
28-
'<script type="text/javascript">'."\n".
29-
"\t".$callback.'('.
27+
$defaultString = $view->toString($model);
28+
29+
$this->assertEquals($defaultString, $this->makeString($prefix, $callback, $data) );
30+
31+
32+
$prefix='window2.';
33+
$callback='name2';
34+
35+
$view->setCallback($callback);
36+
$view->setPrefix($prefix);
37+
38+
$customString = $view->toString($model);
39+
40+
$this->assertEquals($customString, $this->makeString($prefix, $callback, $data) );
41+
}
42+
43+
/**
44+
* @param $prefix
45+
* @param $callback
46+
* @return string
47+
*/
48+
protected function makeString($prefix, $callback, $data)
49+
{
50+
return '<script type="text/javascript">'."\n".
51+
"\t".$prefix.$callback.'=\''.
3052
str_ireplace(
3153
array('u0022', 'u0027'),
3254
array('\u0022', '\u0027'),
@@ -38,11 +60,8 @@ public function testMain()
3860
JSON_HEX_TAG
3961
)
4062
).
41-
');'."\n".
42-
'</script>'."\n",
43-
$view->toString($model)
44-
);
45-
63+
'\';'."\n".
64+
'</script>'."\n";
4665
}
4766

4867
}

0 commit comments

Comments
 (0)