Skip to content

Commit 6d93e15

Browse files
authored
Merge pull request #23 from codex-team/revert-22-revert-21-beta-editor
Fix editor according to the Beta requirements
2 parents 46ccc4a + f3c4dbc commit 6d93e15

34 files changed

+3340
-873
lines changed

.php_cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
return PhpCsFixer\Config::create()
4+
->setUsingCache(false)
5+
->setRules([
6+
'@PSR2' => true,
7+
'array_syntax' => ['syntax' => 'short'],
8+
'ordered_imports' => true,
9+
'single_import_per_statement' => false,
10+
'no_whitespace_in_blank_line' => true,
11+
'no_unused_imports' => true,
12+
'no_blank_lines_before_namespace' => false,
13+
'blank_line_before_return' => true,
14+
'binary_operator_spaces' => true,
15+
'cast_spaces' => true,
16+
'short_scalar_cast' => true,
17+
'declare_equal_normalize' => true,
18+
'method_argument_space' => true,
19+
'method_separation' => true,
20+
'no_leading_namespace_whitespace' => true,
21+
'no_multiline_whitespace_around_double_arrow' => true,
22+
'no_whitespace_before_comma_in_array' => true,
23+
'trim_array_spaces' => true,
24+
//'single_quote' => true,
25+
'phpdoc_add_missing_param_annotation' => true,
26+
'phpdoc_align' => true,
27+
'phpdoc_scalar' => true,
28+
'phpdoc_indent' => true,
29+
'phpdoc_order' => true,
30+
'phpdoc_separation' => true,
31+
'no_empty_statement' => true,
32+
'concat_space' => ['spacing' => 'one'],
33+
'no_multiline_whitespace_before_semicolons' => true,
34+
'no_leading_import_slash' => true,
35+
'no_trailing_comma_in_list_call' => true,
36+
'no_trailing_comma_in_singleline_array' => true,
37+
'phpdoc_add_missing_param_annotation' => true,
38+
'phpdoc_align' => true,
39+
'phpdoc_no_empty_return' => true,
40+
'return_type_declaration' => true,
41+
'ternary_operator_spaces' => true,
42+
])
43+
->setFinder(
44+
PhpCsFixer\Finder::create()
45+
->in(__DIR__)
46+
);

