├── .gitignore ├── assets └── components │ └── ajaxform │ ├── index.html │ ├── css │ ├── default.css │ └── lib │ │ └── jquery.jgrowl.min.css │ ├── action.php │ └── js │ ├── lib │ ├── jquery.jgrowl.min.js │ ├── jquery.jgrowl.map │ ├── jquery.form.min.js │ └── jquery.min.js │ └── default.js ├── _build ├── includes │ └── functions.php ├── data │ ├── transport.chunks.php │ └── transport.snippets.php ├── properties │ └── properties.ajaxform.php ├── build.config.php └── build.transport.php ├── core └── components │ └── ajaxform │ ├── docs │ ├── readme.txt │ ├── changelog.txt │ └── license.txt │ ├── lexicon │ ├── en │ │ ├── properties.inc.php │ │ └── default.inc.php │ ├── uk │ │ ├── properties.inc.php │ │ └── default.inc.php │ └── ru │ │ ├── properties.inc.php │ │ └── default.inc.php │ ├── elements │ ├── chunks │ │ └── chunk.example.tpl │ └── snippets │ │ └── snippet.ajaxform.php │ └── model │ └── ajaxform │ └── ajaxform.class.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | config.core.php -------------------------------------------------------------------------------- /assets/components/ajaxform/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_build/includes/functions.php: -------------------------------------------------------------------------------- 1 | ')); 14 | } -------------------------------------------------------------------------------- /core/components/ajaxform/docs/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------- 2 | AjaxForm 3 | -------------------- 4 | Author: Vasiliy Naumkin 5 | -------------------- 6 | 7 | Simple component for MODX Revolution, that allows you to send any form through ajax. 8 | 9 | 10 | Quick start 11 | 1. Create new chunk with name "myForm". 12 | 2. Add form into that chunk. 13 | 3. Call AjaxForm at any page [[!AjaxForm?form=`myForm`&snippet=`FormIt`]] 14 | 15 | You can specify any parameters for end snippet: 16 | [[!AjaxForm? 17 | &form=`myForm` 18 | &snippet=`FormIt` 19 | &hooks=`email` 20 | &emailto=`info@mysite.com` 21 | &etc=`...` 22 | ]] 23 | 24 | -------------------- 25 | Feel free to suggest ideas/improvements/bugs on GitHub: 26 | http://github.com/bezumkin/AjaxForm/issues -------------------------------------------------------------------------------- /assets/components/ajaxform/css/default.css: -------------------------------------------------------------------------------- 1 | @import url('./lib/jquery.jgrowl.min.css'); 2 | .af-message-success { background-color: green !important; } 3 | .af-message-error { background-color: brown !important; } 4 | .af-message-info { background-color: black !important; } 5 | .ajax_form.af_example { 6 | width: 100%; 7 | } 8 | .ajax_form.af_example .controls input, 9 | .ajax_form.af_example .controls textarea { 10 | width: 100%; 11 | } 12 | .ajax_form .error { 13 | color: brown; 14 | } 15 | @media screen and (min-width: 320px) { 16 | .ajax_form.af_example .controls button[type="submit"] { 17 | float: right; 18 | } 19 | } 20 | @media screen and (max-width: 320px) { 21 | .ajax_form.af_example .controls button { 22 | width: 100%; 23 | margin-top: 5px; 24 | } 25 | } -------------------------------------------------------------------------------- /core/components/ajaxform/lexicon/en/properties.inc.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'file' => 'example', 8 | 'description' => '', 9 | ), 10 | ); 11 | 12 | foreach ($tmp as $k => $v) { 13 | /** @var modChunk $chunk */ 14 | $chunk = $modx->newObject('modChunk'); 15 | /** @noinspection PhpUndefinedVariableInspection */ 16 | $chunk->fromArray(array( 17 | 'id' => 0, 18 | 'name' => $k, 19 | 'description' => @$v['description'], 20 | 'snippet' => file_get_contents($sources['source_core'] . '/elements/chunks/chunk.' . $v['file'] . '.tpl'), 21 | 'static' => BUILD_CHUNK_STATIC, 22 | 'source' => 1, 23 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/chunk.' . $v['file'] . '.tpl', 24 | ), '', true, true); 25 | 26 | $chunks[] = $chunk; 27 | } 28 | unset($tmp); 29 | 30 | return $chunks; 31 | -------------------------------------------------------------------------------- /core/components/ajaxform/lexicon/en/default.inc.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'file' => 'ajaxform', 8 | 'description' => '', 9 | ), 10 | ); 11 | 12 | foreach ($tmp as $k => $v) { 13 | /** @var modSnippet $snippet */ 14 | $snippet = $modx->newObject('modSnippet'); 15 | /** @noinspection PhpUndefinedVariableInspection */ 16 | $snippet->fromArray(array( 17 | 'id' => 0, 18 | 'name' => $k, 19 | 'description' => @$v['description'], 20 | 'snippet' => getSnippetContent($sources['source_core'] . '/elements/snippets/snippet.' . $v['file'] . '.php'), 21 | 'static' => BUILD_SNIPPET_STATIC, 22 | 'source' => 1, 23 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/snippet.' . $v['file'] . '.php', 24 | ), '', true, true); 25 | 26 | /** @noinspection PhpIncludeInspection */ 27 | $properties = include $sources['build'] . 'properties/properties.' . $v['file'] . '.php'; 28 | $snippet->setProperties($properties); 29 | 30 | $snippets[] = $snippet; 31 | } 32 | unset($tmp, $properties); 33 | 34 | return $snippets; 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | | :warning: On June 13, 2023, [MODX RSC](https://github.com/modx-pro/) will end support for AjaxForm. It will still be available on [modstore.pro](https://modstore.pro/packages/utilities/ajaxform) and [extras.modx.com](https://extras.modx.com/package/ajaxform) marketplaces, but we recommend using [FetchIt](https://github.com/GulomovCreative/FetchIt). | 2 | | --- 3 | 4 | | :warning: 13 июня 2023 года команда [MODX RSC](https://github.com/modx-pro/) прекратила поддержку AjaxForm. Он будет продолжать быть доступным на маркетплейсах [modstore.pro](https://modstore.pro/packages/utilities/ajaxform) и [extras.modx.com](https://extras.modx.com/package/ajaxform), но мы рекомендуем использовать вместо него компонент [FetchIt](https://github.com/GulomovCreative/FetchIt). | 5 | | --- 6 | 7 | ## AjaxForm 8 | 9 | Simple component for MODX Revolution, that allows you to send any form through ajax. 10 | 11 | ## Quick start 12 | 1. Create new chunk with name "myForm". 13 | 2. Add form with class="ajax_form" into that chunk. 14 | 3. Call AjaxForm at any page 15 | ``` 16 | [[!AjaxForm?form=`myForm`&snippet=`FormIt`]] 17 | ``` 18 | 19 | You can specify any parameters for end snippet: 20 | ``` 21 | [[!AjaxForm? 22 | &form=`myForm` 23 | &snippet=`FormIt` 24 | &hooks=`email` 25 | &emailTo=`info@mysite.com` 26 | &etc=`...` 27 | ]] 28 | ``` 29 | -------------------------------------------------------------------------------- /assets/components/ajaxform/action.php: -------------------------------------------------------------------------------- 1 | getService('error', 'error.modError'); 6 | $modx->setLogLevel(modX::LOG_LEVEL_ERROR); 7 | $modx->setLogTarget('FILE'); 8 | 9 | // Switch context if need 10 | if (!empty($_REQUEST['pageId'])) { 11 | if ($resource = $modx->getObject('modResource', (int)$_REQUEST['pageId'])) { 12 | if ($resource->get('context_key') != 'web') { 13 | $modx->switchContext($resource->get('context_key')); 14 | } 15 | $modx->resource = $resource; 16 | } 17 | } 18 | 19 | /** @var AjaxForm $AjaxForm */ 20 | $AjaxForm = $modx->getService('ajaxform', 'AjaxForm', $modx->getOption('ajaxform_core_path', null, 21 | $modx->getOption('core_path') . 'components/ajaxform/') . 'model/ajaxform/', array()); 22 | 23 | if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') { 24 | $modx->sendRedirect($modx->makeUrl($modx->getOption('site_start'), '', '', 'full')); 25 | } elseif (empty($_REQUEST['af_action'])) { 26 | echo $AjaxForm->error('af_err_action_ns'); 27 | } else { 28 | echo $AjaxForm->process($_REQUEST['af_action'], array_merge($_FILES, $_REQUEST)); 29 | } 30 | 31 | @session_write_close(); -------------------------------------------------------------------------------- /_build/properties/properties.ajaxform.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'type' => 'textfield', 8 | 'value' => 'tpl.AjaxForm.example', 9 | ), 10 | 'snippet' => array( 11 | 'type' => 'textfield', 12 | 'value' => 'FormIt', 13 | ), 14 | 'frontend_css' => array( 15 | 'type' => 'textfield', 16 | 'value' => '[[+assetsUrl]]css/default.css', 17 | ), 18 | 'frontend_js' => array( 19 | 'type' => 'textfield', 20 | 'value' => '[[+assetsUrl]]js/default.js', 21 | ), 22 | 'actionUrl' => array( 23 | 'type' => 'textfield', 24 | 'value' => '[[+assetsUrl]]action.php', 25 | ), 26 | 'formSelector' => array( 27 | 'type' => 'textfield', 28 | 'value' => 'ajax_form', 29 | ), 30 | 'objectName' => array( 31 | 'type' => 'textfield', 32 | 'value' => 'AjaxForm', 33 | ), 34 | 'clearFieldsOnSuccess' => array( 35 | 'type' => 'combo-boolean', 36 | 'value' => true, 37 | ), 38 | ); 39 | 40 | foreach ($tmp as $k => $v) { 41 | $properties[] = array_merge( 42 | array( 43 | 'name' => $k, 44 | 'desc' => PKG_NAME_LOWER . '_prop_' . $k, 45 | 'lexicon' => PKG_NAME_LOWER . ':properties', 46 | ), $v 47 | ); 48 | } 49 | 50 | return $properties; 51 | -------------------------------------------------------------------------------- /assets/components/ajaxform/css/lib/jquery.jgrowl.min.css: -------------------------------------------------------------------------------- 1 | .jGrowl{z-index:9999;color:#fff;font-size:12px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:fixed}.jGrowl.top-left{left:0;top:0}.jGrowl.top-right{right:0;top:0}.jGrowl.bottom-left{left:0;bottom:0}.jGrowl.bottom-right{right:0;bottom:0}.jGrowl.center{top:0;width:50%;left:25%}.jGrowl.center .jGrowl-closer,.jGrowl.center .jGrowl-notification{margin-left:auto;margin-right:auto}.jGrowl-notification{background-color:#000;opacity:.9;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100));-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100));zoom:1;width:250px;padding:10px;margin:10px;text-align:left;display:none;border-radius:5px;min-height:40px}.jGrowl-notification .ui-state-highlight,.jGrowl-notification .ui-widget-content .ui-state-highlight,.jGrowl-notification .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}.jGrowl-notification .jGrowl-header{font-weight:700;font-size:.85em}.jGrowl-notification .jGrowl-close{background-color:transparent;color:inherit;border:none;z-index:99;float:right;font-weight:700;font-size:1em;cursor:pointer}.jGrowl-closer{background-color:#000;opacity:.9;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100));-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100));zoom:1;width:250px;padding:10px;margin:10px;display:none;border-radius:5px;padding-top:4px;padding-bottom:4px;cursor:pointer;font-size:.9em;font-weight:700;text-align:center}.jGrowl-closer .ui-state-highlight,.jGrowl-closer .ui-widget-content .ui-state-highlight,.jGrowl-closer .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}@media print{.jGrowl{display:none}} -------------------------------------------------------------------------------- /core/components/ajaxform/elements/chunks/chunk.example.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 | [[+fi.error.name]] 8 |
9 |
10 | 11 |
12 | 13 |
14 | 15 | [[+fi.error.email]] 16 |
17 |
18 | 19 |
20 | 21 |
22 | 23 | [[+fi.error.message]] 24 |
25 |
26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | [[+fi.success:is=`1`:then=` 35 |
[[+fi.successMessage]]
36 | `]] 37 | [[+fi.validation_error:is=`1`:then=` 38 |
[[+fi.validation_error_message]]
39 | `]] 40 |
41 | -------------------------------------------------------------------------------- /_build/build.config.php: -------------------------------------------------------------------------------- 1 | loadClass('ajaxform', MODX_CORE_PATH . 'components/ajaxform/model/ajaxform/', false, true)) { 6 | return false; 7 | } 8 | $AjaxForm = new AjaxForm($modx, $scriptProperties); 9 | 10 | $snippet = $modx->getOption('snippet', $scriptProperties, 'FormIt', true); 11 | $tpl = $modx->getOption('form', $scriptProperties, 'tpl.AjaxForm.example', true); 12 | $formSelector = $modx->getOption('formSelector', $scriptProperties, 'ajax_form', true); 13 | $objectName = $modx->getOption('objectName', $scriptProperties, 'AjaxForm', true); 14 | $AjaxForm->loadJsCss($objectName); 15 | 16 | /** @var pdoTools $pdo */ 17 | if (class_exists('pdoTools') && $pdo = $modx->getService('pdoTools')) { 18 | $content = $pdo->getChunk($tpl, $scriptProperties); 19 | } else { 20 | $content = $modx->getChunk($tpl, $scriptProperties); 21 | } 22 | if (empty($content)) { 23 | return $modx->lexicon('af_err_chunk_nf', array('name' => $tpl)); 24 | } 25 | 26 | // Add selector to tag form 27 | if (preg_match('#'; 52 | if ((stripos($content, '') !== false)) { 53 | if (preg_match('##i', $content, $matches)) { 54 | $content = str_ireplace($matches[0], '', $content); 55 | } 56 | $content = str_ireplace('', "\n\t$action\n", $content); 57 | } 58 | 59 | // Save snippet properties 60 | if (!empty(session_id())) { 61 | // ... to user`s session 62 | $_SESSION['AjaxForm'][$hash] = $scriptProperties; 63 | } else { 64 | // ... to cache file 65 | $modx->cacheManager->set('ajaxform/props_' . $hash, $scriptProperties, 3600); 66 | } 67 | 68 | // Call snippet for preparation of form 69 | $action = !empty($_REQUEST['af_action']) 70 | ? $_REQUEST['af_action'] 71 | : $hash; 72 | 73 | $AjaxForm->process($action, $_REQUEST); 74 | 75 | // Return chunk 76 | return $content; 77 | -------------------------------------------------------------------------------- /core/components/ajaxform/docs/changelog.txt: -------------------------------------------------------------------------------- 1 | 1.2.2-pl 2 | ============== 3 | - Fixed JS error `undefined is not an object (evaluating '$submitter.length')` 4 | 5 | 1.2.1-pl 6 | ============== 7 | - Fixed JS error `Cannot read properties of undefined (reading 'defaults')` 8 | 9 | 1.2.0-pl 10 | ============== 11 | - Added Ukrainian lexicons 12 | - Added `clearFieldsOnSuccess` snippet parameter 13 | - Added work with disabled sessions for anonymous users 14 | - Fixed adding the value of the button you clicked to submit the form to the submitted data 15 | - Fixed: `document.write` has been replaced by `document.body.appendChild` 16 | - Fixed: cut `type="text/javascript"` from the `"); 90 | } 91 | 92 | 93 | /** 94 | * Loads snippet for form processing 95 | * 96 | * @param $action 97 | * @param array $fields 98 | * 99 | * @return array|string 100 | */ 101 | public function process($action, array $fields = array()) 102 | { 103 | $scriptProperties = !empty(session_id()) 104 | ? @$_SESSION['AjaxForm'][$action] 105 | : $this->modx->cacheManager->get('ajaxform/props_' . $action); 106 | if (empty($scriptProperties)) { 107 | return $this->error('af_err_action_nf'); 108 | } 109 | unset($fields['af_action'], $_POST['af_action']); 110 | 111 | $scriptProperties['fields'] = $fields; 112 | $scriptProperties['AjaxForm'] = $this; 113 | 114 | $name = $scriptProperties['snippet']; 115 | $set = ''; 116 | if (strpos($name, '@') !== false) { 117 | list($name, $set) = explode('@', $name); 118 | } 119 | 120 | /** @var modSnippet $snippet */ 121 | if ($snippet = $this->modx->getObject('modSnippet', array('name' => $name))) { 122 | $properties = $snippet->getProperties(); 123 | $property_set = !empty($set) 124 | ? $snippet->getPropertySet($set) 125 | : array(); 126 | 127 | $scriptProperties = array_merge($properties, $property_set, $scriptProperties); 128 | $snippet->_cacheable = false; 129 | $snippet->_processed = false; 130 | 131 | $response = $snippet->process($scriptProperties); 132 | if (strtolower($snippet->name) == 'formit') { 133 | $response = $this->handleFormIt($scriptProperties); 134 | } 135 | 136 | return $response; 137 | } else { 138 | return $this->error('af_err_snippet_nf', array(), array('name' => $name)); 139 | } 140 | } 141 | 142 | 143 | /** 144 | * Method for obtaining data from FormIt 145 | * 146 | * @param array $scriptProperties 147 | * 148 | * @return array|string 149 | */ 150 | public function handleFormIt(array $scriptProperties = array()) 151 | { 152 | $plPrefix = isset($scriptProperties['placeholderPrefix']) 153 | ? $scriptProperties['placeholderPrefix'] 154 | : 'fi.'; 155 | 156 | $errors = array(); 157 | foreach ($scriptProperties['fields'] as $k => $v) { 158 | if (isset($this->modx->placeholders[$plPrefix . 'error.' . $k])) { 159 | $errors[$k] = $this->modx->placeholders[$plPrefix . 'error.' . $k]; 160 | } 161 | } 162 | 163 | if (!empty($this->modx->placeholders[$plPrefix . 'error.recaptcha'])) { 164 | $errors['recaptcha'] = $this->modx->placeholders[$plPrefix . 'error.recaptcha']; 165 | } 166 | 167 | if (!empty($this->modx->placeholders[$plPrefix . 'error.recaptchav2_error'])) { 168 | $errors['recaptcha'] = $this->modx->placeholders[$plPrefix . 'error.recaptchav2_error']; 169 | } 170 | 171 | if (!empty($errors)) { 172 | $message = !empty($this->modx->placeholders[$plPrefix . 'validation_error_message']) 173 | ? $this->modx->placeholders[$plPrefix . 'validation_error_message'] 174 | : 'af_err_has_errors'; 175 | $status = 'error'; 176 | } else { 177 | $message = isset($this->modx->placeholders[$plPrefix . 'successMessage']) 178 | ? $this->modx->placeholders[$plPrefix . 'successMessage'] 179 | : 'af_success_submit'; 180 | $status = 'success'; 181 | } 182 | 183 | return $this->$status($message, $errors); 184 | } 185 | 186 | 187 | /** 188 | * This method returns an error of the order 189 | * 190 | * @param string $message A lexicon key for error message 191 | * @param array $data .Additional data, for example cart status 192 | * @param array $placeholders Array with placeholders for lexicon entry 193 | * 194 | * @return array|string $response 195 | */ 196 | public function error($message = '', $data = array(), $placeholders = array()) 197 | { 198 | $response = array( 199 | 'success' => false, 200 | 'message' => $this->modx->lexicon($message, $placeholders), 201 | 'data' => $data, 202 | ); 203 | 204 | return $this->config['json_response'] 205 | ? $this->modx->toJSON($response) 206 | : $response; 207 | } 208 | 209 | 210 | /** 211 | * This method returns an success of the order 212 | * 213 | * @param string $message A lexicon key for success message 214 | * @param array $data .Additional data, for example cart status 215 | * @param array $placeholders Array with placeholders for lexicon entry 216 | * 217 | * @return array|string $response 218 | */ 219 | public function success($message = '', $data = array(), $placeholders = array()) 220 | { 221 | $response = array( 222 | 'success' => true, 223 | 'message' => $this->modx->lexicon($message, $placeholders), 224 | 'data' => $data, 225 | ); 226 | 227 | return $this->config['json_response'] 228 | ? $this->modx->toJSON($response) 229 | : $response; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /_build/build.transport.php: -------------------------------------------------------------------------------- 1 | $root, 15 | 'build' => $root . '_build/', 16 | 'data' => $root . '_build/data/', 17 | 'resolvers' => $root . '_build/resolvers/', 18 | 'chunks' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/', 19 | 'snippets' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/', 20 | 'plugins' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/plugins/', 21 | 'lexicon' => $root . 'core/components/' . PKG_NAME_LOWER . '/lexicon/', 22 | 'docs' => $root . 'core/components/' . PKG_NAME_LOWER . '/docs/', 23 | 'pages' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/pages/', 24 | 'source_assets' => $root . 'assets/components/' . PKG_NAME_LOWER, 25 | 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER, 26 | ); 27 | unset($root); 28 | 29 | require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; 30 | require_once $sources['build'] . '/includes/functions.php'; 31 | 32 | $modx = new modX(); 33 | $modx->initialize('mgr'); 34 | echo '
'; /* used for nice formatting of log messages */
 35 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
 36 | $modx->setLogTarget('ECHO');
 37 | $modx->getService('error', 'error.modError');
 38 | 
 39 | $modx->loadClass('transport.modPackageBuilder', '', false, true);
 40 | $builder = new modPackageBuilder($modx);
 41 | $builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE);
 42 | $builder->registerNamespace(PKG_NAME_LOWER, false, true, '{core_path}components/' . PKG_NAME_LOWER . '/');
 43 | $modx->log(modX::LOG_LEVEL_INFO, 'Created Transport Package and Namespace.');
 44 | 
 45 | /* load system settings */
 46 | if (defined('BUILD_SETTING_UPDATE')) {
 47 |     $settings = include $sources['data'] . 'transport.settings.php';
 48 |     if (!is_array($settings)) {
 49 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.');
 50 |     } else {
 51 |         $attributes = array(
 52 |             xPDOTransport::UNIQUE_KEY => 'key',
 53 |             xPDOTransport::PRESERVE_KEYS => true,
 54 |             xPDOTransport::UPDATE_OBJECT => BUILD_SETTING_UPDATE,
 55 |         );
 56 |         foreach ($settings as $setting) {
 57 |             $vehicle = $builder->createVehicle($setting, $attributes);
 58 |             $builder->putVehicle($vehicle);
 59 |         }
 60 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($settings) . ' System Settings.');
 61 |     }
 62 |     unset($settings, $setting, $attributes);
 63 | }
 64 | 
 65 | /* load plugins events */
 66 | if (defined('BUILD_EVENT_UPDATE')) {
 67 |     $events = include $sources['data'] . 'transport.events.php';
 68 |     if (!is_array($events)) {
 69 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in events.');
 70 |     } else {
 71 |         $attributes = array(
 72 |             xPDOTransport::PRESERVE_KEYS => true,
 73 |             xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE,
 74 |         );
 75 |         foreach ($events as $event) {
 76 |             $vehicle = $builder->createVehicle($event, $attributes);
 77 |             $builder->putVehicle($vehicle);
 78 |         }
 79 |         $modx->log(xPDO::LOG_LEVEL_INFO, 'Packaged in ' . count($events) . ' Plugins events.');
 80 |     }
 81 |     unset ($events, $event, $attributes);
 82 | }
 83 | 
 84 | /* package in default access policy */
 85 | if (defined('BUILD_POLICY_UPDATE')) {
 86 |     $attributes = array(
 87 |         xPDOTransport::PRESERVE_KEYS => false,
 88 |         xPDOTransport::UNIQUE_KEY => array('name'),
 89 |         xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_UPDATE,
 90 |     );
 91 |     $policies = include $sources['data'] . 'transport.policies.php';
 92 |     if (!is_array($policies)) {
 93 |         $modx->log(modX::LOG_LEVEL_FATAL, 'Adding policies failed.');
 94 |     }
 95 |     foreach ($policies as $policy) {
 96 |         $vehicle = $builder->createVehicle($policy, $attributes);
 97 |         $builder->putVehicle($vehicle);
 98 |     }
 99 |     $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($policies) . ' Access Policies.');
