├── images ├── add.png ├── del.png ├── delete.png ├── index.gif ├── info.png ├── info_2.png ├── info_8.png ├── plus.png ├── bg_body.gif ├── info_12.png ├── info_17.png ├── plus_up.png ├── bg_footer.gif ├── bg_header.gif ├── plus_down.png ├── sides_top.gif ├── corners_left.png ├── corners_right.png └── corners_bottom.gif ├── file.php ├── constants.php ├── creator.css ├── post_parser.php ├── functions.php ├── create_modx.php ├── mod_parser.php ├── parser_outdata.php ├── index.php ├── modx_parser.php ├── license.txt ├── template.php └── modx_functions.js /images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/add.png -------------------------------------------------------------------------------- /images/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/del.png -------------------------------------------------------------------------------- /images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/delete.png -------------------------------------------------------------------------------- /images/index.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/index.gif -------------------------------------------------------------------------------- /images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/info.png -------------------------------------------------------------------------------- /images/info_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/info_2.png -------------------------------------------------------------------------------- /images/info_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/info_8.png -------------------------------------------------------------------------------- /images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/plus.png -------------------------------------------------------------------------------- /images/bg_body.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/bg_body.gif -------------------------------------------------------------------------------- /images/info_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/info_12.png -------------------------------------------------------------------------------- /images/info_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/info_17.png -------------------------------------------------------------------------------- /images/plus_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/plus_up.png -------------------------------------------------------------------------------- /images/bg_footer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/bg_footer.gif -------------------------------------------------------------------------------- /images/bg_header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/bg_header.gif -------------------------------------------------------------------------------- /images/plus_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/plus_down.png -------------------------------------------------------------------------------- /images/sides_top.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/sides_top.gif -------------------------------------------------------------------------------- /images/corners_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/corners_left.png -------------------------------------------------------------------------------- /images/corners_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/corners_right.png -------------------------------------------------------------------------------- /images/corners_bottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpBB/modx_creator_offline/master/images/corners_bottom.gif -------------------------------------------------------------------------------- /file.php: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /constants.php: -------------------------------------------------------------------------------- 1 | 'Abkhazian', 45 | 'aa' => 'Afar', 46 | 'af' => 'Afrikaans', 47 | 'sq' => 'Albanian', 48 | 'am' => 'Amharic', 49 | 'ar' => 'Arabic', 50 | 'hy' => 'Armenian', 51 | 'as' => 'Assamese', 52 | 'ay' => 'Aymara', 53 | 'az' => 'Azerbaijani', 54 | 'ba' => 'Bashkir', 55 | 'eu' => 'Basque', 56 | 'bn' => 'Bengali', 57 | 'dz' => 'Bhutani', 58 | 'bh' => 'Bihari', 59 | 'bi' => 'Bislama', 60 | 'br' => 'Breton', 61 | 'bg' => 'Bulgarian', 62 | 'my' => 'Burmese', 63 | 'be' => 'Byelorussian', 64 | 'km' => 'Cambodian', 65 | 'ca' => 'Catalan', 66 | 'zh' => 'Chinese', 67 | 'co' => 'Corsican', 68 | 'hr' => 'Croatian', 69 | 'cs' => 'Czech', 70 | 'da' => 'Danish', 71 | 'nl' => 'Dutch', 72 | 'en' => 'English', 73 | 'eo' => 'Esperanto', 74 | 'et' => 'Estonian', 75 | 'fo' => 'Faeroese', 76 | 'fj' => 'Fiji', 77 | 'fi' => 'Finnish', 78 | 'fr' => 'French', 79 | 'fy' => 'Frisian', 80 | 'gl' => 'Galician', 81 | 'ka' => 'Georgian', 82 | 'de' => 'German', 83 | 'el' => 'Greek', 84 | 'kl' => 'Greenlandic', 85 | 'gn' => 'Guarani', 86 | 'gu' => 'Gujarati', 87 | 'ha' => 'Hausa', 88 | 'iw' => 'Hebrew', 89 | 'hi' => 'Hindi', 90 | 'hu' => 'Hungarian', 91 | 'is' => 'Icelandic', 92 | 'in' => 'Indonesian', 93 | 'ia' => 'Interlingua', 94 | 'ik' => 'Inupiak', 95 | 'ga' => 'Irish', 96 | 'it' => 'Italian', 97 | 'ja' => 'Japanese', 98 | 'jw' => 'Javanese', 99 | 'kn' => 'Kannada', 100 | 'ks' => 'Kashmiri', 101 | 'kk' => 'Kazakh', 102 | 'rw' => 'Kinyarwanda', 103 | 'ky' => 'Kirghiz', 104 | 'rn' => 'Kirundi', 105 | 'ko' => 'Korean', 106 | 'ku' => 'Kurdish', 107 | 'lo' => 'Laothian', 108 | 'la' => 'Latin', 109 | 'lv' => 'Lettish', 110 | 'ln' => 'Lingala', 111 | 'lt' => 'Lithuanian', 112 | 'mk' => 'Macedonian', 113 | 'mg' => 'Malagasy', 114 | 'ms' => 'Malay', 115 | 'ml' => 'Malayalam', 116 | 'mt' => 'Maltese', 117 | 'mi' => 'Maori', 118 | 'mr' => 'Marathi', 119 | 'mo' => 'Moldavian', 120 | 'mn' => 'Mongolian', 121 | 'na' => 'Nauru', 122 | 'ne' => 'Nepali', 123 | 'no' => 'Norwegian', 124 | 'oc' => 'Occitan', 125 | 'or' => 'Oriya', 126 | 'om' => 'Oromo', 127 | 'ps' => 'Pashto', 128 | 'fa' => 'Persian', 129 | 'pl' => 'Polish', 130 | 'pt' => 'Portuguese', 131 | 'pa' => 'Punjabi', 132 | 'qu' => 'Quechua', 133 | 'rm' => 'Rhaeto-Romance', 134 | 'ro' => 'Romanian', 135 | 'ru' => 'Russian', 136 | 'sm' => 'Samoan', 137 | 'sg' => 'Sangro', 138 | 'sa' => 'Sanskrit', 139 | 'gd' => 'Scots Gaelic', 140 | 'sr' => 'Serbian', 141 | 'sh' => 'Serbo-Croatian', 142 | 'st' => 'Sesotho', 143 | 'tn' => 'Setswana', 144 | 'sn' => 'Shona', 145 | 'sd' => 'Sindhi', 146 | 'si' => 'Singhalese', 147 | 'ss' => 'Siswati', 148 | 'sk' => 'Slovak', 149 | 'sl' => 'Slovenian', 150 | 'so' => 'Somali', 151 | 'es' => 'Spanish', 152 | 'su' => 'Sudanese', 153 | 'sw' => 'Swahili', 154 | 'sv' => 'Swedish', 155 | 'tl' => 'Tagalog', 156 | 'tg' => 'Tajik', 157 | 'ta' => 'Tamil', 158 | 'tt' => 'Tatar', 159 | 'te' => 'Tegulu', 160 | 'th' => 'Thai', 161 | 'bo' => 'Tibetan', 162 | 'ti' => 'Tigrinya', 163 | 'to' => 'Tonga', 164 | 'ts' => 'Tsonga', 165 | 'tr' => 'Turkish', 166 | 'tk' => 'Turkmen', 167 | 'tw' => 'Twi', 168 | 'uk' => 'Ukrainian', 169 | 'ur' => 'Urdu', 170 | 'uz' => 'Uzbek', 171 | 'vi' => 'Vietnamese', 172 | 'vo' => 'Volapuk', 173 | 'cy' => 'Welsh', 174 | 'wo' => 'Wolof', 175 | 'xh' => 'Xhosa', 176 | 'ji' => 'Yiddish', 177 | 'yo' => 'Yoruba', 178 | 'zu' => 'Zulu', 179 | ); 180 | 181 | ?> 182 | -------------------------------------------------------------------------------- /creator.css: -------------------------------------------------------------------------------- 1 | /* css for the MODX creator */ 2 | /* Mostly copied from http:www.phpbb.com */ 3 | body { 4 | /* Text-Sizing with ems: http://www.clagnut.com/blog/348/ */ 5 | font-family: Verdana, Helvetica, Arial, sans-serif; 6 | color: #536482; 7 | background-color: #ACA8A1; 8 | font-size: 62.5%; /* This sets the default font size to be equivalent to 10px */ 9 | margin: 0; 10 | text-align: center; 11 | } 12 | 13 | body div.header { 14 | background-repeat: no-repeat; 15 | width: 850px; 16 | height: 129px; 17 | float: left; 18 | margin-top: 21px; 19 | } 20 | 21 | body div.header h1 { 22 | margin: 0; 23 | } 24 | 25 | body.modx-creator .panel { 26 | margin-bottom: 10px !important; 27 | } 28 | 29 | body.modx-creator fieldset.modx-level1 { 30 | background-color: #FFFFFF; 31 | padding: 10px; 32 | margin-top: 5px; 33 | margin-bottom: 10px; 34 | } 35 | 36 | body.modx-creator fieldset.modx-level2 { 37 | padding: 5px; 38 | background-color: #F5F8FB; 39 | border: 1px solid #E5E8EC; 40 | margin-top: 5px; 41 | margin-bottom: 10px; 42 | font-size: 1em !important; 43 | } 44 | 45 | body.modx-creator fieldset.file-edit dt { 46 | width: 19em !important; 47 | } 48 | 49 | body.modx-creator fieldset.file-edit dd { 50 | margin-left: 20em !important; 51 | } 52 | 53 | body.modx-creator .sub-legend, body.modx .main-legend { 54 | color: #28313F; 55 | } 56 | 57 | body.modx-creator .main-legend { 58 | font-size: 1.1em; 59 | } 60 | 61 | body.modx-creator .adjusted-size { 62 | font-size: 1.1em !important; 63 | } 64 | 65 | body.modx-creator .copy-to { 66 | margin-bottom: 5px; 67 | } 68 | 69 | body.modx-creator img.sign, body.modx-creator img.action-image { 70 | vertical-align: middle !important; 71 | margin-right: 3px; 72 | height:14px; 73 | width:14px; 74 | } 75 | 76 | body.modx-creator img.action-image { 77 | cursor: pointer; 78 | } 79 | 80 | body.modx-creator div.right-tools { 81 | float: left; 82 | width: 14px; 83 | clear: right; 84 | } 85 | 86 | body.modx-creator div.right-tools img { 87 | margin-bottom: 2px; 88 | } 89 | 90 | body.modx-creator textarea.right-tools { 91 | float: left; 92 | margin-bottom: 3px; 93 | } 94 | 95 | dd label { 96 | white-space: nowrap; 97 | color: #333; 98 | } 99 | 100 | dd input, dd textarea { 101 | margin-right: 3px; 102 | } 103 | 104 | dd select { 105 | width: auto; 106 | } 107 | 108 | dd textarea { 109 | width: 85%; 110 | } 111 | 112 | dt label { 113 | font-weight: bold; 114 | text-align: left; 115 | } 116 | 117 | fieldset dl { 118 | padding: 4px 0; 119 | } 120 | 121 | fieldset dt { 122 | float: left; 123 | width: 40%; 124 | text-align: left; 125 | display: block; 126 | } 127 | 128 | fieldset dd { 129 | margin-left: 41%; 130 | vertical-align: top; 131 | margin-bottom: 3px; 132 | } 133 | 134 | fieldset dl:hover dt label { 135 | color: #000000; 136 | } 137 | 138 | fieldset.fields2 dl:hover dt label { 139 | color: inherit; 140 | } 141 | 142 | fieldset.fields2 dt { 143 | width: 15em; 144 | border-right-width: 0; 145 | } 146 | 147 | fieldset.fields2 dd { 148 | margin-left: 16em; 149 | border-left-width: 0; 150 | } 151 | 152 | fieldset.submit-buttons { 153 | text-align: center; 154 | vertical-align: middle; 155 | margin: 0 0; 156 | } 157 | 158 | fieldset { 159 | border: none; 160 | } 161 | 162 | h1 { 163 | font-size: 20px; 164 | text-align: center; 165 | margin-bottom: 0; 166 | padding: 10px 0 5px 0; 167 | } 168 | 169 | h3 { 170 | color: #115098; 171 | font-family: Arial, Helvetica, sans-serif; 172 | font-weight: bold; 173 | border-bottom: 1px solid #CCCCCC; 174 | margin-bottom: 3px; 175 | padding-bottom: 2px; 176 | font-size: 1.3em; 177 | margin-top: 0; 178 | } 179 | 180 | hr.dashed { 181 | border-top: 1px dashed #CCCCCC; 182 | margin: 10px 0; 183 | } 184 | 185 | input.inputbox { width: 85%; } 186 | input.medium { width: 50%; } 187 | input.narrow { width: 25%; } 188 | input.tiny { width: 125px; } 189 | 190 | input.button1, input.button2 { 191 | font-size: 1em; 192 | } 193 | 194 | input.button1, input.button2 { 195 | width: auto !important; 196 | padding-top: 1px; 197 | padding-bottom: 1px; 198 | font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; 199 | color: #000; 200 | background: #FAFAFA none repeat-x top; 201 | } 202 | 203 | input.button1 { 204 | font-weight: bold; 205 | border: 1px solid #666666; 206 | } 207 | 208 | label { 209 | cursor: default; 210 | padding-right: 5px; 211 | color: #333; 212 | } 213 | 214 | label input { 215 | vertical-align: middle; 216 | } 217 | 218 | label img { 219 | vertical-align: middle; 220 | } 221 | 222 | span.side-left, span.side-right { 223 | display: block; 224 | width: 20px; 225 | height: 150px; 226 | background: url("./images/sides_top.gif") no-repeat; 227 | } 228 | 229 | span.side-left { 230 | background-position: 0 0; 231 | float: left; 232 | margin-right: 10px; 233 | } 234 | 235 | span.side-right { 236 | background-position: 100% 0; 237 | float: right; 238 | } 239 | 240 | span.corners-top, span.corners-bottom, span.corners-top span, span.corners-bottom span { 241 | font-size: 1px; 242 | line-height: 1px; 243 | display: block; 244 | height: 5px; 245 | background-repeat: no-repeat; 246 | } 247 | 248 | span.corners-top { 249 | background-image: url("./images/corners_left.png"); 250 | background-position: 0 0; 251 | margin: 0 -5px; 252 | } 253 | 254 | span.corners-top span { 255 | background-image: url("./images/corners_right.png"); 256 | background-position: 100% 0; 257 | } 258 | 259 | span.corners-bottom { 260 | background-image: url("./images/corners_left.png"); 261 | background-position: 0 100%; 262 | margin: 0 -5px; 263 | clear: both; 264 | } 265 | 266 | span.corners-bottom span { 267 | background-image: url("./images/corners_right.png"); 268 | background-position: 100% 100%; 269 | } 270 | 271 | span.fcorners-bottom, span.fcorners-bottom span { 272 | font-size: 1px; 273 | line-height: 1px; 274 | display: block; 275 | height: 20px; 276 | background-repeat: no-repeat; 277 | background-image: url("./images/corners_bottom.gif"); 278 | margin: 0; 279 | } 280 | 281 | span.fcorners-bottom { 282 | background-position: 0 0; 283 | } 284 | 285 | span.fcorners-bottom span { 286 | background-position: 100% -20px; 287 | } 288 | 289 | textarea.inputbox { 290 | width: 85%; 291 | } 292 | 293 | #wrap { 294 | width: 910px; 295 | background: #FFFFFF url("./images/bg_body.gif") repeat-y 0 0; 296 | margin: 10px auto; 297 | text-align: left; 298 | padding: 0; 299 | } 300 | 301 | #page-body { 302 | margin: 40px 30px; 303 | clear: both; 304 | } 305 | 306 | #page-footer { 307 | background: url("./images/bg_footer.gif") repeat-x 0 100%; 308 | margin-top: -20px; 309 | clear: both; 310 | } 311 | 312 | #page-header { 313 | background: url("./images/bg_header.gif") repeat-x 0 0; 314 | height: 150px; 315 | clear: both; 316 | } 317 | 318 | .autowidth { 319 | width: auto !important; 320 | } 321 | 322 | /* Input field styles 323 | ---------------------------------------- */ 324 | .inputbox { 325 | background-color: #FFFFFF; 326 | border: 1px solid #c0c0c0; 327 | color: #333333; 328 | padding: 2px; 329 | cursor: text; 330 | } 331 | 332 | .inputbox:hover { 333 | border: 1px solid #eaeaea; 334 | } 335 | 336 | .inputbox:focus { 337 | border: 1px solid #eaeaea; 338 | color: #4b4b4b; 339 | } 340 | 341 | .panel { 342 | background-color: #ECF1F3; 343 | color: #28313F; 344 | margin-bottom: 10px !important; 345 | padding: 0 10px; 346 | } 347 | 348 | .panel span.corners-top, .panel span.corners-bottom { 349 | margin: 0 -10px; 350 | } 351 | 352 | #error-div { 353 | color: #000000; 354 | background-color: #CC0000; 355 | font-size: 1.3em; 356 | padding: 4px; 357 | margin-left: 4px; 358 | } 359 | 360 | #warning-div{ 361 | color: #000000; 362 | background-color: #F9F100; 363 | font-size: 1.3em; 364 | padding: 4px; 365 | margin-left: 4px; 366 | } 367 | 368 | .error-dl { 369 | background-color: #CC0000; 370 | padding-left: 4px; 371 | } 372 | 373 | .warning-dl { 374 | background: #F9F100; 375 | padding-left: 4px; 376 | } 377 | -------------------------------------------------------------------------------- /post_parser.php: -------------------------------------------------------------------------------- 1 | cnt_action = -1; 49 | $this->cnt_edit = -1; 50 | $this->cnt_open = -1; 51 | 52 | // The strings 53 | $this->mod_version = (isset($post_data['version'])) ? stripslashes(trim($post_data['version'])) : ''; 54 | $this->target_version = (isset($post_data['target'])) ? stripslashes(trim($post_data['target'])) : ''; 55 | $this->installation_level = (isset($post_data['install-level'])) ? stripslashes(trim($post_data['install-level'])) : ''; 56 | $this->installation_time = (isset($post_data['install-time'])) ? intval(trim($post_data['install-time'])) : 0; 57 | $this->installation_time = (!empty($this->installation_time)) ? $this->installation_time * 60 : 0; 58 | $this->license = (isset($post_data['license'])) ? stripslashes(trim($post_data['license'])) : ''; 59 | $this->php_installer = (isset($post_data['php-installer'])) ? stripslashes(trim($post_data['php-installer'])) : ''; 60 | 61 | $this->github = (isset($post_data['github'])) ? trim($post_data['github']) : ''; 62 | 63 | // Arrays 64 | $this->title = (isset($post_data['title'])) ? $this->modx_stripslashes($post_data['title']) : array(); 65 | $this->title = $this->int_keys($this->title); 66 | 67 | $this->description = (isset($post_data['desc'])) ? $this->int_keys($this->modx_stripslashes($post_data['desc'])) : array(); 68 | $this->description = $this->int_keys($this->description); 69 | 70 | $this->author_notes = (isset($post_data['notes'])) ? $this->modx_stripslashes($post_data['notes']) : array(); 71 | $this->author_notes = $this->int_keys($this->author_notes); 72 | 73 | $this->diy = (isset($post_data['diy'])) ? $this->modx_stripslashes($post_data['diy']) : array(); 74 | $this->diy = $this->int_keys($this->diy); 75 | 76 | $this->copy = (isset($post_data['copy'])) ? $this->modx_stripslashes($post_data['copy']) : array(); 77 | $this->copy = $this->int_keys($this->copy); 78 | 79 | $this->delete = (isset($post_data['delete'])) ? $this->modx_stripslashes($post_data['delete']) : array(); 80 | $this->delete = $this->int_keys($this->delete); 81 | 82 | $tmp_arr = (isset($post_data['meta'])) ? $this->modx_stripslashes($post_data['meta']) : array(); 83 | foreach ($tmp_arr as $value) 84 | { 85 | // We don't want to double the meta tag from this app. 86 | if (isset($value['content']) && $value['content'] != META) 87 | { 88 | $this->meta[] = $value; 89 | } 90 | } 91 | 92 | 93 | $tmp_arr = (isset($post_data['modx'])) ? $this->modx_stripslashes($post_data['modx']) : array(); 94 | foreach ($tmp_arr as $value) 95 | { 96 | foreach ($value as $key2 => $value2) 97 | { 98 | if ($key2 == 'file') 99 | { 100 | $this->cnt_open++; 101 | $this->cnt_edit = 0; 102 | $this->action[$this->cnt_open]['file'] = $value2; 103 | } 104 | else 105 | { 106 | $this->cnt_edit++; 107 | $this->cnt_action = -1; 108 | foreach ($value2 as $value3) 109 | { 110 | $value3['data'] = (isset($value3['data'])) ? $this->parse_cdata($value3['data']) : ''; 111 | $this->cnt_action++; 112 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action] = array( 113 | 'type' => (isset($value3['type'])) ? $value3['type'] : '', 114 | 'data' => $value3['data'], 115 | ); 116 | if (!empty($value3['lang'])) 117 | { 118 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action]['lang'] = $value3['lang']; 119 | } 120 | } 121 | } 122 | } 123 | } 124 | 125 | $this->author = (isset($post_data['author'])) ? $this->modx_stripslashes($post_data['author']) : array(); 126 | $this->author = $this->int_keys($this->author); 127 | 128 | $this->link = (isset($post_data['links'])) ? $this->modx_stripslashes($post_data['links']) : array(); 129 | $this->link = $this->int_keys($this->link); 130 | 131 | $this->history = (isset($post_data['history'])) ? $this->modx_stripslashes($post_data['history']) : array(); 132 | $this->history = $this->int_keys($this->history); 133 | usort($this->history, array($this, 'version_sort')); 134 | if (isset($post_data['reverse_history'])) 135 | { 136 | $this->history = array_reverse($this->history); 137 | } 138 | 139 | $this->sql = (isset($post_data['sql'])) ? $this->modx_stripslashes($post_data['sql']) : array(); 140 | $this->sql = $this->int_keys($this->sql); 141 | 142 | // We need to set the counters back to zero. 143 | $this->cnt_action = 0; 144 | $this->cnt_author = 0; 145 | $this->cnt_author_notes = 0; 146 | $this->cnt_change = 0; 147 | $this->cnt_changelog = 0; 148 | $this->cnt_copy = 0; 149 | $this->cnt_delete = 0; 150 | $this->cnt_description = 0; 151 | $this->cnt_diy = 0; 152 | $this->cnt_edit = 0; 153 | $this->cnt_history = 0; 154 | $this->cnt_link = 0; 155 | $this->cnt_meta = 0; 156 | $this->cnt_open = 0; 157 | $this->cnt_sql = 0; 158 | $this->cnt_title = 0; 159 | } 160 | 161 | // private functions. 162 | 163 | /** 164 | * version_sort 165 | * 166 | * Callback function to sort the history array. 167 | */ 168 | private function version_sort($a, $b) 169 | { // sorterar ratingen 170 | return (version_compare($a['version'], $b['version'])); 171 | } 172 | 173 | /** 174 | * parse_cdata 175 | * 176 | * Handles edits or finds containing . 177 | * Those will brake the xml if not correctly escaped. 178 | */ 179 | private function parse_cdata($data) 180 | { 181 | $find = array( 182 | '', 184 | '<![CDATA[', 185 | ']]>'); 186 | $replace = array( 187 | '<![CDATA[', 188 | ']]>', 189 | ']]><![CDATA[]]> $value) 227 | { 228 | if (is_array($value)) 229 | { 230 | $this->modx_stripslashes($array[$key]); 231 | } 232 | else 233 | { 234 | $value = str_replace(chr(13), '', $value); 235 | if (STRIP) 236 | { 237 | $array[$key] = stripslashes($value); 238 | } 239 | } 240 | } 241 | return($array); 242 | } 243 | 244 | } 245 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | =') && get_magic_quotes_gpc()) 42 | { 43 | $text = stripslashes($text); 44 | } 45 | */ 46 | 47 | $xml->startElement($name); 48 | if($attributes != false) 49 | { 50 | foreach($attributes as $key => $value) 51 | { 52 | if($value != '') 53 | { 54 | $xml->writeAttribute($key, $value); 55 | } 56 | } 57 | } 58 | if($text != '') 59 | { 60 | if($cdata) 61 | { 62 | $xml->writeCdata($text); 63 | } 64 | else 65 | { 66 | $xml->text($text); 67 | } 68 | } 69 | $xml->endElement(); 70 | } 71 | 72 | /** 73 | * count_rows() 74 | * 75 | * Counts the number of rows needed for '; 422 | $modx_img = 'Inline explain'; 423 | } 424 | else if($value3['type'] != 'comment') 425 | { 426 | $textarea = true; 427 | $modx_input = ''; 428 | if($value3['type'] == 'find') 429 | { 430 | $modx_img = 'Find explain'; 431 | } 432 | else if($value3['type'] == 'remove') 433 | { 434 | $modx_img = 'Find and delete explain'; 435 | } 436 | else 437 | { 438 | $modx_img = 'Action explain'; 439 | } 440 | } 441 | else 442 | { 443 | $textarea = true; 444 | // The comments needs a lang select 445 | $modx_input = ''; 446 | $modx_select = ''; 447 | $modx_img = 'Comment explain'; 448 | } 449 | 450 | $template->assign_block_vars('file_row.edit.action', array( 451 | 'DL_ID' => $dl_id, 452 | 'DT_ID' => $dt_id, 453 | 'DD_ID' => $dd_id, 454 | 'S_TEXTAREA' => $textarea, 455 | 'MODX_INPUT' => $modx_input, 456 | 'MODX_IMG' => $modx_img, 457 | 'MODX_SELECT' => $modx_select, 458 | 'TYPE' => $value3['type'], 459 | )); 460 | } 461 | } 462 | } 463 | } 464 | } 465 | } 466 | 467 | if (($dload || $preview) && empty($error)) 468 | { 469 | include('./create_modx.php'); 470 | } 471 | 472 | $template->assign_vars(array( 473 | 'GITHUB' => $u_github, 474 | 475 | 'INSTALL_LEVEL' => (isset($install_level)) ? $install_level : '', 476 | 'INSTALL_TIME' => (isset($install_time)) ? $install_time : '', 477 | 478 | 'LANG_SELECT' => lang_select(), 479 | 'LICENSE' => (!empty($license)) ? $license : 'http://opensource.org/licenses/gpl-license.php GNU General Public License v2', 480 | 481 | 'MOD_VERSION' => (isset($version)) ? $version : '', 482 | 483 | 'PHP_INSTALLER' => (!empty($php_installer)) ? $php_installer : '', 484 | 'PHPBB_LATEST' => PHPBB_LATEST, 485 | 486 | 'S_ERROR_TITLE' => (isset($error['title'])) ? true : false, 487 | 'S_ERROR_DESC' => (isset($error['desc'])) ? true : false, 488 | 'S_ERROR_VERSION' => (isset($error['version'])) ? true : false, 489 | 'S_ERROR_TARGET' => (isset($error['target'])) ? true : false, 490 | 'S_ERROR_INSTALL_LEVEL' => (isset($error['install_level'])) ? true : false, 491 | 'S_ERROR_INSTALL_TIME' => (isset($error['install_time'])) ? true : false, 492 | 'S_ERROR_AUTHOR' => (isset($error['author'])) ? true : false, 493 | 'S_ERROR_GITHUB' => (isset($error['github'])) ? true : false, 494 | 'S_ERRORS' => (($dload || $preview) && !empty($error)) ? true : false, 495 | 496 | 'S_IS_COPY' => $s_is_copy, 497 | 'S_IS_DELETE' => $s_is_delete, 498 | 'S_IN_MODX_CREATOR' => true, 499 | 'S_SUBMIT' => ($submit) ? true : false, 500 | 501 | 'S_WARNING_TARGET' => (isset($warning['target'])) ? true : false, 502 | 'S_WARNINGS' => (($dload || $preview) && !empty($warning)) ? true : false, 503 | 504 | 'TARGET_VERSION' => (isset($target)) ? $target : '', 505 | )); 506 | 507 | $template->set_filenames(array( 508 | 'body' => 'modx_creator.html', 509 | )); 510 | 511 | $template->display('body'); 512 | -------------------------------------------------------------------------------- /modx_parser.php: -------------------------------------------------------------------------------- 1 | parser = xml_parser_create('UTF-8'); 55 | // Set some parser settings. 56 | xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 57 | xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); 58 | xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1); 59 | xml_parser_set_option($this->parser, XML_OPTION_SKIP_TAGSTART, 0); 60 | 61 | xml_parse_into_struct($this->parser, $modx_data, $modx_arr); 62 | 63 | $modx_size = sizeof($modx_arr); 64 | 65 | // Set some local switches. 66 | $in_mod_version = $in_header = $in_author = $in_history = $in_installation = $in_target = $in_entry = false; 67 | 68 | foreach ($modx_arr as $modx_pos => $modx_row) 69 | { 70 | // The rows gets so long. And this makes the converting easier. :) 71 | $attrs = (isset($modx_row['attributes'])) ? $modx_row['attributes'] : ''; 72 | 73 | switch ($modx_row['tag']) 74 | { 75 | case 'mod': 76 | if ($modx_row['type'] == 'open') 77 | { 78 | $this->used_modx = $this->check_modx_version($attrs['xmlns']); 79 | } 80 | break; 81 | 82 | // header strings 83 | case 'header'; 84 | $in_header = ($modx_row['type'] == 'open') ? true : false; 85 | break; 86 | 87 | case 'level': 88 | $this->installation_level = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 89 | break; 90 | 91 | case 'license': 92 | $this->license = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 93 | break; 94 | 95 | case 'github': 96 | $this->github = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 97 | break; 98 | 99 | case 'time': 100 | $this->installation_time = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 101 | break; 102 | 103 | // Single arrays 104 | case 'author-notes': 105 | $this->author_notes[] = array( 106 | 'lang' => (isset($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 107 | 'note' => (isset($modx_row['value'])) ? $modx_row['value'] : '', 108 | ); 109 | break; 110 | 111 | case 'description': 112 | $this->description[] = array( 113 | 'lang' => (isset($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 114 | 'desc' => (isset($modx_row['value'])) ? $modx_row['value'] : '', 115 | ); 116 | break; 117 | 118 | case 'diy-instructions': 119 | $this->diy[] = array( 120 | 'lang' => (!empty($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 121 | 'diy' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 122 | ); 123 | break; 124 | 125 | case 'copy'; 126 | $this->in_copy = ($modx_row['type'] == 'open') ? true : false; 127 | break; 128 | 129 | case 'delete'; 130 | $this->in_delete = ($modx_row['type'] == 'open') ? true : false; 131 | break; 132 | 133 | case 'file': 134 | if ($this->in_copy) 135 | { 136 | $this->copy[] = array( 137 | 'from' => (!empty($attrs['from'])) ? $attrs['from'] : '', 138 | 'to' => (!empty($attrs['to'])) ? $attrs['to'] : '', 139 | ); 140 | } 141 | else if ($this->in_delete && !empty($attrs['name'])) 142 | { 143 | $this->delete[] = $attrs['name']; 144 | } 145 | break; 146 | 147 | case 'link': 148 | $this->link[] = array( 149 | 'type' => (isset($attrs['type'])) ? $attrs['type'] : '', 150 | 'href' => (isset($attrs['href'])) ? $attrs['href'] : '', 151 | 'lang' => (isset($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 152 | 'realname' => (isset($attrs['realname'])) ? $attrs['realname'] : '', 153 | 'title' => (isset($modx_row['value'])) ? $modx_row['value'] : '', 154 | ); 155 | break; 156 | 157 | case 'meta': 158 | if (isset($attrs['content']) && $attrs['content'] != META) 159 | { 160 | $this->meta[] = array( 161 | 'name' => (isset($attrs['name'])) ? $attrs['name'] : '', 162 | 'content' => $attrs['content'], 163 | ); 164 | } 165 | break; 166 | 167 | case 'php-installer': 168 | $this->php_installer = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 169 | break; 170 | 171 | case 'sql': 172 | $this->sql[] = array( 173 | 'dbms' => (!empty($attrs['dbms'])) ? $attrs['dbms'] : 'sql-parser', 174 | 'query' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 175 | ); 176 | break; 177 | 178 | case 'title': 179 | $this->title[] = array( 180 | 'lang' => (isset($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 181 | 'title' => (isset($modx_row['value'])) ? $modx_row['value'] : '', 182 | ); 183 | break; 184 | 185 | // Author stuff 186 | case 'author': 187 | if ($modx_row['type'] == 'open') 188 | { 189 | $in_author = true; 190 | $this->author[$this->cnt_author] = array(); 191 | } 192 | else if ($modx_row['type'] == 'close') 193 | { 194 | $in_author = false; 195 | $this->cnt_author++; 196 | } 197 | break; 198 | 199 | case 'contributions': 200 | if ($in_author) 201 | { 202 | $this->author[$this->cnt_author]['contributions'][] = array( 203 | 'status' => (isset($attrs['status'])) ? $attrs['status'] : '', 204 | 'from' => (isset($attrs['from'])) ? $attrs['from'] : '', 205 | 'to' => (isset($attrs['to'])) ? $attrs['to'] : '', 206 | 'position' => (isset($attrs['position'])) ? $attrs['position'] : '', 207 | ); 208 | } 209 | break; 210 | 211 | case 'email': 212 | if ($in_author) 213 | { 214 | $this->author[$this->cnt_author]['email'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 215 | } 216 | break; 217 | 218 | case 'homepage': 219 | if ($in_author) 220 | { 221 | $this->author[$this->cnt_author]['homepage'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 222 | } 223 | break; 224 | 225 | case 'realname': 226 | if($in_author) 227 | { 228 | $this->author[$this->cnt_author]['realname'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 229 | } 230 | break; 231 | 232 | case 'username': 233 | if ($in_author) 234 | { 235 | $this->author[$this->cnt_author]['username'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 236 | if (isset($attrs['phpbbcom'])) 237 | { 238 | $this->author[$this->cnt_author]['phpbbcom'] = true; 239 | } 240 | } 241 | break; 242 | 243 | // Version strings 244 | case 'mod-version': 245 | if ($this->used_modx == MODX_10 && $modx_row['type'] == 'open') 246 | { 247 | $in_mod_version = true; 248 | } 249 | else if ($this->used_modx == MODX_10 && $modx_row['type'] == 'close') 250 | { 251 | $this->mod_version = (isset($version_major)) ? $version_major : ''; 252 | $this->mod_version .= (isset($version_minor)) ? '.' . $version_minor : ''; 253 | $this->mod_version .= (isset($version_revision)) ? '.' . $version_revision : ''; 254 | $this->mod_version .= (isset($version_release)) ? '.' . $version_release : ''; 255 | 256 | // Empty these since they are used by others. 257 | $version_major = $version_minor = $version_revision = $version_release = ''; 258 | $in_mod_version = false; 259 | } 260 | else if ($this->used_modx == MODX_12) 261 | { 262 | $this->mod_version = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 263 | } 264 | break; 265 | 266 | case 'major': 267 | $version_major = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 268 | break; 269 | 270 | case 'minor': 271 | $version_minor = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 272 | break; 273 | 274 | case 'release': 275 | $version_release = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 276 | break; 277 | 278 | case 'revision': 279 | $version_revision = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 280 | break; 281 | 282 | case 'target-major': 283 | $version_major = (!empty($modx_row['value'])) ? $modx_row['value'] : ''; 284 | break; 285 | 286 | case 'target-minor': 287 | $version_minor = (!empty($modx_row['value'])) ? $modx_row['value'] : ''; 288 | break; 289 | 290 | case 'target-release': 291 | $version_release = (!empty($modx_row['value'])) ? $modx_row['value'] : ''; 292 | break; 293 | 294 | case 'target-revision': 295 | $version_revision = (!empty($modx_row['value'])) ? $modx_row['value'] : ''; 296 | break; 297 | 298 | case 'target-version': 299 | if ($this->used_modx == MODX_10 && $modx_row['type'] == 'open') 300 | { 301 | $in_target = true; 302 | } 303 | else if ($this->used_modx == MODX_10 && $modx_row['type'] == 'close') 304 | { 305 | $this->target_version = (isset($version_major)) ? $version_major : ''; 306 | $this->target_version .= (isset($version_minor)) ? '.' . $version_minor : ''; 307 | $this->target_version .= (isset($version_revision)) ? '.' . $version_revision : ''; 308 | $this->target_version .= (isset($version_release)) ? '.' . $version_release : ''; 309 | 310 | $version_major = $version_minor = $version_revision = $version_release = ''; 311 | $in_target = false; 312 | } 313 | else if ($this->used_modx == MODX_12) 314 | { 315 | $this->target_version = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 316 | } 317 | break; 318 | 319 | // History 320 | case 'change': 321 | if ($in_entry) 322 | { 323 | $this->history[$this->cnt_history]['changelog'][] = array( 324 | 'lang' => $this->lang, 325 | 'change' => (isset($modx_row['value'])) ? $modx_row['value'] : '', 326 | ); 327 | } 328 | break; 329 | 330 | case 'changelog': 331 | if ($in_entry) 332 | { 333 | if ($modx_row['type'] == 'open') 334 | { 335 | $this->lang = (isset($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en'; 336 | } 337 | } 338 | break; 339 | 340 | case 'date': 341 | if($in_entry) 342 | { 343 | $this->history[$this->cnt_history]['date'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 344 | } 345 | break; 346 | 347 | case 'entry': 348 | if ($modx_row['type'] == 'open') 349 | { 350 | $this->history[$this->cnt_history] = array(); 351 | $in_entry = true; 352 | } 353 | else 354 | { 355 | $this->cnt_history++; 356 | $this->cnt_changelog = 0; 357 | $in_entry = false; 358 | } 359 | break; 360 | 361 | case 'rev-version': 362 | if($in_entry) 363 | { 364 | if ($this->used_modx == MODX_10 && $modx_row['type'] == 'close') 365 | { 366 | $this->history[$this->cnt_history]['version'] = (isset($version_major)) ? $version_major : ''; 367 | $this->history[$this->cnt_history]['version'] .= (isset($version_minor)) ? '.' . $version_minor : ''; 368 | $this->history[$this->cnt_history]['version'] .= (isset($version_revision)) ? '.' . $version_revision : ''; 369 | $this->history[$this->cnt_history]['version'] .= (isset($version_release)) ? '.' . $version_release : ''; 370 | 371 | $version_major = $version_minor = $version_revision = $version_release = ''; 372 | } 373 | else if ($this->used_modx == MODX_12) 374 | { 375 | $this->history[$this->cnt_history]['version'] = (isset($modx_row['value'])) ? $modx_row['value'] : ''; 376 | } 377 | } 378 | break; 379 | 380 | // The damage part 381 | case 'action': 382 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 383 | 'type' => (isset($attrs['type'])) ? $attrs['type'] : '', 384 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 385 | ); 386 | break; 387 | 388 | case 'comment': 389 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 390 | 'lang' => (!empty($attrs['lang']) && $this->check_iso_lang($attrs['lang'])) ? $attrs['lang'] : 'en', 391 | 'type' => 'comment', 392 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 393 | ); 394 | break; 395 | 396 | case 'edit': 397 | if ($modx_row['type'] == 'open') 398 | { 399 | $this->action[$this->cnt_open][$this->cnt_edit] = array(); 400 | } 401 | else 402 | { 403 | $this->cnt_edit++; 404 | $this->cnt_action = 0; 405 | } 406 | break; 407 | 408 | case 'find': 409 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 410 | 'type' => 'find', 411 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 412 | ); 413 | break; 414 | 415 | case 'remove': 416 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 417 | 'type' => 'remove', 418 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 419 | ); 420 | break; 421 | 422 | case 'inline-action': 423 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 424 | 'type' => (isset($attrs['type'])) ? 'inline-' . $attrs['type'] : '', 425 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 426 | ); 427 | break; 428 | 429 | case 'inline-find': 430 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 431 | 'type' => 'inline-find', 432 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 433 | ); 434 | break; 435 | 436 | case 'inline-remove': 437 | $this->action[$this->cnt_open][$this->cnt_edit][$this->cnt_action++] = array( 438 | 'type' => 'inline-remove', 439 | 'data' => (!empty($modx_row['value'])) ? $modx_row['value'] : '', 440 | ); 441 | break; 442 | 443 | case 'open': 444 | if ($modx_row['type'] == 'open') 445 | { 446 | $this->action[$this->cnt_open] = array( 447 | 'file' => (isset($attrs['src'])) ? $attrs['src'] : '', 448 | ); 449 | } 450 | else 451 | { 452 | $this->cnt_open++; 453 | $this->cnt_edit = 0; 454 | } 455 | break; 456 | } 457 | } 458 | 459 | xml_parser_free($this->parser); 460 | 461 | // We need to set the counters back to zero. 462 | $this->cnt_action = 0; 463 | $this->cnt_author = 0; 464 | $this->cnt_author_notes = 0; 465 | $this->cnt_change = 0; 466 | $this->cnt_changelog = 0; 467 | $this->cnt_copy = 0; 468 | $this->cnt_delete = 0; 469 | $this->cnt_description = 0; 470 | $this->cnt_diy = 0; 471 | $this->cnt_edit = 0; 472 | $this->cnt_history = 0; 473 | $this->cnt_link = 0; 474 | $this->cnt_meta = 0; 475 | $this->cnt_open = 0; 476 | $this->cnt_sql = 0; 477 | $this->cnt_title = 0; 478 | } 479 | 480 | // Private functions. 481 | /** 482 | * Checks the MODX version. There are differences in the version strings from 1.0.x to 1.2.x. 483 | */ 484 | private function check_modx_version($version_string) 485 | { 486 | if (strpos($version_string, 'modx-1.0') !== false) 487 | { 488 | return(MODX_10); 489 | } 490 | else 491 | { 492 | return(MODX_12); 493 | } 494 | } 495 | 496 | /** 497 | * check_iso_lang() 498 | * 499 | * Checks if the submitted lang code is valid. 500 | * @param $lang, string containing the language code 501 | * 502 | * @return bool, true if the code is valid. 503 | */ 504 | private function check_iso_lang($lang) 505 | { 506 | // Don't bother with dialects. 507 | $lang = substr($lang, 0, 2); 508 | 509 | $lang_codes = array('ab', 'aa', 'af', 'sq', 'am', 'ar', 'hy', 'as', 'ay', 'az', 'ba', 'eu', 'bn', 'dz', 'bh', 'bi', 'br', 'bg', 'my', 'be', 'km', 'ca', 'zh', 'co', 'hr', 'cs', 'da', 'nl', 'en', 'eo', 'et', 'fo', 'fj', 'fi', 'fr', 'fy', 'gl', 'ka', 'de', 'el', 'kl', 'gn', 'gu', 'ha', 'iw', 'hi', 'hu', 'is', 'in', 'ia', 'ik', 'ga', 'it', 'ja', 'jw', 'kn', 'ks', 'kk', 'rw', 'ky', 'rn', 'ko', 'ku', 'lo', 'la', 'lv', 'ln', 'lt', 'mk', 'mg', 'ms', 'ml', 'mt', 'mi', 'mr', 'mo', 'mn', 'na', 'ne', 'no', 'oc', 'or', 'om', 'ps', 'fa', 'pl', 'pt', 'pa', 'qu', 'rm', 'ro', 'ru', 'sm', 'sg', 'sa', 'gd', 'sr', 'sh', 'st', 'tn', 'sn', 'sd', 'si', 'ss', 'sk', 'sl', 'so', 'es', 'su', 'sw', 'sv', 'tl', 'tg', 'ta', 'tt', 'te', 'th', 'bo', 'ti', 'to', 'ts', 'tr', 'tk', 'tw', 'uk', 'ur', 'uz', 'vi', 'vo', 'cy', 'wo', 'xh', 'ji', 'yo', 'zu'); 510 | 511 | // What language are we gonna use 512 | $return = in_array($lang, $lang_codes); 513 | 514 | return($return); 515 | } 516 | 517 | } 518 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /template.php: -------------------------------------------------------------------------------- 1 | $this->_tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value 28 | * if it's a root-level variable, it'll be like this: 29 | * --> $this->_tpldata[.][0][varname] == value 30 | */ 31 | var $_tpldata = array('.' => array(0 => array())); 32 | var $_rootref; 33 | 34 | // Root dir and hash of filenames for each template handle. 35 | var $root = ''; 36 | var $cachepath = ''; 37 | var $files = array(); 38 | var $filename = array(); 39 | var $files_inherit = array(); 40 | var $files_template = array(); 41 | var $inherit_root = ''; 42 | 43 | // this will hash handle names to the compiled/uncompiled code for that handle. 44 | var $compiled_code = array(); 45 | 46 | /** 47 | * Set template location 48 | * @access public 49 | */ 50 | function set_template() 51 | { 52 | global $phpbb_root_path, $user; 53 | 54 | if (file_exists($phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template')) 55 | { 56 | $this->root = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template'; 57 | $this->cachepath = $phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $user->theme['template_path']) . '_'; 58 | 59 | if ($user->theme['template_inherits_id']) 60 | { 61 | $this->inherit_root = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template'; 62 | } 63 | } 64 | else 65 | { 66 | trigger_error('Template path could not be found: styles/' . $user->theme['template_path'] . '/template', E_USER_ERROR); 67 | } 68 | 69 | $this->_rootref = &$this->_tpldata['.'][0]; 70 | 71 | return true; 72 | } 73 | 74 | /** 75 | * Set custom template location (able to use directory outside of phpBB) 76 | * @access public 77 | */ 78 | function set_custom_template($template_path, $template_name) 79 | { 80 | global $phpbb_root_path; 81 | 82 | $this->root = $template_path; 83 | $this->cachepath = $phpbb_root_path . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_'; 84 | 85 | return true; 86 | } 87 | 88 | /** 89 | * Sets the template filenames for handles. $filename_array 90 | * should be a hash of handle => filename pairs. 91 | * @access public 92 | */ 93 | function set_filenames($filename_array) 94 | { 95 | if (!is_array($filename_array)) 96 | { 97 | return false; 98 | } 99 | foreach ($filename_array as $handle => $filename) 100 | { 101 | if (empty($filename)) 102 | { 103 | trigger_error("template->set_filenames: Empty filename specified for $handle", E_USER_ERROR); 104 | } 105 | 106 | $this->filename[$handle] = $filename; 107 | $this->files[$handle] = $this->root . '/' . $filename; 108 | 109 | if ($this->inherit_root) 110 | { 111 | $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename; 112 | } 113 | } 114 | 115 | return true; 116 | } 117 | 118 | /** 119 | * Destroy template data set 120 | * @access public 121 | */ 122 | function destroy() 123 | { 124 | $this->_tpldata = array('.' => array(0 => array())); 125 | } 126 | 127 | /** 128 | * Reset/empty complete block 129 | * @access public 130 | */ 131 | function destroy_block_vars($blockname) 132 | { 133 | if (strpos($blockname, '.') !== false) 134 | { 135 | // Nested block. 136 | $blocks = explode('.', $blockname); 137 | $blockcount = sizeof($blocks) - 1; 138 | 139 | $str = &$this->_tpldata; 140 | for ($i = 0; $i < $blockcount; $i++) 141 | { 142 | $str = &$str[$blocks[$i]]; 143 | $str = &$str[sizeof($str) - 1]; 144 | } 145 | 146 | unset($str[$blocks[$blockcount]]); 147 | } 148 | else 149 | { 150 | // Top-level block. 151 | unset($this->_tpldata[$blockname]); 152 | } 153 | 154 | return true; 155 | } 156 | 157 | /** 158 | * Display handle 159 | * @access public 160 | */ 161 | function display($handle, $include_once = true) 162 | { 163 | global $user, $phpbb_hook; 164 | 165 | if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, __FUNCTION__), $handle, $include_once)) 166 | { 167 | if ($phpbb_hook->hook_return(array(__CLASS__, __FUNCTION__))) 168 | { 169 | return $phpbb_hook->hook_return_result(array(__CLASS__, __FUNCTION__)); 170 | } 171 | } 172 | 173 | if (defined('IN_ERROR_HANDLER')) 174 | { 175 | if ((E_NOTICE & error_reporting()) == E_NOTICE) 176 | { 177 | error_reporting(error_reporting() ^ E_NOTICE); 178 | } 179 | } 180 | 181 | if ($filename = $this->_tpl_load($handle)) 182 | { 183 | ($include_once) ? include_once($filename) : include($filename); 184 | } 185 | else 186 | { 187 | eval(' ?>' . $this->compiled_code[$handle] . 'display($handle, $include_once); 201 | $contents = ob_get_clean(); 202 | 203 | if ($return_content) 204 | { 205 | return $contents; 206 | } 207 | 208 | $this->assign_var($template_var, $contents); 209 | 210 | return true; 211 | } 212 | 213 | /** 214 | * Load a compiled template if possible, if not, recompile it 215 | * @access private 216 | */ 217 | function _tpl_load(&$handle) 218 | { 219 | global $user, $phpEx, $config; 220 | 221 | $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . $phpEx; 222 | // $this->files_template[$handle] = $user->theme['template_id']; 223 | 224 | $recompile = false; 225 | if (!file_exists($filename) || @filesize($filename) === 0) 226 | { 227 | $recompile = true; 228 | } 229 | else if ($config['load_tplcompile']) 230 | { 231 | // No way around it: we need to check inheritance here 232 | if ($user->theme['template_inherits_id'] && !file_exists($this->files[$handle])) 233 | { 234 | $this->files[$handle] = $this->files_inherit[$handle]; 235 | $this->files_template[$handle] = $user->theme['template_inherits_id']; 236 | } 237 | $recompile = (@filemtime($filename) < filemtime($this->files[$handle])) ? true : false; 238 | } 239 | 240 | // Recompile page if the original template is newer, otherwise load the compiled version 241 | if (!$recompile) 242 | { 243 | return $filename; 244 | } 245 | 246 | global $db, $phpbb_root_path; 247 | 248 | if (!class_exists('template_compile')) 249 | { 250 | include($phpbb_root_path . 'includes/functions_template.' . $phpEx); 251 | } 252 | 253 | // Inheritance - we point to another template file for this one. Equality is also used for store_db 254 | if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($this->files[$handle])) 255 | { 256 | $this->files[$handle] = $this->files_inherit[$handle]; 257 | $this->files_template[$handle] = $user->theme['template_inherits_id']; 258 | } 259 | 260 | $compile = new template_compile($this); 261 | 262 | // If we don't have a file assigned to this handle, die. 263 | if (!isset($this->files[$handle])) 264 | { 265 | trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR); 266 | } 267 | 268 | // Just compile if no user object is present (happens within the installer) 269 | if (!$user) 270 | { 271 | $compile->_tpl_load_file($handle); 272 | return false; 273 | } 274 | 275 | if (isset($user->theme['template_storedb']) && $user->theme['template_storedb']) 276 | { 277 | $rows = array(); 278 | $ids = array(); 279 | // Inheritance 280 | if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) 281 | { 282 | $ids[] = $user->theme['template_inherits_id']; 283 | } 284 | $ids[] = $user->theme['template_id']; 285 | 286 | foreach ($ids as $id) 287 | { 288 | $sql = 'SELECT * 289 | FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' 290 | WHERE template_id = ' . $id . " 291 | AND (template_filename = '" . $db->sql_escape($this->filename[$handle]) . "' 292 | OR template_included " . $db->sql_like_expression($db->any_char . $this->filename[$handle] . ':' . $db->any_char) . ')'; 293 | 294 | $result = $db->sql_query($sql); 295 | while ($row = $db->sql_fetchrow($result)) 296 | { 297 | $rows[$row['template_filename']] = $row; 298 | } 299 | $db->sql_freeresult($result); 300 | } 301 | 302 | if (sizeof($rows)) 303 | { 304 | foreach ($rows as $row) 305 | { 306 | $file = $this->root . '/' . $row['template_filename']; 307 | $force_reload = false; 308 | if ($row['template_id'] != $user->theme['template_id']) 309 | { 310 | // make sure that we are not overlooking a file not in the db yet 311 | if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file)) 312 | { 313 | $file = $this->inherit_root . '/' . $row['template_filename']; 314 | $this->files[$row['template_filename']] = $file; 315 | $this->files_inherit[$row['template_filename']] = $file; 316 | $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; 317 | } 318 | else if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) 319 | { 320 | // Ok, we have a situation. There is a file in the subtemplate, but nothing in the DB. We have to fix that. 321 | $force_reload = true; 322 | $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; 323 | } 324 | } 325 | else 326 | { 327 | $this->files_template[$row['template_filename']] = $user->theme['template_id']; 328 | } 329 | 330 | if ($force_reload || $row['template_mtime'] < filemtime($file)) 331 | { 332 | if ($row['template_filename'] == $this->filename[$handle]) 333 | { 334 | $compile->_tpl_load_file($handle, true); 335 | } 336 | else 337 | { 338 | $this->files[$row['template_filename']] = $file; 339 | $this->filename[$row['template_filename']] = $row['template_filename']; 340 | $compile->_tpl_load_file($row['template_filename'], true); 341 | unset($this->compiled_code[$row['template_filename']]); 342 | unset($this->files[$row['template_filename']]); 343 | unset($this->filename[$row['template_filename']]); 344 | } 345 | } 346 | 347 | if ($row['template_filename'] == $this->filename[$handle]) 348 | { 349 | $this->compiled_code[$handle] = $compile->compile(trim($row['template_data'])); 350 | $compile->compile_write($handle, $this->compiled_code[$handle]); 351 | } 352 | else 353 | { 354 | // Only bother compiling if it doesn't already exist 355 | if (!file_exists($this->cachepath . str_replace('/', '.', $row['template_filename']) . '.' . $phpEx)) 356 | { 357 | $this->filename[$row['template_filename']] = $row['template_filename']; 358 | $compile->compile_write($row['template_filename'], $compile->compile(trim($row['template_data']))); 359 | unset($this->filename[$row['template_filename']]); 360 | } 361 | } 362 | } 363 | } 364 | else 365 | { 366 | $file = $this->root . '/' . $row['template_filename']; 367 | 368 | if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file)) 369 | { 370 | $file = $this->inherit_root . '/' . $row['template_filename']; 371 | $this->files[$row['template_filename']] = $file; 372 | $this->files_inherit[$row['template_filename']] = $file; 373 | $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id']; 374 | } 375 | // Try to load from filesystem and instruct to insert into the styles table... 376 | $compile->_tpl_load_file($handle, true); 377 | return false; 378 | } 379 | 380 | return false; 381 | } 382 | 383 | $compile->_tpl_load_file($handle); 384 | return false; 385 | } 386 | 387 | /** 388 | * Assign key variable pairs from an array 389 | * @access public 390 | */ 391 | function assign_vars($vararray) 392 | { 393 | foreach ($vararray as $key => $val) 394 | { 395 | $this->_rootref[$key] = $val; 396 | } 397 | 398 | return true; 399 | } 400 | 401 | /** 402 | * Assign a single variable to a single key 403 | * @access public 404 | */ 405 | function assign_var($varname, $varval) 406 | { 407 | $this->_rootref[$varname] = $varval; 408 | 409 | return true; 410 | } 411 | 412 | /** 413 | * Assign key variable pairs from an array to a specified block 414 | * @access public 415 | */ 416 | function assign_block_vars($blockname, $vararray) 417 | { 418 | if (strpos($blockname, '.') !== false) 419 | { 420 | // Nested block. 421 | $blocks = explode('.', $blockname); 422 | $blockcount = sizeof($blocks) - 1; 423 | 424 | $str = &$this->_tpldata; 425 | for ($i = 0; $i < $blockcount; $i++) 426 | { 427 | $str = &$str[$blocks[$i]]; 428 | $str = &$str[sizeof($str) - 1]; 429 | } 430 | 431 | $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0; 432 | $vararray['S_ROW_COUNT'] = $s_row_count; 433 | 434 | // Assign S_FIRST_ROW 435 | if (!$s_row_count) 436 | { 437 | $vararray['S_FIRST_ROW'] = true; 438 | } 439 | 440 | // Now the tricky part, we always assign S_LAST_ROW and remove the entry before 441 | // This is much more clever than going through the complete template data on display (phew) 442 | $vararray['S_LAST_ROW'] = true; 443 | if ($s_row_count > 0) 444 | { 445 | unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']); 446 | } 447 | 448 | // Now we add the block that we're actually assigning to. 449 | // We're adding a new iteration to this block with the given 450 | // variable assignments. 451 | $str[$blocks[$blockcount]][] = $vararray; 452 | } 453 | else 454 | { 455 | // Top-level block. 456 | $s_row_count = (isset($this->_tpldata[$blockname])) ? sizeof($this->_tpldata[$blockname]) : 0; 457 | $vararray['S_ROW_COUNT'] = $s_row_count; 458 | 459 | // Assign S_FIRST_ROW 460 | if (!$s_row_count) 461 | { 462 | $vararray['S_FIRST_ROW'] = true; 463 | } 464 | 465 | // We always assign S_LAST_ROW and remove the entry before 466 | $vararray['S_LAST_ROW'] = true; 467 | if ($s_row_count > 0) 468 | { 469 | unset($this->_tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']); 470 | } 471 | 472 | // Add a new iteration to this block with the variable assignments we were given. 473 | $this->_tpldata[$blockname][] = $vararray; 474 | } 475 | 476 | return true; 477 | } 478 | 479 | /** 480 | * Change already assigned key variable pair (one-dimensional - single loop entry) 481 | * 482 | * An example of how to use this function: 483 | * {@example alter_block_array.php} 484 | * 485 | * @param string $blockname the blockname, for example 'loop' 486 | * @param array $vararray the var array to insert/add or merge 487 | * @param mixed $key Key to search for 488 | * 489 | * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] 490 | * 491 | * int: Position [the position to change or insert at directly given] 492 | * 493 | * If key is false the position is set to 0 494 | * If key is true the position is set to the last entry 495 | * 496 | * @param string $mode Mode to execute (valid modes are 'insert' and 'change') 497 | * 498 | * If insert, the vararray is inserted at the given position (position counting from zero). 499 | * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). 500 | * 501 | * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) 502 | * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) 503 | * 504 | * @return bool false on error, true on success 505 | * @access public 506 | */ 507 | function alter_block_array($blockname, $vararray, $key = false, $mode = 'insert') 508 | { 509 | if (strpos($blockname, '.') !== false) 510 | { 511 | // Nested blocks are not supported 512 | return false; 513 | } 514 | 515 | // Change key to zero (change first position) if false and to last position if true 516 | if ($key === false || $key === true) 517 | { 518 | $key = ($key === false) ? 0 : sizeof($this->_tpldata[$blockname]); 519 | } 520 | 521 | // Get correct position if array given 522 | if (is_array($key)) 523 | { 524 | // Search array to get correct position 525 | list($search_key, $search_value) = @each($key); 526 | 527 | $key = NULL; 528 | foreach ($this->_tpldata[$blockname] as $i => $val_ary) 529 | { 530 | if ($val_ary[$search_key] === $search_value) 531 | { 532 | $key = $i; 533 | break; 534 | } 535 | } 536 | 537 | // key/value pair not found 538 | if ($key === NULL) 539 | { 540 | return false; 541 | } 542 | } 543 | 544 | // Insert Block 545 | if ($mode == 'insert') 546 | { 547 | // Make sure we are not exceeding the last iteration 548 | if ($key >= sizeof($this->_tpldata[$blockname])) 549 | { 550 | $key = sizeof($this->_tpldata[$blockname]); 551 | unset($this->_tpldata[$blockname][($key - 1)]['S_LAST_ROW']); 552 | $vararray['S_LAST_ROW'] = true; 553 | } 554 | else if ($key === 0) 555 | { 556 | unset($this->_tpldata[$blockname][0]['S_FIRST_ROW']); 557 | $vararray['S_FIRST_ROW'] = true; 558 | } 559 | 560 | // Re-position template blocks 561 | for ($i = sizeof($this->_tpldata[$blockname]); $i > $key; $i--) 562 | { 563 | $this->_tpldata[$blockname][$i] = $this->_tpldata[$blockname][$i-1]; 564 | $this->_tpldata[$blockname][$i]['S_ROW_COUNT'] = $i; 565 | } 566 | 567 | // Insert vararray at given position 568 | $vararray['S_ROW_COUNT'] = $key; 569 | $this->_tpldata[$blockname][$key] = $vararray; 570 | 571 | return true; 572 | } 573 | 574 | // Which block to change? 575 | if ($mode == 'change') 576 | { 577 | if ($key == sizeof($this->_tpldata[$blockname])) 578 | { 579 | $key--; 580 | } 581 | 582 | $this->_tpldata[$blockname][$key] = array_merge($this->_tpldata[$blockname][$key], $vararray); 583 | return true; 584 | } 585 | 586 | return false; 587 | } 588 | 589 | /** 590 | * Include a separate template 591 | * @access private 592 | */ 593 | function _tpl_include($filename, $include = true) 594 | { 595 | $handle = $filename; 596 | $this->filename[$handle] = $filename; 597 | $this->files[$handle] = $this->root . '/' . $filename; 598 | if ($this->inherit_root) 599 | { 600 | $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename; 601 | } 602 | 603 | $filename = $this->_tpl_load($handle); 604 | 605 | if ($include) 606 | { 607 | global $user; 608 | 609 | if ($filename) 610 | { 611 | include($filename); 612 | return; 613 | } 614 | eval(' ?>' . $this->compiled_code[$handle] . 'template = &$template; 652 | } 653 | 654 | /** 655 | * Load template source from file 656 | * @access private 657 | */ 658 | function _tpl_load_file($handle, $store_in_db = false) 659 | { 660 | // Try and open template for read 661 | if (!file_exists($this->template->files[$handle])) 662 | { 663 | trigger_error("template->_tpl_load_file(): File {$this->template->files[$handle]} does not exist or is empty", E_USER_ERROR); 664 | } 665 | 666 | $this->template->compiled_code[$handle] = $this->compile(trim(@file_get_contents($this->template->files[$handle]))); 667 | 668 | // Actually compile the code now. 669 | $this->compile_write($handle, $this->template->compiled_code[$handle]); 670 | 671 | // Store in database if required... 672 | if ($store_in_db) 673 | { 674 | global $db, $user; 675 | 676 | $sql_ary = array( 677 | 'template_id' => $this->template->files_template[$handle], 678 | 'template_filename' => $this->template->filename[$handle], 679 | 'template_included' => '', 680 | 'template_mtime' => time(), 681 | 'template_data' => trim(@file_get_contents($this->template->files[$handle])), 682 | ); 683 | 684 | $sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); 685 | $db->sql_query($sql); 686 | } 687 | } 688 | 689 | /** 690 | * Remove any PHP tags that do not belong, these regular expressions are derived from 691 | * the ones that exist in zend_language_scanner.l 692 | * @access private 693 | */ 694 | function remove_php_tags(&$code) 695 | { 696 | // This matches the information gathered from the internal PHP lexer 697 | $match = array( 698 | '#<([\?%])=?.*?\1>#s', 699 | '#.*?#s', 700 | '#<\?php(?:\r\n?|[ \n\t]).*?\?>#s' 701 | ); 702 | 703 | $code = preg_replace($match, '', $code); 704 | } 705 | 706 | /** 707 | * The all seeing all doing compile method. Parts are inspired by or directly from Smarty 708 | * @access private 709 | */ 710 | function compile($code, $no_echo = false, $echo_var = '') 711 | { 712 | global $config; 713 | 714 | if ($echo_var) 715 | { 716 | global $$echo_var; 717 | } 718 | 719 | // Remove any "loose" php ... we want to give admins the ability 720 | // to switch on/off PHP for a given template. Allowing unchecked 721 | // php is a no-no. There is a potential issue here in that non-php 722 | // content may be removed ... however designers should use entities 723 | // if they wish to display < and > 724 | $this->remove_php_tags($code); 725 | 726 | // Pull out all block/statement level elements and separate plain text 727 | preg_match_all('#(.*?)#s', $code, $matches); 728 | $php_blocks = $matches[1]; 729 | $code = preg_replace('#.*?#s', '', $code); 730 | 731 | preg_match_all('##', $code, $matches); 732 | $include_blocks = $matches[1]; 733 | $code = preg_replace('##', '', $code); 734 | 735 | preg_match_all('##', $code, $matches); 736 | $includephp_blocks = $matches[1]; 737 | $code = preg_replace('##', '', $code); 738 | 739 | preg_match_all('##', $code, $blocks, PREG_SET_ORDER); 740 | 741 | $text_blocks = preg_split('##', $code); 742 | 743 | for ($i = 0, $j = sizeof($text_blocks); $i < $j; $i++) 744 | { 745 | $this->compile_var_tags($text_blocks[$i]); 746 | } 747 | $compile_blocks = array(); 748 | 749 | for ($curr_tb = 0, $tb_size = sizeof($blocks); $curr_tb < $tb_size; $curr_tb++) 750 | { 751 | $block_val = &$blocks[$curr_tb]; 752 | 753 | switch ($block_val[1]) 754 | { 755 | case 'BEGIN': 756 | $this->block_else_level[] = false; 757 | $compile_blocks[] = 'compile_tag_block($block_val[2]) . ' ?>'; 758 | break; 759 | 760 | case 'BEGINELSE': 761 | $this->block_else_level[sizeof($this->block_else_level) - 1] = true; 762 | $compile_blocks[] = ''; 763 | break; 764 | 765 | case 'END': 766 | array_pop($this->block_names); 767 | $compile_blocks[] = 'block_else_level)) ? '}' : '}}') . ' ?>'; 768 | break; 769 | 770 | case 'IF': 771 | $compile_blocks[] = 'compile_tag_if($block_val[2], false) . ' ?>'; 772 | break; 773 | 774 | case 'ELSE': 775 | $compile_blocks[] = ''; 776 | break; 777 | 778 | case 'ELSEIF': 779 | $compile_blocks[] = 'compile_tag_if($block_val[2], true) . ' ?>'; 780 | break; 781 | 782 | case 'ENDIF': 783 | $compile_blocks[] = ''; 784 | break; 785 | 786 | case 'DEFINE': 787 | $compile_blocks[] = 'compile_tag_define($block_val[2], true) . ' ?>'; 788 | break; 789 | 790 | case 'UNDEFINE': 791 | $compile_blocks[] = 'compile_tag_define($block_val[2], false) . ' ?>'; 792 | break; 793 | 794 | case 'INCLUDE': 795 | $temp = array_shift($include_blocks); 796 | $compile_blocks[] = 'compile_tag_include($temp) . ' ?>'; 797 | $this->template->_tpl_include($temp, false); 798 | break; 799 | 800 | case 'INCLUDEPHP': 801 | $compile_blocks[] = ($config['tpl_allow_php']) ? 'compile_tag_include_php(array_shift($includephp_blocks)) . ' ?>' : ''; 802 | break; 803 | 804 | case 'PHP': 805 | $compile_blocks[] = ($config['tpl_allow_php']) ? '' : ''; 806 | break; 807 | 808 | default: 809 | $this->compile_var_tags($block_val[0]); 810 | $trim_check = trim($block_val[0]); 811 | $compile_blocks[] = (!$no_echo) ? ((!empty($trim_check)) ? $block_val[0] : '') : ((!empty($trim_check)) ? $block_val[0] : ''); 812 | break; 813 | } 814 | } 815 | 816 | $template_php = ''; 817 | for ($i = 0, $size = sizeof($text_blocks); $i < $size; $i++) 818 | { 819 | $trim_check_text = trim($text_blocks[$i]); 820 | $template_php .= (!$no_echo) ? (($trim_check_text != '') ? $text_blocks[$i] : '') . ((isset($compile_blocks[$i])) ? $compile_blocks[$i] : '') : (($trim_check_text != '') ? $text_blocks[$i] : '') . ((isset($compile_blocks[$i])) ? $compile_blocks[$i] : ''); 821 | } 822 | 823 | // There will be a number of occasions where we switch into and out of 824 | // PHP mode instantaneously. Rather than "burden" the parser with this 825 | // we'll strip out such occurences, minimising such switching 826 | if ($no_echo) 827 | { 828 | return "\$$echo_var .= '" . str_replace(' ?>generate_block_varref($namespace, $varname, true, $var_val[2]); 851 | 852 | $text_blocks = str_replace($var_val[0], $new, $text_blocks); 853 | } 854 | 855 | // This will handle the remaining root-level varrefs 856 | // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array 857 | if (strpos($text_blocks, '{L_') !== false) 858 | { 859 | $text_blocks = preg_replace('#\{L_([A-Z0-9\-_]+)\}#', "_rootref['L_\\1'])) ? \$this->_rootref['L_\\1'] : ((isset(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '{ \\1 }')); ?>", $text_blocks); 860 | } 861 | 862 | // Handle addslashed language variables prefixed with LA_ 863 | // If a template variable already exist, it will be used in favor of it... 864 | if (strpos($text_blocks, '{LA_') !== false) 865 | { 866 | $text_blocks = preg_replace('#\{LA_([A-Z0-9\-_]+)\}#', "_rootref['LA_\\1'])) ? \$this->_rootref['LA_\\1'] : ((isset(\$this->_rootref['L_\\1'])) ? addslashes(\$this->_rootref['L_\\1']) : ((isset(\$user->lang['\\1'])) ? addslashes(\$user->lang['\\1']) : '{ \\1 }'))); ?>", $text_blocks); 867 | } 868 | 869 | // Handle remaining varrefs 870 | $text_blocks = preg_replace('#\{([A-Z0-9\-_]+)\}#', "_rootref['\\1'])) ? \$this->_rootref['\\1'] : ''; ?>", $text_blocks); 871 | $text_blocks = preg_replace('#\{\$([A-Z0-9\-_]+)\}#', "_tpldata['DEFINE']['.']['\\1'])) ? \$this->_tpldata['DEFINE']['.']['\\1'] : ''; ?>", $text_blocks); 872 | 873 | return; 874 | } 875 | 876 | /** 877 | * Compile blocks 878 | * @access private 879 | */ 880 | function compile_tag_block($tag_args) 881 | { 882 | $no_nesting = false; 883 | 884 | // Is the designer wanting to call another loop in a loop? 885 | if (strpos($tag_args, '!') === 0) 886 | { 887 | // Count the number if ! occurrences (not allowed in vars) 888 | $no_nesting = substr_count($tag_args, '!'); 889 | $tag_args = substr($tag_args, $no_nesting); 890 | } 891 | 892 | // Allow for control of looping (indexes start from zero): 893 | // foo(2) : Will start the loop on the 3rd entry 894 | // foo(-2) : Will start the loop two entries from the end 895 | // foo(3,4) : Will start the loop on the fourth entry and end it on the fifth 896 | // foo(3,-4) : Will start the loop on the fourth entry and end it four from last 897 | if (preg_match('#^([^()]*)\(([\-\d]+)(?:,([\-\d]+))?\)$#', $tag_args, $match)) 898 | { 899 | $tag_args = $match[1]; 900 | 901 | if ($match[2] < 0) 902 | { 903 | $loop_start = '($_' . $tag_args . '_count ' . $match[2] . ' < 0 ? 0 : $_' . $tag_args . '_count ' . $match[2] . ')'; 904 | } 905 | else 906 | { 907 | $loop_start = '($_' . $tag_args . '_count < ' . $match[2] . ' ? $_' . $tag_args . '_count : ' . $match[2] . ')'; 908 | } 909 | 910 | if (strlen($match[3]) < 1 || $match[3] == -1) 911 | { 912 | $loop_end = '$_' . $tag_args . '_count'; 913 | } 914 | else if ($match[3] >= 0) 915 | { 916 | $loop_end = '(' . ($match[3] + 1) . ' > $_' . $tag_args . '_count ? $_' . $tag_args . '_count : ' . ($match[3] + 1) . ')'; 917 | } 918 | else //if ($match[3] < -1) 919 | { 920 | $loop_end = '$_' . $tag_args . '_count' . ($match[3] + 1); 921 | } 922 | } 923 | else 924 | { 925 | $loop_start = 0; 926 | $loop_end = '$_' . $tag_args . '_count'; 927 | } 928 | 929 | $tag_template_php = ''; 930 | array_push($this->block_names, $tag_args); 931 | 932 | if ($no_nesting !== false) 933 | { 934 | // We need to implode $no_nesting times from the end... 935 | $block = array_slice($this->block_names, -$no_nesting); 936 | } 937 | else 938 | { 939 | $block = $this->block_names; 940 | } 941 | 942 | if (sizeof($block) < 2) 943 | { 944 | // Block is not nested. 945 | $tag_template_php = '$_' . $tag_args . "_count = (isset(\$this->_tpldata['$tag_args'])) ? sizeof(\$this->_tpldata['$tag_args']) : 0;"; 946 | $varref = "\$this->_tpldata['$tag_args']"; 947 | } 948 | else 949 | { 950 | // This block is nested. 951 | // Generate a namespace string for this block. 952 | $namespace = implode('.', $block); 953 | 954 | // Get a reference to the data array for this block that depends on the 955 | // current indices of all parent blocks. 956 | $varref = $this->generate_block_data_ref($namespace, false); 957 | 958 | // Create the for loop code to iterate over this block. 959 | $tag_template_php = '$_' . $tag_args . '_count = (isset(' . $varref . ')) ? sizeof(' . $varref . ') : 0;'; 960 | } 961 | 962 | $tag_template_php .= 'if ($_' . $tag_args . '_count) {'; 963 | 964 | /** 965 | * The following uses foreach for iteration instead of a for loop, foreach is faster but requires PHP to make a copy of the contents of the array which uses more memory 966 | * 967 | * if (!$offset) 968 | * { 969 | * $tag_template_php .= 'foreach (' . $varref . ' as $_' . $tag_args . '_i => $_' . $tag_args . '_val){'; 970 | * } 971 | * 972 | */ 973 | 974 | $tag_template_php .= 'for ($_' . $tag_args . '_i = ' . $loop_start . '; $_' . $tag_args . '_i < ' . $loop_end . '; ++$_' . $tag_args . '_i){'; 975 | $tag_template_php .= '$_'. $tag_args . '_val = &' . $varref . '[$_'. $tag_args. '_i];'; 976 | 977 | return $tag_template_php; 978 | } 979 | 980 | /** 981 | * Compile IF tags - much of this is from Smarty with 982 | * some adaptions for our block level methods 983 | * @access private 984 | */ 985 | function compile_tag_if($tag_args, $elseif) 986 | { 987 | // Tokenize args for 'if' tag. 988 | preg_match_all('/(?: 989 | "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | 990 | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | 991 | [(),] | 992 | [^\s(),]+)/x', $tag_args, $match); 993 | 994 | $tokens = $match[0]; 995 | $is_arg_stack = array(); 996 | 997 | for ($i = 0, $size = sizeof($tokens); $i < $size; $i++) 998 | { 999 | $token = &$tokens[$i]; 1000 | 1001 | switch ($token) 1002 | { 1003 | case '!==': 1004 | case '===': 1005 | case '<<': 1006 | case '>>': 1007 | case '|': 1008 | case '^': 1009 | case '&': 1010 | case '~': 1011 | case ')': 1012 | case ',': 1013 | case '+': 1014 | case '-': 1015 | case '*': 1016 | case '/': 1017 | case '@': 1018 | break; 1019 | 1020 | case '==': 1021 | case 'eq': 1022 | $token = '=='; 1023 | break; 1024 | 1025 | case '!=': 1026 | case '<>': 1027 | case 'ne': 1028 | case 'neq': 1029 | $token = '!='; 1030 | break; 1031 | 1032 | case '<': 1033 | case 'lt': 1034 | $token = '<'; 1035 | break; 1036 | 1037 | case '<=': 1038 | case 'le': 1039 | case 'lte': 1040 | $token = '<='; 1041 | break; 1042 | 1043 | case '>': 1044 | case 'gt': 1045 | $token = '>'; 1046 | break; 1047 | 1048 | case '>=': 1049 | case 'ge': 1050 | case 'gte': 1051 | $token = '>='; 1052 | break; 1053 | 1054 | case '&&': 1055 | case 'and': 1056 | $token = '&&'; 1057 | break; 1058 | 1059 | case '||': 1060 | case 'or': 1061 | $token = '||'; 1062 | break; 1063 | 1064 | case '!': 1065 | case 'not': 1066 | $token = '!'; 1067 | break; 1068 | 1069 | case '%': 1070 | case 'mod': 1071 | $token = '%'; 1072 | break; 1073 | 1074 | case '(': 1075 | array_push($is_arg_stack, $i); 1076 | break; 1077 | 1078 | case 'is': 1079 | $is_arg_start = ($tokens[$i-1] == ')') ? array_pop($is_arg_stack) : $i-1; 1080 | $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); 1081 | 1082 | $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); 1083 | 1084 | array_splice($tokens, $is_arg_start, sizeof($tokens), $new_tokens); 1085 | 1086 | $i = $is_arg_start; 1087 | 1088 | // no break 1089 | 1090 | default: 1091 | if (preg_match('#^((?:[a-z0-9\-_]+\.)+)?(\$)?(?=[A-Z])([A-Z0-9\-_]+)#s', $token, $varrefs)) 1092 | { 1093 | $token = (!empty($varrefs[1])) ? $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[2]) . '[\'' . $varrefs[3] . '\']' : (($varrefs[2]) ? '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[3] . '\']' : '$this->_rootref[\'' . $varrefs[3] . '\']'); 1094 | } 1095 | else if (preg_match('#^\.((?:[a-z0-9\-_]+\.?)+)$#s', $token, $varrefs)) 1096 | { 1097 | // Allow checking if loops are set with .loopname 1098 | // It is also possible to check the loop count by doing for example 1099 | $blocks = explode('.', $varrefs[1]); 1100 | 1101 | // If the block is nested, we have a reference that we can grab. 1102 | // If the block is not nested, we just go and grab the block from _tpldata 1103 | if (sizeof($blocks) > 1) 1104 | { 1105 | $block = array_pop($blocks); 1106 | $namespace = implode('.', $blocks); 1107 | $varref = $this->generate_block_data_ref($namespace, true); 1108 | 1109 | // Add the block reference for the last child. 1110 | $varref .= "['" . $block . "']"; 1111 | } 1112 | else 1113 | { 1114 | $varref = '$this->_tpldata'; 1115 | 1116 | // Add the block reference for the last child. 1117 | $varref .= "['" . $blocks[0] . "']"; 1118 | } 1119 | $token = "sizeof($varref)"; 1120 | } 1121 | else if (!empty($token)) 1122 | { 1123 | $token = '(' . $token . ')'; 1124 | } 1125 | 1126 | break; 1127 | } 1128 | } 1129 | 1130 | // If there are no valid tokens left or only control/compare characters left, we do skip this statement 1131 | if (!sizeof($tokens) || str_replace(array(' ', '=', '!', '<', '>', '&', '|', '%', '(', ')'), '', implode('', $tokens)) == '') 1132 | { 1133 | $tokens = array('false'); 1134 | } 1135 | return (($elseif) ? '} else if (' : 'if (') . (implode(' ', $tokens) . ') { '); 1136 | } 1137 | 1138 | /** 1139 | * Compile DEFINE tags 1140 | * @access private 1141 | */ 1142 | function compile_tag_define($tag_args, $op) 1143 | { 1144 | preg_match('#^((?:[a-z0-9\-_]+\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (\'?)([^\']*)(\'?))?$#', $tag_args, $match); 1145 | 1146 | if (empty($match[2]) || (!isset($match[4]) && $op)) 1147 | { 1148 | return ''; 1149 | } 1150 | 1151 | if (!$op) 1152 | { 1153 | return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ');'; 1154 | } 1155 | 1156 | // Are we a string? 1157 | if ($match[3] && $match[5]) 1158 | { 1159 | $match[4] = str_replace(array('\\\'', '\\\\', '\''), array('\'', '\\', '\\\''), $match[4]); 1160 | 1161 | // Compile reference, we allow template variables in defines... 1162 | $match[4] = $this->compile($match[4]); 1163 | 1164 | // Now replace the php code 1165 | $match[4] = "'" . str_replace(array(''), array("' . ", " . '"), $match[4]) . "'"; 1166 | } 1167 | else 1168 | { 1169 | preg_match('#true|false|\.#i', $match[4], $type); 1170 | 1171 | switch (strtolower($type[0])) 1172 | { 1173 | case 'true': 1174 | case 'false': 1175 | $match[4] = strtoupper($match[4]); 1176 | break; 1177 | 1178 | case '.': 1179 | $match[4] = doubleval($match[4]); 1180 | break; 1181 | 1182 | default: 1183 | $match[4] = intval($match[4]); 1184 | break; 1185 | } 1186 | } 1187 | 1188 | return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $match[4] . ';'; 1189 | } 1190 | 1191 | /** 1192 | * Compile INCLUDE tag 1193 | * @access private 1194 | */ 1195 | function compile_tag_include($tag_args) 1196 | { 1197 | return "\$this->_tpl_include('$tag_args');"; 1198 | } 1199 | 1200 | /** 1201 | * Compile INCLUDE_PHP tag 1202 | * @access private 1203 | */ 1204 | function compile_tag_include_php($tag_args) 1205 | { 1206 | return "include('" . $tag_args . "');"; 1207 | } 1208 | 1209 | /** 1210 | * parse expression 1211 | * This is from Smarty 1212 | * @access private 1213 | */ 1214 | function _parse_is_expr($is_arg, $tokens) 1215 | { 1216 | $expr_end = 0; 1217 | $negate_expr = false; 1218 | 1219 | if (($first_token = array_shift($tokens)) == 'not') 1220 | { 1221 | $negate_expr = true; 1222 | $expr_type = array_shift($tokens); 1223 | } 1224 | else 1225 | { 1226 | $expr_type = $first_token; 1227 | } 1228 | 1229 | switch ($expr_type) 1230 | { 1231 | case 'even': 1232 | if (@$tokens[$expr_end] == 'by') 1233 | { 1234 | $expr_end++; 1235 | $expr_arg = $tokens[$expr_end++]; 1236 | $expr = "!(($is_arg / $expr_arg) % $expr_arg)"; 1237 | } 1238 | else 1239 | { 1240 | $expr = "!($is_arg & 1)"; 1241 | } 1242 | break; 1243 | 1244 | case 'odd': 1245 | if (@$tokens[$expr_end] == 'by') 1246 | { 1247 | $expr_end++; 1248 | $expr_arg = $tokens[$expr_end++]; 1249 | $expr = "(($is_arg / $expr_arg) % $expr_arg)"; 1250 | } 1251 | else 1252 | { 1253 | $expr = "($is_arg & 1)"; 1254 | } 1255 | break; 1256 | 1257 | case 'div': 1258 | if (@$tokens[$expr_end] == 'by') 1259 | { 1260 | $expr_end++; 1261 | $expr_arg = $tokens[$expr_end++]; 1262 | $expr = "!($is_arg % $expr_arg)"; 1263 | } 1264 | break; 1265 | } 1266 | 1267 | if ($negate_expr) 1268 | { 1269 | $expr = "!($expr)"; 1270 | } 1271 | 1272 | array_splice($tokens, 0, $expr_end, $expr); 1273 | 1274 | return $tokens; 1275 | } 1276 | 1277 | /** 1278 | * Generates a reference to the given variable inside the given (possibly nested) 1279 | * block namespace. This is a string of the form: 1280 | * ' . $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . ' 1281 | * It's ready to be inserted into an "echo" line in one of the templates. 1282 | * NOTE: expects a trailing "." on the namespace. 1283 | * @access private 1284 | */ 1285 | function generate_block_varref($namespace, $varname, $echo = true, $defop = false) 1286 | { 1287 | // Strip the trailing period. 1288 | $namespace = substr($namespace, 0, -1); 1289 | 1290 | // Get a reference to the data block for this namespace. 1291 | $varref = $this->generate_block_data_ref($namespace, true, $defop); 1292 | // Prepend the necessary code to stick this in an echo line. 1293 | 1294 | // Append the variable reference. 1295 | $varref .= "['$varname']"; 1296 | $varref = ($echo) ? "" : ((isset($varref)) ? $varref : ''); 1297 | 1298 | return $varref; 1299 | } 1300 | 1301 | /** 1302 | * Generates a reference to the array of data values for the given 1303 | * (possibly nested) block namespace. This is a string of the form: 1304 | * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN'] 1305 | * 1306 | * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above. 1307 | * NOTE: does not expect a trailing "." on the blockname. 1308 | * @access private 1309 | */ 1310 | function generate_block_data_ref($blockname, $include_last_iterator, $defop = false) 1311 | { 1312 | // Get an array of the blocks involved. 1313 | $blocks = explode('.', $blockname); 1314 | $blockcount = sizeof($blocks) - 1; 1315 | 1316 | // DEFINE is not an element of any referenced variable, we must use _tpldata to access it 1317 | if ($defop) 1318 | { 1319 | $varref = '$this->_tpldata[\'DEFINE\']'; 1320 | // Build up the string with everything but the last child. 1321 | for ($i = 0; $i < $blockcount; $i++) 1322 | { 1323 | $varref .= "['" . $blocks[$i] . "'][\$_" . $blocks[$i] . '_i]'; 1324 | } 1325 | // Add the block reference for the last child. 1326 | $varref .= "['" . $blocks[$blockcount] . "']"; 1327 | // Add the iterator for the last child if requried. 1328 | if ($include_last_iterator) 1329 | { 1330 | $varref .= '[$_' . $blocks[$blockcount] . '_i]'; 1331 | } 1332 | return $varref; 1333 | } 1334 | else if ($include_last_iterator) 1335 | { 1336 | return '$_'. $blocks[$blockcount] . '_val'; 1337 | } 1338 | else 1339 | { 1340 | return '$_'. $blocks[$blockcount - 1] . '_val[\''. $blocks[$blockcount]. '\']'; 1341 | } 1342 | } 1343 | 1344 | /** 1345 | * Write compiled file to cache directory 1346 | * @access private 1347 | */ 1348 | function compile_write($handle, $data) 1349 | { 1350 | global $phpEx; 1351 | 1352 | $filename = $this->template->cachepath . str_replace('/', '.', $this->template->filename[$handle]) . '.' . $phpEx; 1353 | 1354 | $data = "' . $data); 1355 | 1356 | if ($fp = @fopen($filename, 'wb')) 1357 | { 1358 | @flock($fp, LOCK_EX); 1359 | @fwrite ($fp, $data); 1360 | @flock($fp, LOCK_UN); 1361 | @fclose($fp); 1362 | 1363 | chmod($filename, 0777); 1364 | } 1365 | 1366 | return; 1367 | } 1368 | } 1369 | 1370 | ?> -------------------------------------------------------------------------------- /modx_functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JavaScript for modx-creator 3 | */ 4 | 5 | var field_cnt = 1; 6 | var file_cnt = 1; 7 | var edit_cnt = 1; 8 | var dl_cnt = 1; 9 | var dt_cnt = 1; 10 | var dd_cnt = 1; 11 | 12 | /** 13 | * Change the input type depending on what is selected 14 | */ 15 | function get_select_change(value, dt_id, dd_id, file_name, dl5_id) 16 | { 17 | var data_type = 0; 18 | var row_count; 19 | var info_img = ''; 20 | var tmp_data = ''; 21 | var tmp_id = dd_id + '_data'; 22 | 23 | // Remove the datafield so that we can change to the one we want 24 | if (document.getElementById(dd_id + '_field')) 25 | { 26 | if(document.getElementById(dd_id + '_data').value) 27 | { 28 | tmp_data = document.getElementById(dd_id + '_data').value; 29 | } 30 | $('#' + dd_id + '_field').remove(); 31 | } 32 | if($('#' + dd_id + '_info')) 33 | { 34 | $('#' + dd_id + '_info').remove(); 35 | } 36 | 37 | if($('#' + dd_id + '_toolbox')) 38 | { 39 | $('#' + dd_id + '_toolbox').remove(); 40 | } 41 | 42 | if($('#' + dd_id + '_delete_tool')) 43 | { 44 | $('#' + dd_id + '_delete_tool').remove(); 45 | } 46 | 47 | 48 | switch(value) 49 | { 50 | case 'find': 51 | data_type = 1; 52 | info_img = 'Find explain'; 53 | break; 54 | 55 | case 'remove': 56 | data_type = 1; 57 | info_img = 'Find and delete explain'; 58 | break; 59 | 60 | case 'after-add': 61 | case 'before-add': 62 | case 'replace-with': 63 | case 'operation': 64 | data_type = 1; 65 | info_img = 'Action explain'; 66 | break; 67 | 68 | case 'inline-find': 69 | case 'inline-remove': 70 | case 'inline-after-add': 71 | case 'inline-before-add': 72 | case 'inline-replace-with': 73 | case 'inline-operation': 74 | data_type = 2; 75 | info_img = 'Inline explain'; 76 | break; 77 | 78 | default: 79 | data_type = 3; 80 | info_img = 'Comment explain'; 81 | break; 82 | } 83 | 84 | switch(data_type) 85 | { 86 | case 1: 87 | var element = '
'; 88 | element += ''; 89 | element += '
'; 90 | element += 'Delete'; 91 | element += 'Add 4 rows'; 92 | element += 'Remove 4 rows'; 93 | element += '
'; 94 | element += '
'; 95 | break; 96 | 97 | case 2: 98 | var element = ''; 99 | element += ''; 100 | element += 'Delete'; 101 | element += ''; 102 | break; 103 | 104 | default: 105 | var element = '
'; 106 | element += ''; 107 | element += '
'; 108 | element += 'Delete'; 109 | element += 'Add 4 rows'; 110 | element += 'Remove 4 rows'; 111 | element += '
'; 112 | element += '
' + lang_select(file_name + '[lang]') + '
'; 113 | element += '
'; 114 | break; 115 | } 116 | 117 | $('#' + dd_id).append(element); 118 | $('#' + dt_id + '_options').append(info_img); 119 | } 120 | 121 | /** 122 | * Generate new fields for the actions 123 | */ 124 | function modx_add_field(obj_id, parent_id, sort, position, if_edit) 125 | { 126 | var edit_id = 'e_' + edit_cnt++; 127 | var dl_id = 'edl_' + dl_cnt++; 128 | var dd_id = 'edd_' + dd_cnt++; 129 | var dt_id = 'edt_' + dt_cnt++; 130 | var new_edit = (if_edit) ? '[' + edit_id + ']' : ''; 131 | 132 | if(sort == 'edit') 133 | { 134 | var element = '
'; 135 | element += ' Edit'; 136 | element += ' Info icon'; 137 | element += 'Delete '; 138 | element += ' '; 139 | element += ''; 140 | element += ' Each FIND typically requires to start a new EDIT'; 141 | element += '

NOTE: Each discreet change to a file must be wrapped in its own edit tag.

'; 142 | element += '
'; 143 | element += '
'; 144 | element += ''; 145 | element += '' + modx_select(obj_id + '[' + edit_id + '][' + dl_id + ']', dt_id, dd_id, dl_id) + ''; 146 | element += '
'; 147 | element += 'Add action above '; 148 | element += ' '; 149 | element += ''; 150 | element += '
'; 151 | element += '
'; 152 | element += '
'; 153 | element += ''; 154 | element += ''; 155 | element += ''; 156 | element += 'Delete'; 157 | element += '
'; 158 | element += '
'; 159 | element += '
'; 160 | } 161 | else 162 | { 163 | var element = '
'; 164 | element += '
'; 165 | element += ''; 166 | element += '' + modx_select(obj_id + '[' + dl_id + ']', dt_id, dd_id, dl_id) + ''; 167 | element += '
'; 168 | element += 'Add action above '; 169 | element += 'Add action below '; 170 | element += 'Type explain'; 171 | element += '
'; 172 | element += '
'; 173 | element += '
'; 174 | element += ''; 175 | element += ''; 176 | element += ''; 177 | element += 'Delete'; 178 | element += '
'; 179 | element += '
'; 180 | } 181 | 182 | if(position == 'above') 183 | { 184 | $('#' + parent_id).before(element); 185 | } 186 | else 187 | { 188 | $('#' + parent_id).after(element); 189 | } 190 | } 191 | 192 | /** 193 | * Generate the type select 194 | */ 195 | function modx_select(file_name, dt_id, dd_id, dl_id) 196 | { 197 | var element = ''; 213 | 214 | return(element); 215 | } 216 | 217 | function act_file() 218 | { 219 | var file_id = 'f_' + file_cnt++; 220 | var edit_id = 'e_' + edit_cnt++; 221 | var dl1_id = 'edl_' + dl_cnt++; 222 | var dl2_id = 'edl_' + dl_cnt++; 223 | var dd_id = 'edd_' + dd_cnt++; 224 | var dt_id = 'edt_' + dt_cnt++; 225 | 226 | var element = '
'; 227 | element += '
'; 228 | element += '
'; 229 | element += ''; 230 | element += 'File explain'; 231 | element += '
'; 232 | element += '
'; 233 | element += ''; 234 | element += 'Delete'; 235 | element += '
'; 236 | element += '
'; 237 | 238 | element += '

'; 239 | 240 | element += '
'; 241 | element += 'Edit'; 242 | element += ' Edit explain '; 243 | element += 'Delete'; 244 | element += ' '; 245 | element += ''; 246 | element += ' Each FIND typically requires to start a new EDIT'; 247 | element += '

NOTE: Each discreet change to a file must be wrapped in its own edit tag.

'; 248 | 249 | element += '
'; 250 | element += '
'; 251 | element += ''; 252 | element += '' + modx_select('modx[' + file_id + '][' + edit_id + '][' + dl2_id + ']', dt_id, dd_id, dl2_id) + ''; 253 | element += '
'; 254 | element += ' Add field above'; 255 | element += ' Add field below'; 256 | element += ' Type explain'; 257 | element += '
'; 258 | element += '
'; 259 | element += '
'; 260 | element += ''; 261 | element += ''; 262 | element += ''; 263 | element += 'Delete'; 264 | element += '
'; 265 | element += '
'; 266 | element += '
'; 267 | element += '
'; 268 | 269 | $('#modx-field').append(element); 270 | } 271 | 272 | /** 273 | * Add author field(s) 274 | */ 275 | function add_author() 276 | { 277 | var field_id = 'author_' + field_cnt++; 278 | var dd_id = 'dd_' + dd_cnt++; 279 | 280 | var element = '
'; 281 | element += '
'; 282 | element += '
'; 283 | element += '
'; 284 | element += ''; 285 | element += 'Delete'; 286 | element += '
'; 287 | element += '
'; 288 | 289 | element += '
'; 290 | element += '
'; 291 | element += '
'; 295 | element += '
'; 296 | 297 | element += '
'; 298 | element += '
'; 299 | element += '
'; 300 | element += ''; 301 | element += '
'; 302 | element += '
'; 303 | 304 | element += '
'; 305 | element += '
'; 306 | element += '
'; 307 | element += ''; 308 | element += '
'; 309 | element += '
'; 310 | element += '
'; 311 | element += '
'; 312 | element += '
'; 313 | element += ''; 314 | element += '
'; 315 | element += '
'; 316 | element += '
'; 317 | 318 | element += ' Info icon'; 319 | element += '
'; 320 | 321 | $('#authors').append(element); 322 | } 323 | 324 | /** 325 | * Add a contributor-field 326 | */ 327 | function add_contributor(field_id) 328 | { 329 | var temp = 'tm_' + field_cnt++; 330 | var dd_id = 'dd_' + dd_cnt++; 331 | 332 | var element = '
'; 333 | element += '
'; 334 | element += '
'; 335 | element += '
'; 336 | element += ''; 340 | element += ' Delete'; 341 | element += '
'; 342 | element += '
'; 343 | 344 | element += '
'; 345 | element += '
'; 346 | element += '
'; 347 | element += ''; 348 | element += '
'; 349 | element += '
'; 350 | 351 | element += '
'; 352 | element += '
'; 353 | element += '
'; 354 | element += ''; 355 | element += '
'; 356 | element += '
'; 357 | 358 | element += '
'; 359 | 360 | $('#' + field_id + '-pre').append(element); 361 | } 362 | 363 | /** 364 | * Add or remove the "To" field based on the status of the contributor 365 | */ 366 | function handle_contributor_to_field(dd_id, field_id, temp) 367 | { 368 | dd_id = '#' + dd_id; 369 | 370 | if ($(dd_id + ' dl dd select').val() == 'past') 371 | { 372 | var element = '
'; 373 | element += '
'; 374 | element += '
'; 375 | element += ''; 376 | element += '
'; 377 | element += '
'; 378 | $(dd_id).append(element); 379 | } 380 | else 381 | { 382 | $(dd_id + ' dl:last').remove(); 383 | } 384 | } 385 | 386 | /** 387 | * Add description 388 | */ 389 | function add_desc() 390 | { 391 | var field_id = 'desc_' + field_cnt++; 392 | var dd_id = 'dd_' + dd_cnt++; 393 | 394 | var element = '

'; 395 | element += ''; 396 | element += '
'; 397 | element += 'Delete'; 398 | element += 'Add 4 rows'; 399 | element += 'Remove  4 rows'; 400 | element += '
'; 401 | element += '
' + lang_select('desc[' + field_id + '][lang]') + ''; 422 | element += ''; 423 | 424 | element += '
'; 425 | element += ' » '; 426 | element += ''; 427 | element += 'Delete'; 428 | element += '
'; 429 | element += ''; 430 | element += ''; 431 | 432 | $('#copy-field').append(element); 433 | } 434 | 435 | /** 436 | * Add file copy 437 | */ 438 | function add_file_copy() 439 | { 440 | temp = 'tm_' + field_cnt++; 441 | var dd_id = 'dd_' + dd_cnt++; 442 | 443 | var element = '
'; 444 | element += ' » '; 445 | element += ''; 446 | element += 'Delete'; 447 | element += '
'; 448 | 449 | $('#dl-copy').append(element); 450 | } 451 | 452 | /** 453 | * Add the main delete-field 454 | */ 455 | function add_delete() 456 | { 457 | var field_id = 'fc_' + field_cnt++; 458 | var temp = 'tm_' + field_cnt++; 459 | var dd_id = 'dd_' + dd_cnt++; 460 | var dd_id2 = 'dd_' + dd_cnt++; 461 | 462 | var element = '
'; 463 | element += '
'; 464 | element += '
'; 465 | element += ''; 466 | element += 'Add fileDelete'; 467 | element += '
'; 468 | 469 | element += '
'; 470 | element += ''; 471 | element += 'Delete'; 472 | element += '
'; 473 | element += '
'; 474 | element += '
'; 475 | 476 | $('#delete-field').append(element); 477 | } 478 | 479 | /** 480 | * Add file delete 481 | */ 482 | function add_file_delete() 483 | { 484 | temp = 'tm_' + field_cnt++; 485 | var dd_id = 'dd_' + dd_cnt++; 486 | 487 | var element = '
'; 488 | element += ''; 489 | element += 'Delete'; 490 | element += '
'; 491 | 492 | $('#dl-delete').append(element); 493 | } 494 | 495 | /** 496 | * Add a history-field 497 | */ 498 | function add_history() 499 | { 500 | var field_id = 'hf_' + field_cnt++; 501 | var temp = 'logdd_' + dd_cnt++; 502 | var dd_id = 'dd_' + dd_cnt++; 503 | 504 | var element = '
'; 505 | element += '
'; 506 | element += '
'; 507 | element += '
'; 508 | element += ''; 509 | element += ''; 510 | element += '
'; 511 | element += '
'; 512 | 513 | element += '
'; 514 | element += '
'; 515 | element += '
'; 516 | element += ''; 517 | element += ' (The date format needs to be YYYY-MM-DD)'; 518 | element += '
'; 519 | element += '
'; 520 | 521 | element += '
'; 522 | element += '
'; 523 | element += '
'; 524 | element += '
'; 525 | element += ''; 526 | element += '
'; 527 | element += '
'; 528 | element += ''; 529 | element += '' + lang_select('history[' + field_id + '][changelog][' + temp + '][lang]') + ''; 530 | element += '
'; 531 | element += '
'; 532 | element += '
'; 533 | 534 | element += ''; 535 | element += '
'; 536 | 537 | $('#history-fields').append(element); 538 | } 539 | 540 | /** 541 | * Add a change to the history 542 | */ 543 | function add_history_change(field_id) 544 | { 545 | var temp = 'logdd_' + dd_cnt++; 546 | var dd_id = 'dd_' + dd_cnt++; 547 | 548 | var element = '
'; 549 | element += '
'; 550 | element += '
'; 551 | element += '
'; 552 | element += ''; 553 | element += '
'; 554 | element += '
'; 555 | element += ''; 556 | element += '' + lang_select('history[' + field_id + '][changelog][' + temp + '][lang]') + ''; 557 | element += ' '; 558 | element += '
'; 559 | element += '
'; 560 | element += '
'; 561 | 562 | $('#' + field_id).append(element); 563 | } 564 | 565 | /** 566 | * Add link-field 567 | */ 568 | function add_link() 569 | { 570 | var field_id = 'lf_' + field_cnt++; 571 | var dd_id = 'dd_' + dd_cnt++; 572 | 573 | var element = '
'; 574 | element += '
'; 575 | element += '
'; 576 | element += '
'; 577 | element += ''; 587 | element += ' '; 588 | element += '
'; 589 | element += '
'; 590 | 591 | element += '
'; 592 | element += '
'; 593 | element += '
'; 594 | element += ''; 595 | element += lang_select('links[' + field_id + '][lang]'); 596 | element += '
'; 597 | element += '
'; 598 | 599 | element += '
'; 600 | element += '
'; 601 | element += '
'; 602 | element += ''; 603 | element += '
'; 604 | element += '
'; 605 | element += '
'; 606 | 607 | $('#link-field').append(element); 608 | } 609 | 610 | /** 611 | * Add notes 612 | */ 613 | function add_notes() 614 | { 615 | var field_id = 'notes_' + field_cnt++; 616 | var dd_id = 'dd_' + dd_cnt++; 617 | 618 | var element = '

'; 619 | element += ''; 620 | element += '
'; 621 | element += 'Delete'; 622 | element += 'Add 4 rows'; 623 | element += 'Scale'; 624 | element += '
'; 625 | element += lang_select('notes[' + field_id + '][lang]'); 626 | element += '
'; 627 | 628 | $('#notes-field').append(element); 629 | } 630 | 631 | /** 632 | * Add diy 633 | */ 634 | function add_diy() 635 | { 636 | var field_id = 'diy_' + field_cnt++; 637 | var dd_id = 'dd_' + dd_cnt++; 638 | 639 | var element = '

'; 640 | element += ''; 641 | element += '
'; 642 | element += 'Delete'; 643 | element += 'Make bigger'; 644 | element += 'Make smaller'; 645 | element += '
'; 646 | element += lang_select('diy[' + field_id + '][lang]'); 647 | element += '
'; 648 | 649 | $('#diy-field').append(element); 650 | } 651 | 652 | /** 653 | * Add SQL-field 654 | */ 655 | function add_sql() 656 | { 657 | var field_id = 'sql_' + field_cnt++; 658 | var dd_id = 'dd_' + dd_cnt++; 659 | 660 | var element = '
'; 661 | element += '
'; 662 | element += '
'; 663 | element += '
'; 664 | element += ''; 674 | element += '
'; 675 | element += '
'; 676 | 677 | element += '
'; 678 | element += '
'; 679 | element += '
'; 680 | element += ''; 681 | element += '
'; 682 | element += 'Delete'; 683 | element += 'Add rows'; 684 | element += 'Remove rows'; 685 | element += '
'; 686 | element += '
'; 687 | element += '
'; 688 | element += '
'; 689 | 690 | $('#sql-field').append(element); 691 | } 692 | 693 | /** 694 | * Add title 695 | */ 696 | function add_title() 697 | { 698 | var field_id = 'title_' + field_cnt++; 699 | var dd_id = 'dd_' + dd_cnt++; 700 | 701 | var element = '
'; 702 | element += ' '; 703 | element += lang_select('title[' + field_id + '][lang]'); 704 | element += ' Delete'; 705 | element += '
'; 706 | 707 | $('#title-field').append(element); 708 | } 709 | 710 | /** 711 | * Counts the number of rows needed for