CodexEditor/BlockHandler.php

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<?php
2+
3+
namespace CodexEditor;
4+
5+
/**
6+
* Class BlockHandler
7+
*
8+
* @package CodexEditor
9+
*/
10+
class BlockHandler
11+
{
12+
/**
13+
* Default pseudo-key for numerical arrays
14+
*/
15+
const DEFAULT_ARRAY_KEY = "-";
16+
17+
/**
18+
* @var ConfigLoader|null
19+
*/
20+
private $rules = null;
21+
22+
/**
23+
* @var \HTMLPurifier_Config
24+
*/
25+
private $sanitizer;
26+
27+
/**
28+
* BlockHandler constructor
29+
*
30+
* @param \HTMLPurifier_Config $sanitizer
31+
* @param string $configuration
32+
*
33+
* @throws CodexEditorException
34+
*/
35+
public function __construct($configuration, $sanitizer)
36+
{
37+
$this->rules = new ConfigLoader($configuration);
38+
$this->sanitizer = $sanitizer;
39+
}
40+
41+
/**
42+
* Validate block for correctness
43+
*
44+
* @param string $blockType
45+
* @param array $blockData
46+
*
47+
* @throws CodexEditorException
48+
*
49+
* @return bool
50+
*/
51+
public function validateBlock($blockType, $blockData)
52+
{
53+
/**
54+
* Default action for blocks that are not mentioned in a configuration
55+
*/
56+
if (!array_key_exists($blockType, $this->rules->tools)) {
57+
throw new CodexEditorException("Tool `$blockType` not found in the configuration");
58+
}
59+
60+
$rule = $this->rules->tools[$blockType];
61+
62+
return $this->validate($rule, $blockData);
63+
}
64+
65+
/**
66+
* Apply sanitizing rules according to the block type
67+
*
68+
* @param string $blockType
69+
* @param array $blockData
70+
*
71+
* @throws CodexEditorException
72+
*
73+
* @return array|bool
74+
*/
75+
public function sanitizeBlock($blockType, $blockData)
76+
{
77+
$rule = $this->rules->tools[$blockType];
78+
79+
return [
80+
'type' => $blockType,
81+
'data' => $this->sanitize($rule, $blockData)
82+
];
83+
}
84+
85+
/**
86+
* Apply validation rule to the data block
87+
*
88+
* @param array $rules
89+
* @param array $blockData
90+
*
91+
* @throws CodexEditorException
92+
*
93+
* @return bool
94+
*/
95+
private function validate($rules, $blockData)
96+
{
97+
/**
98+
* Make sure that every required param exists in data block
99+
*/
100+
foreach ($rules as $key => $value) {
101+
if (($key != BlockHandler::DEFAULT_ARRAY_KEY) && (isset($value['required']) ? $value['required'] : true)) {
102+
if (!isset($blockData[$key])) {
103+
throw new CodexEditorException("Not found required param `$key`");
104+
}
105+
}
106+
}
107+
108+
/**
109+
* Check if there is not extra params (not mentioned in configuration rule)
110+
*/
111+
foreach ($blockData as $key => $value) {
112+
if (!is_integer($key) && !isset($rules[$key])) {
113+
throw new CodexEditorException("Found extra param `$key`");
114+
}
115+
}
116+
117+
/**
118+
* Validate every key in data block
119+
*/
120+
foreach ($blockData as $key => $value) {
121+
/**
122+
* PHP Array has integer keys
123+
*/
124+
if (is_integer($key)) {
125+
$key = BlockHandler::DEFAULT_ARRAY_KEY;
126+
}
127+
128+
$rule = $rules[$key];
129+
$elementType = $rule['type'];
130+
131+
/**
132+
* Process canBeOnly rule
133+
*/
134+
if (isset($rule['canBeOnly'])) {
135+
if (!in_array($value, $rule['canBeOnly'])) {
136+
throw new CodexEditorException("Option '$key' with value `$value` has invalid value. Check canBeOnly param.");
137+
}
138+
}
139+
140+
/**
141+
* Validate element types
142+
*/
143+
switch ($elementType) {
144+
case 'string':
145+
if (!is_string($value)) {
146+
throw new CodexEditorException("Option '$key' with value `$value` must be string");
147+
}
148+
break;
149+
150+
case 'integer':
151+
case 'int':
152+
if (!is_integer($value)) {
153+
throw new CodexEditorException("Option '$key' with value `$value` must be integer");
154+
}
155+
break;
156+
157+
case 'array':
158+
$this->validate($rule['data'], $value);
159+
break;
160+
161+
case 'boolean':
162+
case 'bool':
163+
if (!is_bool($value)) {
164+
throw new CodexEditorException("Option '$key' with value `$value` must be boolean");
165+
}
166+
break;
167+
168+
default:
169+
throw new CodexEditorException("Unhandled type `$elementType`");
170+
}
171+
}
172+
173+
return true;
174+
}
175+
176+
/**
177+
* Sanitize strings in the data block
178+
*
179+
* @param array $rules
180+
* @param array $blockData
181+
*
182+
* @throws CodexEditorException
183+
*
184+
* @return array
185+
*/
186+
private function sanitize($rules, $blockData)
187+
{
188+
/**
189+
* Sanitize every key in data block
190+
*/
191+
foreach ($blockData as $key => $value) {
192+
$rule = $rules[$key];
193+
$elementType = $rule['type'];
194+
195+
/**
196+
* Sanitize string with Purifier
197+
*/
198+
if ($elementType == 'string') {
199+
$allowedTags = isset($rule['allowedTags']) ? $rule['allowedTags'] : '';
200+
$blockData[$key] = $this->getPurifier($allowedTags)->purify($value);
201+
}
202+
203+
/**
204+
* Sanitize nested elements
205+
*/
206+
if ($elementType == 'array') {
207+
$blockData[$key] = $this->sanitize($rule['data'], $value);
208+
}
209+
}
210+
211+
return $blockData;
212+
}
213+
214+
/**
215+
* Create and return new default purifier
216+
*
217+
* @param $allowedTags
218+
*
219+
* @return \HTMLPurifier
220+
*/
221+
private function getPurifier($allowedTags)
222+
{
223+
$sanitizer = clone $this->sanitizer;
224+
$sanitizer->set('HTML.Allowed', $allowedTags);
225+
226+
$purifier = new \HTMLPurifier($sanitizer);
227+
228+
return $purifier;
229+
}
230+
}

0 commit comments

Comments
 (0)