100 |     flush();
101 |     unset($policies, $policy, $attributes);
102 | }
103 | 
104 | /* package in default access policy templates */
105 | if (defined('BUILD_POLICY_TEMPLATE_UPDATE')) {
106 |     $templates = include dirname(__FILE__) . '/data/transport.policytemplates.php';
107 |     $attributes = array(
108 |         xPDOTransport::PRESERVE_KEYS => false,
109 |         xPDOTransport::UNIQUE_KEY => array('name'),
110 |         xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_TEMPLATE_UPDATE,
111 |         xPDOTransport::RELATED_OBJECTS => true,
112 |         xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
113 |             'Permissions' => array(
114 |                 xPDOTransport::PRESERVE_KEYS => false,
115 |                 xPDOTransport::UPDATE_OBJECT => BUILD_PERMISSION_UPDATE,
116 |                 xPDOTransport::UNIQUE_KEY => array('template', 'name'),
117 |             ),
118 |         ),
119 |     );
120 |     if (is_array($templates)) {
121 |         foreach ($templates as $template) {
122 |             $vehicle = $builder->createVehicle($template, $attributes);
123 |             $builder->putVehicle($vehicle);
124 |         }
125 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($templates) . ' Access Policy Templates.');
126 |         flush();
127 |     } else {
128 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in Access Policy Templates.');
129 |     }
130 |     unset ($templates, $template, $attributes);
131 | }
132 | 
133 | /* load menus */
134 | if (defined('BUILD_MENU_UPDATE')) {
135 |     $menus = include $sources['data'] . 'transport.menu.php';
136 |     $attributes = array(
137 |         xPDOTransport::PRESERVE_KEYS => true,
138 |         xPDOTransport::UPDATE_OBJECT => BUILD_MENU_UPDATE,
139 |         xPDOTransport::UNIQUE_KEY => 'text',
140 |         xPDOTransport::RELATED_OBJECTS => true,
141 |         xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
142 |             'Action' => array(
143 |                 xPDOTransport::PRESERVE_KEYS => false,
144 |                 xPDOTransport::UPDATE_OBJECT => BUILD_ACTION_UPDATE,
145 |                 xPDOTransport::UNIQUE_KEY => array('namespace', 'controller'),
146 |             ),
147 |         ),
148 |     );
149 |     if (is_array($menus)) {
150 |         foreach ($menus as $menu) {
151 |             $vehicle = $builder->createVehicle($menu, $attributes);
152 |             $builder->putVehicle($vehicle);
153 |             /** @var modMenu $menu */
154 |             $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in menu "' . $menu->get('text') . '".');
155 |         }
156 |     } else {
157 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in menu.');
158 |     }
159 |     unset($vehicle, $menus, $menu, $attributes);
160 | }
161 | 
162 | 
163 | /* create category */
164 | $modx->log(xPDO::LOG_LEVEL_INFO, 'Created category.');
165 | /** @var modCategory $category */
166 | $category = $modx->newObject('modCategory');
167 | $category->set('category', PKG_NAME);
168 | /* create category vehicle */
169 | $attr = array(
170 |     xPDOTransport::UNIQUE_KEY => 'category',
171 |     xPDOTransport::PRESERVE_KEYS => false,
172 |     xPDOTransport::UPDATE_OBJECT => true,
173 |     xPDOTransport::RELATED_OBJECTS => true,
174 | );
175 | 
176 | /* add snippets */
177 | if (defined('BUILD_SNIPPET_UPDATE')) {
178 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Snippets'] = array(
179 |         xPDOTransport::PRESERVE_KEYS => false,
180 |         xPDOTransport::UPDATE_OBJECT => BUILD_SNIPPET_UPDATE,
181 |         xPDOTransport::UNIQUE_KEY => 'name',
182 |     );
183 |     $snippets = include $sources['data'] . 'transport.snippets.php';
184 |     if (!is_array($snippets)) {
185 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.');
186 |     } else {
187 |         $category->addMany($snippets);
188 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($snippets) . ' snippets.');
189 |     }
190 | }
191 | 
192 | /* add chunks */
193 | if (defined('BUILD_CHUNK_UPDATE')) {
194 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Chunks'] = array(
195 |         xPDOTransport::PRESERVE_KEYS => false,
196 |         xPDOTransport::UPDATE_OBJECT => BUILD_CHUNK_UPDATE,
197 |         xPDOTransport::UNIQUE_KEY => 'name',
198 |     );
199 |     $chunks = include $sources['data'] . 'transport.chunks.php';
200 |     if (!is_array($chunks)) {
201 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in chunks.');
202 |     } else {
203 |         $category->addMany($chunks);
204 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($chunks) . ' chunks.');
205 |     }
206 | }
207 | 
208 | /* add plugins */
209 | if (defined('BUILD_PLUGIN_UPDATE')) {
210 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = array(
211 |         xPDOTransport::PRESERVE_KEYS => false,
212 |         xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE,
213 |         xPDOTransport::UNIQUE_KEY => 'name',
214 |     );
215 |     $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['PluginEvents'] = array(
216 |         xPDOTransport::PRESERVE_KEYS => true,
217 |         xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE,
218 |         xPDOTransport::UNIQUE_KEY => array('pluginid', 'event'),
219 |     );
220 |     $plugins = include $sources['data'] . 'transport.plugins.php';
221 |     if (!is_array($plugins)) {
222 |         $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in plugins.');
223 |     } else {
224 |         $category->addMany($plugins);
225 |         $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($plugins) . ' plugins.');
226 |     }
227 | }
228 | 
229 | $vehicle = $builder->createVehicle($category, $attr);
230 | 
231 | /* now pack in resolvers */
232 | $vehicle->resolve('file', array(
233 |     'source' => $sources['source_assets'],
234 |     'target' => "return MODX_ASSETS_PATH . 'components/';",
235 | ));
236 | $vehicle->resolve('file', array(
237 |     'source' => $sources['source_core'],
238 |     'target' => "return MODX_CORE_PATH . 'components/';",
239 | ));
240 | 
241 | foreach ($BUILD_RESOLVERS as $resolver) {
242 |     if ($vehicle->resolve('php', array('source' => $sources['resolvers'] . 'resolve.' . $resolver . '.php'))) {
243 |         $modx->log(modX::LOG_LEVEL_INFO, 'Added resolver "' . $resolver . '" to category.');
244 |     } else {
245 |         $modx->log(modX::LOG_LEVEL_INFO, 'Could not add resolver "' . $resolver . '" to category.');
246 |     }
247 | }
248 | 
249 | flush();
250 | $builder->putVehicle($vehicle);
251 | 
252 | /* now pack in the license file, readme and setup options */
253 | $builder->setPackageAttributes(array(
254 |     'changelog' => file_get_contents($sources['docs'] . 'changelog.txt')
255 | ,
256 |     'license' => file_get_contents($sources['docs'] . 'license.txt')
257 | ,
258 |     'readme' => file_get_contents($sources['docs'] . 'readme.txt')
259 |     /*
260 |     ,'setup-options' => array(
261 |         'source' => $sources['build'].'setup.options.php',
262 |     ),
263 |     */
264 | ));
265 | $modx->log(modX::LOG_LEVEL_INFO, 'Added package attributes and setup options.');
266 | 
267 | /* zip up package */
268 | $modx->log(modX::LOG_LEVEL_INFO, 'Packing up transport package zip...');
269 | $builder->pack();
270 | 
271 | $mtime = microtime();
272 | $mtime = explode(" ", $mtime);
273 | $mtime = $mtime[1] + $mtime[0];
274 | $tend = $mtime;
275 | $totalTime = ($tend - $tstart);
276 | $totalTime = sprintf("%2.4f s", $totalTime);
277 | 
278 | if (defined('PKG_AUTO_INSTALL') && PKG_AUTO_INSTALL) {
279 |     $signature = $builder->getSignature();
280 |     $sig = explode('-', $signature);
281 |     $versionSignature = explode('.', $sig[1]);
282 | 
283 |     /** @var modTransportPackage $package */
284 |     if (!$package = $modx->getObject('transport.modTransportPackage', array('signature' => $signature))) {
285 |         $package = $modx->newObject('transport.modTransportPackage');
286 |         $package->set('signature', $signature);
287 |         $package->fromArray(array(
288 |             'created' => date('Y-m-d h:i:s'),
289 |             'updated' => null,
290 |             'state' => 1,
291 |             'workspace' => 1,
292 |             'provider' => 0,
293 |             'source' => $signature . '.transport.zip',
294 |             'package_name' => $sig[0],
295 |             'version_major' => $versionSignature[0],
296 |             'version_minor' => !empty($versionSignature[1]) ? $versionSignature[1] : 0,
297 |             'version_patch' => !empty($versionSignature[2]) ? $versionSignature[2] : 0,
298 |         ));
299 |         if (!empty($sig[2])) {
300 |             $r = preg_split('/([0-9]+)/', $sig[2], -1, PREG_SPLIT_DELIM_CAPTURE);
301 |             if (is_array($r) && !empty($r)) {
302 |                 $package->set('release', $r[0]);
303 |                 $package->set('release_index', (isset($r[1]) ? $r[1] : '0'));
304 |             } else {
305 |                 $package->set('release', $sig[2]);
306 |             }
307 |         }
308 |         $package->save();
309 |     }
310 | 
311 |     if ($package->install()) {
312 |         $modx->runProcessor('system/clearcache');
313 |     }
314 | }
315 | if (!empty($_GET['download'])) {
316 |     echo '';
317 | }
318 | 
319 | $modx->log(modX::LOG_LEVEL_INFO, "\n
Execution time: {$totalTime}\n"); 320 | echo '
'; -------------------------------------------------------------------------------- /assets/components/ajaxform/js/lib/jquery.form.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Form Plugin; v20131017 3 | * http://jquery.malsup.com/form/ 4 | * Copyright (c) 2013 M. Alsup; Dual licensed: MIT/GPL 5 | * https://github.com/malsup/form#copyright-and-license 6 | */ 7 | ;(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=this;if(i.clk=r,"image"==r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n={};n.fileapi=void 0!==e("").get(0).files,n.formdata=void 0!==window.FormData;var i=!!e.fn.prop;e.fn.attr2=function(){if(!i)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t){function r(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;o>a;a++)i[a]=i[a].replace(/\+/g," "),n=i[a].split("="),s.push([decodeURIComponent(n[0]),decodeURIComponent(n[1])]);return s}function o(a){for(var n=new FormData,i=0;a.length>i;i++)n.append(a[i].name,a[i].value);if(t.extraData){var o=r(t.extraData);for(i=0;o.length>i;i++)o[i]&&n.append(o[i][0],o[i][1])}t.data=null;var s=e.extend(!0,{},e.ajaxSettings,t,{contentType:!1,processData:!1,cache:!1,type:u||"POST"});t.uploadProgress&&(s.xhr=function(){var r=e.ajaxSettings.xhr();return r.upload&&r.upload.addEventListener("progress",function(e){var r=0,a=e.loaded||e.position,n=e.total;e.lengthComputable&&(r=Math.ceil(100*(a/n))),t.uploadProgress(e,a,n,r)},!1),r}),s.data=null;var l=s.beforeSend;return s.beforeSend=function(e,r){r.data=t.formData?t.formData:n,l&&l.call(this,e,r)},e.ajax(s)}function s(r){function n(e){var t=null;try{e.contentWindow&&(t=e.contentWindow.document)}catch(r){a("cannot get iframe.contentWindow document: "+r)}if(t)return t;try{t=e.contentDocument?e.contentDocument:e.document}catch(r){a("cannot get iframe.contentDocument: "+r),t=e.document}return t}function o(){function t(){try{var e=n(g).readyState;a("state = "+e),e&&"uninitialized"==e.toLowerCase()&&setTimeout(t,50)}catch(r){a("Server abort: ",r," (",r.name,")"),s(k),j&&clearTimeout(j),j=void 0}}var r=f.attr2("target"),i=f.attr2("action");w.setAttribute("target",d),(!u||/post/i.test(u))&&w.setAttribute("method","POST"),i!=m.url&&w.setAttribute("action",m.url),m.skipEncodingOverride||u&&!/post/i.test(u)||f.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),m.timeout&&(j=setTimeout(function(){T=!0,s(D)},m.timeout));var o=[];try{if(m.extraData)for(var l in m.extraData)m.extraData.hasOwnProperty(l)&&(e.isPlainObject(m.extraData[l])&&m.extraData[l].hasOwnProperty("name")&&m.extraData[l].hasOwnProperty("value")?o.push(e('').val(m.extraData[l].value).appendTo(w)[0]):o.push(e('').val(m.extraData[l]).appendTo(w)[0]));m.iframeTarget||v.appendTo("body"),g.attachEvent?g.attachEvent("onload",s):g.addEventListener("load",s,!1),setTimeout(t,15);try{w.submit()}catch(c){var p=document.createElement("form").submit;p.apply(w)}}finally{w.setAttribute("action",i),r?w.setAttribute("target",r):f.removeAttr("target"),e(o).remove()}}function s(t){if(!x.aborted&&!F){if(M=n(g),M||(a("cannot access response document"),t=k),t===D&&x)return x.abort("timeout"),S.reject(x,"timeout"),void 0;if(t==k&&x)return x.abort("server abort"),S.reject(x,"error","server abort"),void 0;if(M&&M.location.href!=m.iframeSrc||T){g.detachEvent?g.detachEvent("onload",s):g.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"==m.dataType||M.XMLDocument||e.isXMLDoc(M);if(a("isXml="+o),!o&&window.opera&&(null===M.body||!M.body.innerHTML)&&--O)return a("requeing onLoad callback, DOM not available"),setTimeout(s,250),void 0;var u=M.body?M.body:M.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=M.XMLDocument?M.XMLDocument:M,o&&(m.dataType="xml"),x.getResponseHeader=function(e){var t={"content-type":m.dataType};return t[e.toLowerCase()]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);var l=(m.dataType||"").toLowerCase(),c=/(json|script|text)/.test(l);if(c||m.textarea){var f=M.getElementsByTagName("textarea")[0];if(f)x.responseText=f.value,x.status=Number(f.getAttribute("status"))||x.status,x.statusText=f.getAttribute("statusText")||x.statusText;else if(c){var d=M.getElementsByTagName("pre")[0],h=M.getElementsByTagName("body")[0];d?x.responseText=d.textContent?d.textContent:d.innerText:h&&(x.responseText=h.textContent?h.textContent:h.innerText)}}else"xml"==l&&!x.responseXML&&x.responseText&&(x.responseXML=X(x.responseText));try{E=_(x,l,m)}catch(b){i="parsererror",x.error=r=b||i}}catch(b){a("error caught: ",b),i="error",x.error=r=b||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&300>x.status||304===x.status?"success":"error"),"success"===i?(m.success&&m.success.call(m.context,E,"success",x),S.resolve(x.responseText,"success",x),p&&e.event.trigger("ajaxSuccess",[x,m])):i&&(void 0===r&&(r=x.statusText),m.error&&m.error.call(m.context,x,i,r),S.reject(x,"error",r),p&&e.event.trigger("ajaxError",[x,m,r])),p&&e.event.trigger("ajaxComplete",[x,m]),p&&!--e.active&&e.event.trigger("ajaxStop"),m.complete&&m.complete.call(m.context,x,i),F=!0,m.timeout&&clearTimeout(j),setTimeout(function(){m.iframeTarget?v.attr("src",m.iframeSrc):v.remove(),x.responseXML=null},100)}}}var l,c,m,p,d,v,g,x,b,y,T,j,w=f[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(c=0;h.length>c;c++)l=e(h[c]),i?l.prop("disabled",!1):l.removeAttr("disabled");if(m=e.extend(!0,{},e.ajaxSettings,t),m.context=m.context||m,d="jqFormIO"+(new Date).getTime(),m.iframeTarget?(v=e(m.iframeTarget),y=v.attr2("name"),y?d=y:v.attr2("name",d)):(v=e('