1: <?php
2:
3: require('qcubed.inc.php');
4: require(__INCLUDES__ . '/codegen/QCodeGen.class.php');
5:
6: function jq_indent ($strText, $intCount, $blnComment = false) {
7: $strTabs = str_repeat("\t", $intCount);
8: if ($blnComment) {
9: $strTabs .= ' * ';
10: }
11: $strRet = preg_replace ( '/^/m', $strTabs , $strText);
12: return $strRet;
13: }
14:
15:
16: class JqAttributes {
17: public $name;
18: public $description;
19:
20: public function __construct($origName, $description) {
21: $this->name = $origName;
22:
23: $html = new \Html2Text\Html2Text($description);
24: $description = $html->getText();
25:
26: $description = str_replace(" \t", "\t", $description);
27: $this->description = $description;
28: }
29: }
30:
31: class Option extends JqAttributes {
32: public $type;
33: public $phpType;
34: public $defaultValue = null;
35: public $propName;
36: public $varName;
37: public $phpQType;
38:
39: static public function php_type($jsType) {
40: $jsType = strtolower($jsType);
41: $jsType = preg_replace('/\([^\)]*\)/', '', $jsType);
42: if (strchr($jsType, ',')) return 'mixed';
43: if (strchr($jsType, ' or ')) return 'mixed';
44: if (stripos($jsType, 'array') === 0) return 'array';
45: switch ($jsType) {
46: case 'mixed': return 'mixed';
47: case 'boolean': return 'boolean';
48: case 'boolean[]': return 'boolean[]';
49: case 'string': return 'string';
50: case 'string[]': return 'string[]';
51: case 'object': return 'mixed';
52: case 'object[]': return 'object[]';
53: case 'selector': return 'mixed';
54: case 'int': return 'integer';
55: case 'int[]': return 'int[]';
56: case 'integer': return 'integer';
57: case 'integer[]': return 'int[]';
58: case 'number': return 'integer';
59: case 'number[]': return 'int[]';
60: case 'double': return 'float';
61: case 'double[]': return 'float[]';
62: case 'float': return 'float';
63: case 'float[]': return 'float[]';
64: case 'date': return 'QDateTime';
65: case 'date[]': return 'QDateTime[]';
66: case 'options': return 'array';
67: case 'array[]': return 'array[]';
68: default: return 'QJsClosure';
69: }
70: }
71:
72: static public function php_qtype($phpType) {
73: $phpType = str_replace('[]', '', $phpType);
74: switch ($phpType) {
75: case 'boolean': return 'QType::Boolean';
76: case 'string': return 'QType::String';
77: case 'mixed': return null;
78: case 'integer': return 'QType::Integer';
79: case 'double': return 'QType::Float';
80: case 'array': return 'QType::ArrayType';
81: case 'QDateTime': return 'QType::DateTime';
82: default: return "'".$phpType."'";
83: }
84: }
85:
86: static public function php_type_prefix($phpType) {
87: $phpType = str_replace('[]', '', $phpType);
88: switch ($phpType) {
89: case 'boolean': return 'bln';
90: case 'string': return 'str';
91: case 'mixed': return 'mix';
92: case 'int': return 'int';
93: case 'integer': return 'int';
94: case 'double': return 'flt';
95: case 'array': return 'arr';
96: case 'QDateTime': return 'dtt';
97: default: return 'mix';
98: }
99: }
100:
101: static public function php_type_suffix($phpType) {
102: if (strpos($phpType, '[]') !== false)
103: return 'Array';
104: return '';
105: }
106:
107: static public function php_value($jsValue) {
108:
109: $jsValue = trim($jsValue);
110: if (!$jsValue)
111: return null;
112: if ($jsValue[0] == '{') {
113: $str = str_replace('{', 'array(', $jsValue);
114: $str = str_replace('}', ')', $str);
115: $str = str_replace(':', '=>', $str);
116: return $str;
117: }
118: if ($jsValue[0] == '[') {
119: $str = str_replace('[', 'array(', $jsValue);
120: $str = str_replace(']', ')', $str);
121: return $str;
122: }
123: if (substr ($jsValue, 0, 4) == 'none') {
124: return null;
125: }
126:
127: try {
128:
129:
130: if (@eval($jsValue. ';') === false) {
131: return null;
132:
133: }
134: } catch (exception $ex) {
135:
136: throw $ex;
137: }
138: return $jsValue;
139: }
140:
141:
142: public function __construct($propName, $origName, $jsType, $defaultValue, $description, $phpType = null) {
143: parent::__construct($origName, $description);
144: $this->type = $jsType;
145: if ($defaultValue !== null)
146: $this->defaultValue = self::php_value($defaultValue);
147:
148: $this->propName = ucfirst($propName);
149: if (($origName === 'dateFormat' ||
150: $origName === 'dateTimeFomat' ||
151: $origName ==='text')
152: && $propName === $origName)
153: $this->propName = 'Jq'.$this->propName;
154:
155: $this->setPhpType($phpType);
156: }
157:
158: public function setPhpType($phpType = null) {
159: $this->phpType = $phpType == null ? self::php_type($this->type) : $phpType;
160: $suffix = self::php_type_suffix($this->phpType);
161: if ($suffix && strrpos($this->propName, $suffix) !== strlen($this->propName) - strlen($suffix)) {
162:
163: $this->propName .= $suffix;
164: }
165: $this->varName = self::php_type_prefix($this->phpType) . $this->propName;
166: $this->phpQType = self::php_qtype($this->phpType);
167: }
168: }
169:
170: class Event extends Option
171: {
172: public $eventClassName;
173: public $eventName;
174: public $arrArgs;
175:
176: public function __construct($strQcClass, $name, $origName, $jsType, $description, $phpType = null) {
177: parent::__construct($name, $origName, $jsType, 'null', $description, $phpType);
178:
179: if (strpos($name, 'on') === 0) {
180: $name = substr($name, 2);
181: }
182: if (stripos($jsType, 'function') === 0) {
183: $subject = substr($jsType, 8);
184: $subject = trim($subject, '()');
185: $this->arrArgs = array();
186: foreach (explode(',', $subject) as $arg) {
187: $arg = trim($arg);
188: $arg = preg_replace('/.*\s/', '', $arg);
189: $this->arrArgs[] = $arg;
190: }
191:
192: $this->eventName = $strQcClass . '_' . $name;
193: } else {
194: $this->eventName = $jsType;
195: }
196: $this->eventClassName = $strQcClass . '_' . $name . 'Event';
197: }
198: }
199:
200: class Method extends JqAttributes {
201: public $signature;
202: public $call;
203: public $phpSignature;
204: public $requiredArgs = array();
205: public $optionalArgs = array();
206:
207: public function __construct($name, $origName, $signature, $description) {
208: parent::__construct($origName, $description);
209: $this->name = ucfirst($name);
210: $signature = str_replace("\n", '', $signature);
211: $this->signature = $signature;
212:
213: $this->phpSignature = ucfirst($name).'(';
214: $this->call = preg_replace('/(.*)\(.*/', '$1', $signature);
215: $args = explode(',', preg_replace('/.*\((.*)\)/', '$1', $signature));
216: for ($i = 0, $cnt = count($args); $i < $cnt; ++$i) {
217: $arg = trim($args[$i]);
218: if (!$arg)
219: continue;
220: if ($arg{0} == '"') {
221:
222: $this->requiredArgs[] = $arg;
223: continue;
224: } else if ($i == 0) {
225: $this->requiredArgs[] = '"'.$origName.'"';
226: }
227: if ($arg{0} == '[') {
228:
229: $arg = trim($arg, '[] ');
230: $this->phpSignature .= '$'.$arg.' = null';
231: $this->optionalArgs[] = '$'.$arg;
232: }
233: elseif ($arg{strlen($arg) - 1} == '[') {
234:
235:
236: $arg = trim($arg, '[] ');
237: $this->phpSignature .= '$'.$arg.' = null';
238: $this->optionalArgs[] = '$'.$arg;
239: break;
240: }
241: else {
242: $this->phpSignature .= '$'.$arg;
243: $this->requiredArgs[] = '$'.$arg;
244: }
245: if ($i < $cnt - 1) {
246: $this->phpSignature .= ', ';
247: }
248: }
249: $this->phpSignature .= ')';
250: if (!$this->requiredArgs) {
251: $this->requiredArgs[] = '"'.$origName.'"';
252: }
253: }
254: }
255:
256: class JqDoc {
257: public $strJqClass;
258: public $strJqSetupFunc;
259: public $strQcClass;
260: public $strQcBaseClass;
261: public $strAbstract = '';
262: public $options = array();
263: public $methods = array();
264: public $events = array();
265: public $descriptionLine = 75;
266: public $hasDisabledProperty = true;
267: protected $names = array();
268:
269: protected function reset_names() {
270: $this->names = array();
271: }
272:
273: protected function has_name($name) {
274: return array_key_exists($name, $this->names);
275: }
276:
277: protected function add_name($name) {
278: $this->names[$name] = $name;
279: }
280:
281: protected function unique_name($name) {
282: $i = 1;
283: $unique_name = $name;
284: while ($this->has_name($unique_name)) {
285: $unique_name = $name.$i;
286: ++$i;
287: }
288: $this->add_name($unique_name);
289: return $unique_name;
290: }
291:
292: public function __construct($strJqClass = null, $strJqSetupFunc = null, $strQcClass = null, $strQcBaseClass = 'QPanel')
293: {
294: $this->strJqClass = $strJqClass;
295:
296: if ($strJqSetupFunc === null) {
297: if ($this->strJqClass !== null)
298: $this->strJqSetupFunc = strtolower($this->strJqClass);
299: } else {
300: $this->strJqSetupFunc = $strJqSetupFunc;
301: }
302:
303: if ($strQcClass === null) {
304: if ($this->strJqClass !== null)
305: $this->strQcClass = 'Q'.$this->strJqClass;
306: } else {
307: $this->strQcClass = $strQcClass;
308: }
309:
310: $this->strQcBaseClass = $strQcBaseClass;
311:
312: $r = new ReflectionClass($this->strQcBaseClass);
313: if ($r->isAbstract()) {
314: $this->strAbstract = 'abstract ';
315: }
316: }
317: }
318:
319: class JqControlGen extends QCodeGenBase {
320: protected $intDatabaseIndex = 1;
321:
322: public function __construct() {
323: QCodeGen::$TemplateEscapeBegin = '<%';
324: QCodeGen::$TemplateEscapeEnd = '%>';
325: QCodeGen::$TemplateEscapeBeginLength = strlen(QCodeGen::$TemplateEscapeBegin);
326: QCodeGen::$TemplateEscapeEndLength = strlen(QCodeGen::$TemplateEscapeEnd);
327: }
328:
329: 330: 331: 332: 333:
334: public function GenerateControl($objJqDoc, $strOutDirControls, $strOutDirControlsBase) {
335: $mixArgumentArray = array('objJqDoc' => $objJqDoc);
336: $strResult = $this->EvaluatePHP(dirname(__FILE__) . '/jq_control.tpl.php', $mixArgumentArray);
337: $strOutFileName = $strOutDirControlsBase . '/'.$objJqDoc->strQcClass . 'Gen.class.php';
338: file_put_contents($strOutFileName, $strResult);
339:
340: $strOutFileName = $strOutDirControlsBase . '/' . $objJqDoc->strQcClass . 'Base.class.php';
341: if (!file_exists($strOutFileName)) {
342: $strEmpty = "<?php\n\tclass ".$objJqDoc->strQcClass."Base extends ".$objJqDoc->strQcClass."Gen\n\t{\n\t}\n?>";
343: file_put_contents($strOutFileName, $strEmpty);
344: }
345:
346: $strOutFileName = $strOutDirControls . '/' . $objJqDoc->strQcClass . '.class.php';
347: if (!file_exists($strOutFileName)) {
348: $strEmpty = "<?php\n\tclass ".$objJqDoc->strQcClass." extends ".$objJqDoc->strQcClass."Base\n\t{\n\t}\n?>";
349: file_put_contents($strOutFileName, $strEmpty);
350: }
351:
352: echo "Generated class: " . $objJqDoc->strQcClass . "<br>";
353: }
354: }