@@ -24,677 +24,677 @@ |
||
| 24 | 24 | class EE_Admin_Page_Loader |
| 25 | 25 | { |
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * _installed_pages |
|
| 29 | - * objects for page_init objects detected and loaded |
|
| 30 | - * |
|
| 31 | - * @access private |
|
| 32 | - * @var \EE_Admin_Page_Init[] |
|
| 33 | - */ |
|
| 34 | - private $_installed_pages = array(); |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * this is used to hold the registry of menu slugs for all the installed admin pages |
|
| 39 | - * |
|
| 40 | - * @var array |
|
| 41 | - */ |
|
| 42 | - private $_menu_slugs = array(); |
|
| 43 | - |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * _caffeinated_extends |
|
| 47 | - * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and |
|
| 48 | - * pieces needed to do so). This property is defined in the _set_caffeinated method. |
|
| 49 | - * |
|
| 50 | - * @var array |
|
| 51 | - */ |
|
| 52 | - private $_caffeinated_extends = array(); |
|
| 53 | - |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * _current_caf_extend_slug |
|
| 57 | - * This property is used for holding the page slug that is required for referencing the correct |
|
| 58 | - * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed. |
|
| 59 | - * |
|
| 60 | - * @var array |
|
| 61 | - */ |
|
| 62 | - private $_current_caf_extend_slug; |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * _prepped_menu_maps |
|
| 66 | - * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu. |
|
| 67 | - * |
|
| 68 | - * @since 4.4.0 |
|
| 69 | - * @var EE_Admin_Page_Menu_Map[] |
|
| 70 | - */ |
|
| 71 | - private $_prepped_menu_maps = array(); |
|
| 72 | - |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * _admin_menu_groups |
|
| 76 | - * array that holds the group headings and details for |
|
| 77 | - * |
|
| 78 | - * @access private |
|
| 79 | - * @var array |
|
| 80 | - */ |
|
| 81 | - private $_admin_menu_groups = array(); |
|
| 82 | - |
|
| 83 | - |
|
| 84 | - /** |
|
| 85 | - * This property will hold the hook file for setting up the filter that does all the connections between admin |
|
| 86 | - * pages. |
|
| 87 | - * |
|
| 88 | - * @var string |
|
| 89 | - */ |
|
| 90 | - public $hook_file; |
|
| 91 | - |
|
| 92 | - |
|
| 93 | - /** |
|
| 94 | - * constructor |
|
| 95 | - * |
|
| 96 | - * @access public |
|
| 97 | - * @return \EE_Admin_Page_Loader |
|
| 98 | - */ |
|
| 99 | - public function __construct() |
|
| 100 | - { |
|
| 101 | - // load menu_map classes |
|
| 102 | - EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core'); |
|
| 103 | - // define the default "groups" for the admin_pages |
|
| 104 | - $this->_set_menu_groups(); |
|
| 105 | - |
|
| 106 | - // let's do a scan and see what installed pages we have |
|
| 107 | - $this->_get_installed_pages(); |
|
| 108 | - // set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to). |
|
| 109 | - add_action('admin_menu', array($this, 'set_menus')); |
|
| 110 | - add_action('network_admin_menu', array($this, 'set_network_menus')); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by |
|
| 116 | - * files in the caffeinated folder. |
|
| 117 | - * |
|
| 118 | - * @access private |
|
| 119 | - * @return void |
|
| 120 | - */ |
|
| 121 | - private function _define_caffeinated_constants() |
|
| 122 | - { |
|
| 123 | - if (! defined('EE_CORE_CAF_ADMIN')) { |
|
| 124 | - define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/'); |
|
| 125 | - define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/'); |
|
| 126 | - define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/'); |
|
| 127 | - define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/'); |
|
| 128 | - define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/'); |
|
| 129 | - define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/'); |
|
| 130 | - } |
|
| 131 | - } |
|
| 132 | - |
|
| 133 | - |
|
| 134 | - /** |
|
| 135 | - * _set_menu_groups |
|
| 136 | - * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array) |
|
| 137 | - * |
|
| 138 | - * @access private |
|
| 139 | - * @return void |
|
| 140 | - */ |
|
| 141 | - private function _set_menu_groups() |
|
| 142 | - { |
|
| 143 | - |
|
| 144 | - // set array of EE_Admin_Page_Menu_Group objects |
|
| 145 | - $groups = array( |
|
| 146 | - 'main' => new EE_Admin_Page_Menu_Group( |
|
| 147 | - array( |
|
| 148 | - 'menu_label' => __('Main', 'event_espresso'), |
|
| 149 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::NONE, |
|
| 150 | - 'menu_slug' => 'main', |
|
| 151 | - 'capability' => 'ee_read_ee', |
|
| 152 | - 'menu_order' => 0, |
|
| 153 | - 'parent_slug' => 'espresso_events', |
|
| 154 | - ) |
|
| 155 | - ), |
|
| 156 | - 'management' => new EE_Admin_Page_Menu_Group( |
|
| 157 | - array( |
|
| 158 | - 'menu_label' => __('Management', 'event_espresso'), |
|
| 159 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 160 | - 'menu_slug' => 'management', |
|
| 161 | - 'capability' => 'ee_read_ee', |
|
| 162 | - 'menu_order' => 10, |
|
| 163 | - 'parent_slug' => 'espresso_events', |
|
| 164 | - ) |
|
| 165 | - ), |
|
| 166 | - 'settings' => new EE_Admin_Page_Menu_Group( |
|
| 167 | - array( |
|
| 168 | - 'menu_label' => __('Settings', 'event_espresso'), |
|
| 169 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 170 | - 'menu_slug' => 'settings', |
|
| 171 | - 'capability' => 'ee_read_ee', |
|
| 172 | - 'menu_order' => 30, |
|
| 173 | - 'parent_slug' => 'espresso_events', |
|
| 174 | - ) |
|
| 175 | - ), |
|
| 176 | - 'templates' => new EE_Admin_Page_Menu_Group( |
|
| 177 | - array( |
|
| 178 | - 'menu_label' => __('Templates', 'event_espresso'), |
|
| 179 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 180 | - 'menu_slug' => 'templates', |
|
| 181 | - 'capability' => 'ee_read_ee', |
|
| 182 | - 'menu_order' => 40, |
|
| 183 | - 'parent_slug' => 'espresso_events', |
|
| 184 | - ) |
|
| 185 | - ), |
|
| 186 | - 'extras' => new EE_Admin_Page_Menu_Group( |
|
| 187 | - array( |
|
| 188 | - 'menu_label' => __('Extras', 'event_espresso'), |
|
| 189 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN, |
|
| 190 | - 'menu_slug' => 'extras', |
|
| 191 | - 'capability' => 'ee_read_ee', |
|
| 192 | - 'menu_order' => 50, |
|
| 193 | - 'parent_slug' => 'espresso_events', |
|
| 194 | - 'maintenance_mode_parent' => 'espresso_maintenance_settings', |
|
| 195 | - ) |
|
| 196 | - ), |
|
| 197 | - 'tools' => new EE_Admin_Page_Menu_Group( |
|
| 198 | - array( |
|
| 199 | - 'menu_label' => __("Tools", "event_espresso"), |
|
| 200 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 201 | - 'menu_slug' => 'tools', |
|
| 202 | - 'capability' => 'ee_read_ee', |
|
| 203 | - 'menu_order' => 60, |
|
| 204 | - 'parent_slug' => 'espresso_events', |
|
| 205 | - ) |
|
| 206 | - ), |
|
| 207 | - 'addons' => new EE_Admin_Page_Menu_Group( |
|
| 208 | - array( |
|
| 209 | - 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN, |
|
| 210 | - 'menu_label' => __('Add-ons', 'event_espresso'), |
|
| 211 | - 'menu_slug' => 'addons', |
|
| 212 | - 'capability' => 'ee_read_ee', |
|
| 213 | - 'menu_order' => 20, |
|
| 214 | - 'parent_slug' => 'espresso_events', |
|
| 215 | - ) |
|
| 216 | - ), |
|
| 217 | - ); |
|
| 218 | - $this->_admin_menu_groups = apply_filters( |
|
| 219 | - 'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups', |
|
| 220 | - $groups |
|
| 221 | - ); |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - |
|
| 225 | - /** |
|
| 226 | - * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group |
|
| 227 | - * slug. The other utility with this function is it validates that all the groups are instances of |
|
| 228 | - * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons). |
|
| 229 | - * |
|
| 230 | - * @since 4.4.0 |
|
| 231 | - * @throws \EE_Error |
|
| 232 | - * @return EE_Admin_Page_Menu_Group[] |
|
| 233 | - */ |
|
| 234 | - private function _rearrange_menu_groups() |
|
| 235 | - { |
|
| 236 | - $groups = array(); |
|
| 237 | - // first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects ) |
|
| 238 | - usort($this->_admin_menu_groups, array($this, '_sort_menu_maps')); |
|
| 239 | - foreach ($this->_admin_menu_groups as $group) { |
|
| 240 | - if (! $group instanceof EE_Admin_Page_Menu_Group) { |
|
| 241 | - throw new EE_Error( |
|
| 242 | - sprintf( |
|
| 243 | - __( |
|
| 244 | - 'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups. All values in this array are required to be a EE_Admin_Page_Menu_Group object. Instead there was: %s', |
|
| 245 | - 'event_espresso' |
|
| 246 | - ), |
|
| 247 | - print_r($group, true) |
|
| 248 | - ) |
|
| 249 | - ); |
|
| 250 | - } |
|
| 251 | - $groups[ $group->menu_slug ] = $group; |
|
| 252 | - } |
|
| 253 | - return $groups; |
|
| 254 | - } |
|
| 255 | - |
|
| 256 | - |
|
| 257 | - /** |
|
| 258 | - * _get_installed_pages |
|
| 259 | - * This just gets the list of installed EE_Admin_pages. |
|
| 260 | - * |
|
| 261 | - * @access private |
|
| 262 | - * @throws EE_Error |
|
| 263 | - * @return void |
|
| 264 | - */ |
|
| 265 | - private function _get_installed_pages() |
|
| 266 | - { |
|
| 267 | - $installed_refs = array(); |
|
| 268 | - $exclude = array('assets', 'templates'); |
|
| 269 | - // grab everything in the admin core directory |
|
| 270 | - $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR); |
|
| 271 | - if ($admin_screens) { |
|
| 272 | - foreach ($admin_screens as $admin_screen) { |
|
| 273 | - // files and anything in the exclude array need not apply |
|
| 274 | - if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
|
| 275 | - // these folders represent the different EE admin pages |
|
| 276 | - $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 277 | - } |
|
| 278 | - } |
|
| 279 | - } |
|
| 280 | - if (empty($installed_refs)) { |
|
| 281 | - $error_msg[] = __( |
|
| 282 | - 'There are no EE_Admin pages detected, it looks like EE did not install properly', |
|
| 283 | - 'event_espresso' |
|
| 284 | - ); |
|
| 285 | - $error_msg[] = $error_msg[0] . "\r\n" |
|
| 286 | - . sprintf( |
|
| 287 | - __( |
|
| 288 | - 'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.', |
|
| 289 | - 'event_espresso' |
|
| 290 | - ), |
|
| 291 | - EE_ADMIN_PAGES |
|
| 292 | - ); |
|
| 293 | - throw new EE_Error(implode('||', $error_msg)); |
|
| 294 | - } |
|
| 295 | - // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff. |
|
| 296 | - $installed_refs = $this->_set_caffeinated($installed_refs); |
|
| 297 | - // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.; |
|
| 298 | - $installed_refs = apply_filters( |
|
| 299 | - 'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs', |
|
| 300 | - $installed_refs |
|
| 301 | - ); |
|
| 302 | - $this->_caffeinated_extends = apply_filters( |
|
| 303 | - 'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends', |
|
| 304 | - $this->_caffeinated_extends |
|
| 305 | - ); |
|
| 306 | - // loop through admin pages and setup the $_installed_pages array. |
|
| 307 | - $hooks_ref = array(); |
|
| 308 | - foreach ($installed_refs as $page => $path) { |
|
| 309 | - // set autoloaders for our admin page classes based on included path information |
|
| 310 | - EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path); |
|
| 311 | - // build list of installed pages |
|
| 312 | - $this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path); |
|
| 313 | - // verify returned object |
|
| 314 | - if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 315 | - if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) { |
|
| 316 | - continue; |
|
| 317 | - } |
|
| 318 | - // skip if in full maintenance mode and maintenance_mode_parent is set |
|
| 319 | - $maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent; |
|
| 320 | - if (empty($maintenance_mode_parent) |
|
| 321 | - && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance |
|
| 322 | - ) { |
|
| 323 | - unset($installed_refs[ $page ]); |
|
| 324 | - continue; |
|
| 325 | - } |
|
| 326 | - $menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug; |
|
| 327 | - $this->_menu_slugs[ $menu_slug ] = $page; |
|
| 328 | - // flag for register hooks on extended pages b/c extended pages use the default INIT. |
|
| 329 | - $extend = false; |
|
| 330 | - // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals. If there are then let's hook into the init admin filter and load our extend instead. |
|
| 331 | - if (isset($this->_caffeinated_extends[ $page ])) { |
|
| 332 | - $this->_current_caf_extend_slug = $page; |
|
| 333 | - $admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name(); |
|
| 334 | - $caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path']; |
|
| 335 | - $caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page']; |
|
| 336 | - add_filter( |
|
| 337 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}", |
|
| 338 | - function ($path_to_file) use ($caf_path) { |
|
| 339 | - return $caf_path; |
|
| 340 | - } |
|
| 341 | - ); |
|
| 342 | - add_filter( |
|
| 343 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}", |
|
| 344 | - function ($admin_page) use ($caf_admin_page) { |
|
| 345 | - return $caf_admin_page; |
|
| 346 | - } |
|
| 347 | - ); |
|
| 348 | - $extend = true; |
|
| 349 | - } |
|
| 350 | - // let's do the registered hooks |
|
| 351 | - $extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend); |
|
| 352 | - $hooks_ref = array_merge($hooks_ref, $extended_hooks); |
|
| 353 | - } |
|
| 354 | - } |
|
| 355 | - // the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder. So we want to make sure we load the file for the parent. |
|
| 356 | - // first make sure we've got unique values |
|
| 357 | - $hooks_ref = array_unique($hooks_ref); |
|
| 358 | - // now let's loop and require! |
|
| 359 | - foreach ($hooks_ref as $path) { |
|
| 360 | - require_once($path); |
|
| 361 | - } |
|
| 362 | - // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested. |
|
| 363 | - global $ee_menu_slugs; |
|
| 364 | - $ee_menu_slugs = $this->_menu_slugs; |
|
| 365 | - // we need to loop again to run any early code |
|
| 366 | - foreach ($installed_refs as $page => $path) { |
|
| 367 | - if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 368 | - $this->_installed_pages[ $page ]->do_initial_loads(); |
|
| 369 | - } |
|
| 370 | - } |
|
| 371 | - do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages); |
|
| 372 | - } |
|
| 373 | - |
|
| 374 | - |
|
| 375 | - /** |
|
| 376 | - * get_admin_page_object |
|
| 377 | - * |
|
| 378 | - * @param string $page_slug |
|
| 379 | - * @return EE_Admin_Page |
|
| 380 | - */ |
|
| 381 | - public function get_admin_page_object($page_slug = '') |
|
| 382 | - { |
|
| 383 | - if (isset($this->_installed_pages[ $page_slug ])) { |
|
| 384 | - return $this->_installed_pages[ $page_slug ]->loaded_page_object(); |
|
| 385 | - } |
|
| 386 | - return null; |
|
| 387 | - } |
|
| 388 | - |
|
| 389 | - |
|
| 390 | - /** |
|
| 391 | - * _get_classname_for_admin_page |
|
| 392 | - * generates an "Admin Page" class based on the directory name |
|
| 393 | - * |
|
| 394 | - * @param $dir_name |
|
| 395 | - * @return string |
|
| 396 | - */ |
|
| 397 | - private function _get_classname_for_admin_page($dir_name = '') |
|
| 398 | - { |
|
| 399 | - $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
| 400 | - return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page'; |
|
| 401 | - } |
|
| 402 | - |
|
| 403 | - |
|
| 404 | - /** |
|
| 405 | - * _get_classname_for_admin_init_page |
|
| 406 | - * generates an "Admin Page Init" class based on the directory name |
|
| 407 | - * |
|
| 408 | - * @param $dir_name |
|
| 409 | - * @return string |
|
| 410 | - */ |
|
| 411 | - private function _get_classname_for_admin_init_page($dir_name = '') |
|
| 412 | - { |
|
| 413 | - $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
| 414 | - return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init'; |
|
| 415 | - } |
|
| 416 | - |
|
| 417 | - |
|
| 418 | - /** |
|
| 419 | - * _load_admin_page |
|
| 420 | - * Loads and instantiates page_init object for a single EE_admin page. |
|
| 421 | - * |
|
| 422 | - * @param string $page page_reference |
|
| 423 | - * @param string $path |
|
| 424 | - * @throws EE_Error |
|
| 425 | - * @return object|bool return page object if valid, bool false if not. |
|
| 426 | - */ |
|
| 427 | - private function _load_admin_page($page = '', $path = '') |
|
| 428 | - { |
|
| 429 | - $class_name = $this->_get_classname_for_admin_init_page($page); |
|
| 430 | - EE_Registry::instance()->load_file($path, $class_name, 'core'); |
|
| 431 | - if (! class_exists($class_name)) { |
|
| 432 | - $inner_error_msg = '<br />' |
|
| 433 | - . sprintf( |
|
| 434 | - esc_html__( |
|
| 435 | - 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
| 436 | - 'event_espresso' |
|
| 437 | - ), |
|
| 438 | - '<strong>' . $class_name . '</strong>' |
|
| 439 | - ); |
|
| 440 | - $error_msg[] = sprintf( |
|
| 441 | - __('Something went wrong with loading the %s admin page.', 'event_espresso'), |
|
| 442 | - $page |
|
| 443 | - ); |
|
| 444 | - $error_msg[] = $error_msg[0] |
|
| 445 | - . "\r\n" |
|
| 446 | - . sprintf( |
|
| 447 | - esc_html__( |
|
| 448 | - 'There is no Init class in place for the %s admin page.', |
|
| 449 | - 'event_espresso' |
|
| 450 | - ), |
|
| 451 | - $page |
|
| 452 | - ) |
|
| 453 | - . $inner_error_msg; |
|
| 454 | - throw new EE_Error(implode('||', $error_msg)); |
|
| 455 | - } |
|
| 456 | - $a = new ReflectionClass($class_name); |
|
| 457 | - return $a->newInstance(); |
|
| 458 | - } |
|
| 459 | - |
|
| 460 | - |
|
| 461 | - /** |
|
| 462 | - * set_menus |
|
| 463 | - * This method sets up the menus for EE Admin Pages |
|
| 464 | - * |
|
| 465 | - * @access private |
|
| 466 | - * @return void |
|
| 467 | - */ |
|
| 468 | - public function set_menus() |
|
| 469 | - { |
|
| 470 | - // prep the menu pages (sort, group.) |
|
| 471 | - $this->_prep_pages(); |
|
| 472 | - foreach ($this->_prepped_menu_maps as $menu_map) { |
|
| 473 | - if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) { |
|
| 474 | - $menu_map->add_menu_page(false); |
|
| 475 | - } |
|
| 476 | - } |
|
| 477 | - } |
|
| 478 | - |
|
| 479 | - |
|
| 480 | - /** |
|
| 481 | - * set_network_menus |
|
| 482 | - * This method sets up the menus for network EE Admin Pages. |
|
| 483 | - * Almost identical to EE_Admin_Page_Loader::set_menus() except pages |
|
| 484 | - * are only added to the menu map if they are intended for the admin menu |
|
| 485 | - * |
|
| 486 | - * @return void |
|
| 487 | - */ |
|
| 488 | - public function set_network_menus() |
|
| 489 | - { |
|
| 490 | - $this->_prep_pages(); |
|
| 491 | - foreach ($this->_prepped_menu_maps as $menu_map) { |
|
| 492 | - if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) { |
|
| 493 | - $menu_map->add_menu_page(true); |
|
| 494 | - } |
|
| 495 | - } |
|
| 496 | - } |
|
| 497 | - |
|
| 498 | - |
|
| 499 | - /** |
|
| 500 | - * _prep_pages |
|
| 501 | - * sets the _prepped_menu_maps property |
|
| 502 | - * |
|
| 503 | - * @access private |
|
| 504 | - * @throws EE_Error |
|
| 505 | - * @return void |
|
| 506 | - */ |
|
| 507 | - private function _prep_pages() |
|
| 508 | - { |
|
| 509 | - $pages_array = array(); |
|
| 510 | - // rearrange _admin_menu_groups to be indexed by group slug. |
|
| 511 | - $menu_groups = $this->_rearrange_menu_groups(); |
|
| 512 | - foreach ($this->_installed_pages as $page) { |
|
| 513 | - if ($page instanceof EE_Admin_page_Init) { |
|
| 514 | - $page_map = $page->get_menu_map(); |
|
| 515 | - // if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item. |
|
| 516 | - if (is_array($page_map) || empty($page_map)) { |
|
| 517 | - new PersistentAdminNotice( |
|
| 518 | - 'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION, |
|
| 519 | - sprintf( |
|
| 520 | - __( |
|
| 521 | - 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core. This means that full functionality for this component is not available. This error message usually appears with an Add-on that is out of date. Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.', |
|
| 522 | - 'event_espresso' |
|
| 523 | - ), |
|
| 524 | - $page->label |
|
| 525 | - ) |
|
| 526 | - ); |
|
| 527 | - continue; |
|
| 528 | - } |
|
| 529 | - // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error. |
|
| 530 | - if (! $page_map instanceof EE_Admin_Page_Menu_Map) { |
|
| 531 | - throw new EE_Error( |
|
| 532 | - sprintf( |
|
| 533 | - __( |
|
| 534 | - 'The menu map for %s must be an EE_Admin_Page_Menu_Map object. Instead it is %s. Please double check that the menu map has been configured correctly.', |
|
| 535 | - 'event_espresso' |
|
| 536 | - ), |
|
| 537 | - $page->label, |
|
| 538 | - $page_map |
|
| 539 | - ) |
|
| 540 | - ); |
|
| 541 | - } |
|
| 542 | - // use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array. |
|
| 543 | - if (empty($page_map->maintenance_mode_parent) |
|
| 544 | - && EE_Maintenance_Mode::instance()->level() |
|
| 545 | - == EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
| 546 | - continue; |
|
| 547 | - } |
|
| 548 | - // assign to group (remember $page_map has the admin page stored in it). |
|
| 549 | - $pages_array[ $page_map->menu_group ][] = $page_map; |
|
| 550 | - } |
|
| 551 | - } |
|
| 552 | - if (empty($pages_array)) { |
|
| 553 | - throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso')); |
|
| 554 | - } |
|
| 555 | - // let's sort the groups, make sure it's a valid group, add header (if to show). |
|
| 556 | - foreach ($pages_array as $group => $menu_maps) { |
|
| 557 | - // valid_group? |
|
| 558 | - if (! array_key_exists($group, $menu_groups)) { |
|
| 559 | - continue; |
|
| 560 | - } |
|
| 561 | - // sort pages. |
|
| 562 | - usort($menu_maps, array($this, '_sort_menu_maps')); |
|
| 563 | - // prepend header |
|
| 564 | - array_unshift($menu_maps, $menu_groups[ $group ]); |
|
| 565 | - // reset $pages_array with prepped data |
|
| 566 | - $pages_array[ $group ] = $menu_maps; |
|
| 567 | - } |
|
| 568 | - // now let's setup the _prepped_menu_maps property |
|
| 569 | - foreach ($menu_groups as $group => $group_objs) { |
|
| 570 | - if (isset($pages_array[ $group ])) { |
|
| 571 | - $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]); |
|
| 572 | - } |
|
| 573 | - }/**/ |
|
| 574 | - } |
|
| 575 | - |
|
| 576 | - |
|
| 577 | - /** |
|
| 578 | - * This method is the "workhorse" for detecting and setting up caffeinated functionality. |
|
| 579 | - * In this method there are three checks being done: |
|
| 580 | - * 1. Do we have any NEW admin page sets. If we do, lets add them into the menu setup (via the $installed_refs |
|
| 581 | - * array) etc. (new page sets are found in caffeinated/new/{page}) |
|
| 582 | - * 2. Do we have any EXTENDED page sets. Basically an extended EE_Admin Page extends the core {child}_Admin_Page |
|
| 583 | - * class. eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class: |
|
| 584 | - * Extend_Events_Admin_Page extends Events_Admin_Page. |
|
| 585 | - * 3. Do we have any files just for setting up hooks into other core pages. The files can be any name in |
|
| 586 | - * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the |
|
| 587 | - * classname inside. These classes are instantiated really early so that any hooks in them are run before the |
|
| 588 | - * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated |
|
| 589 | - * admin_pages) |
|
| 590 | - * |
|
| 591 | - * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be |
|
| 592 | - * loaded. |
|
| 593 | - * @return array |
|
| 594 | - */ |
|
| 595 | - private function _set_caffeinated($installed_refs) |
|
| 596 | - { |
|
| 597 | - |
|
| 598 | - // first let's check if there IS a caffeinated folder. If there is not then lets get out. |
|
| 599 | - if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) { |
|
| 600 | - return $installed_refs; |
|
| 601 | - } |
|
| 602 | - $this->_define_caffeinated_constants(); |
|
| 603 | - $exclude = array('tickets'); |
|
| 604 | - // okay let's setup an "New" pages first (we'll return installed refs later) |
|
| 605 | - $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR); |
|
| 606 | - if ($new_admin_screens) { |
|
| 607 | - foreach ($new_admin_screens as $admin_screen) { |
|
| 608 | - // files and anything in the exclude array need not apply |
|
| 609 | - if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
|
| 610 | - // these folders represent the different NEW EE admin pages |
|
| 611 | - $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 612 | - // set autoloaders for our admin page classes based on included path information |
|
| 613 | - EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen); |
|
| 614 | - } |
|
| 615 | - } |
|
| 616 | - } |
|
| 617 | - // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page) |
|
| 618 | - $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR); |
|
| 619 | - if ($extends) { |
|
| 620 | - foreach ($extends as $extend) { |
|
| 621 | - if (is_dir($extend)) { |
|
| 622 | - $extend_ref = basename($extend); |
|
| 623 | - // now let's make sure there is a file that matches the expected format |
|
| 624 | - $filename = str_replace( |
|
| 625 | - ' ', |
|
| 626 | - '_', |
|
| 627 | - ucwords( |
|
| 628 | - str_replace( |
|
| 629 | - '_', |
|
| 630 | - ' ', |
|
| 631 | - $extend_ref |
|
| 632 | - ) |
|
| 633 | - ) |
|
| 634 | - ); |
|
| 635 | - $filename = 'Extend_' . $filename . '_Admin_Page'; |
|
| 636 | - $this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace( |
|
| 637 | - array('\\', '/'), |
|
| 638 | - '/', |
|
| 639 | - EE_CORE_CAF_ADMIN |
|
| 640 | - . 'extend/' |
|
| 641 | - . $extend_ref |
|
| 642 | - . '/' |
|
| 643 | - . $filename |
|
| 644 | - . '.core.php' |
|
| 645 | - ); |
|
| 646 | - $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename; |
|
| 647 | - // set autoloaders for our admin page classes based on included path information |
|
| 648 | - EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend); |
|
| 649 | - } |
|
| 650 | - } |
|
| 651 | - } |
|
| 652 | - // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!). |
|
| 653 | - $ee_admin_hooks = array(); |
|
| 654 | - $hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php'); |
|
| 655 | - if ($hooks) { |
|
| 656 | - foreach ($hooks as $hook) { |
|
| 657 | - if (is_readable($hook)) { |
|
| 658 | - require_once $hook; |
|
| 659 | - $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook); |
|
| 660 | - $classname = str_replace('.class.php', '', $classname); |
|
| 661 | - if (class_exists($classname)) { |
|
| 662 | - $a = new ReflectionClass($classname); |
|
| 663 | - $ee_admin_hooks[] = $a->newInstance(); |
|
| 664 | - } |
|
| 665 | - } |
|
| 666 | - } |
|
| 667 | - }/**/ |
|
| 668 | - $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks); |
|
| 669 | - return $installed_refs; |
|
| 670 | - } |
|
| 671 | - |
|
| 672 | - |
|
| 673 | - /** |
|
| 674 | - * Utility method for sorting the _menu_maps (callback for usort php function) |
|
| 675 | - * |
|
| 676 | - * @since 4.4.0 |
|
| 677 | - * @param EE_Admin_Page_Menu_Map $a menu_map object |
|
| 678 | - * @param EE_Admin_Page_Menu_Map $b being compared to |
|
| 679 | - * @return int sort order |
|
| 680 | - */ |
|
| 681 | - private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b) |
|
| 682 | - { |
|
| 683 | - if ($a->menu_order == $b->menu_order) { |
|
| 684 | - return 0; |
|
| 685 | - } |
|
| 686 | - return ($a->menu_order < $b->menu_order) ? -1 : 1; |
|
| 687 | - } |
|
| 688 | - |
|
| 689 | - |
|
| 690 | - /** |
|
| 691 | - * _default_header_link |
|
| 692 | - * This is just a dummy method to use with header submenu items |
|
| 693 | - * |
|
| 694 | - * @return bool false |
|
| 695 | - */ |
|
| 696 | - public function _default_header_link() |
|
| 697 | - { |
|
| 698 | - return false; |
|
| 699 | - } |
|
| 27 | + /** |
|
| 28 | + * _installed_pages |
|
| 29 | + * objects for page_init objects detected and loaded |
|
| 30 | + * |
|
| 31 | + * @access private |
|
| 32 | + * @var \EE_Admin_Page_Init[] |
|
| 33 | + */ |
|
| 34 | + private $_installed_pages = array(); |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * this is used to hold the registry of menu slugs for all the installed admin pages |
|
| 39 | + * |
|
| 40 | + * @var array |
|
| 41 | + */ |
|
| 42 | + private $_menu_slugs = array(); |
|
| 43 | + |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * _caffeinated_extends |
|
| 47 | + * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and |
|
| 48 | + * pieces needed to do so). This property is defined in the _set_caffeinated method. |
|
| 49 | + * |
|
| 50 | + * @var array |
|
| 51 | + */ |
|
| 52 | + private $_caffeinated_extends = array(); |
|
| 53 | + |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * _current_caf_extend_slug |
|
| 57 | + * This property is used for holding the page slug that is required for referencing the correct |
|
| 58 | + * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed. |
|
| 59 | + * |
|
| 60 | + * @var array |
|
| 61 | + */ |
|
| 62 | + private $_current_caf_extend_slug; |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * _prepped_menu_maps |
|
| 66 | + * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu. |
|
| 67 | + * |
|
| 68 | + * @since 4.4.0 |
|
| 69 | + * @var EE_Admin_Page_Menu_Map[] |
|
| 70 | + */ |
|
| 71 | + private $_prepped_menu_maps = array(); |
|
| 72 | + |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * _admin_menu_groups |
|
| 76 | + * array that holds the group headings and details for |
|
| 77 | + * |
|
| 78 | + * @access private |
|
| 79 | + * @var array |
|
| 80 | + */ |
|
| 81 | + private $_admin_menu_groups = array(); |
|
| 82 | + |
|
| 83 | + |
|
| 84 | + /** |
|
| 85 | + * This property will hold the hook file for setting up the filter that does all the connections between admin |
|
| 86 | + * pages. |
|
| 87 | + * |
|
| 88 | + * @var string |
|
| 89 | + */ |
|
| 90 | + public $hook_file; |
|
| 91 | + |
|
| 92 | + |
|
| 93 | + /** |
|
| 94 | + * constructor |
|
| 95 | + * |
|
| 96 | + * @access public |
|
| 97 | + * @return \EE_Admin_Page_Loader |
|
| 98 | + */ |
|
| 99 | + public function __construct() |
|
| 100 | + { |
|
| 101 | + // load menu_map classes |
|
| 102 | + EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core'); |
|
| 103 | + // define the default "groups" for the admin_pages |
|
| 104 | + $this->_set_menu_groups(); |
|
| 105 | + |
|
| 106 | + // let's do a scan and see what installed pages we have |
|
| 107 | + $this->_get_installed_pages(); |
|
| 108 | + // set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to). |
|
| 109 | + add_action('admin_menu', array($this, 'set_menus')); |
|
| 110 | + add_action('network_admin_menu', array($this, 'set_network_menus')); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by |
|
| 116 | + * files in the caffeinated folder. |
|
| 117 | + * |
|
| 118 | + * @access private |
|
| 119 | + * @return void |
|
| 120 | + */ |
|
| 121 | + private function _define_caffeinated_constants() |
|
| 122 | + { |
|
| 123 | + if (! defined('EE_CORE_CAF_ADMIN')) { |
|
| 124 | + define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/'); |
|
| 125 | + define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/'); |
|
| 126 | + define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/'); |
|
| 127 | + define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/'); |
|
| 128 | + define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/'); |
|
| 129 | + define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/'); |
|
| 130 | + } |
|
| 131 | + } |
|
| 132 | + |
|
| 133 | + |
|
| 134 | + /** |
|
| 135 | + * _set_menu_groups |
|
| 136 | + * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array) |
|
| 137 | + * |
|
| 138 | + * @access private |
|
| 139 | + * @return void |
|
| 140 | + */ |
|
| 141 | + private function _set_menu_groups() |
|
| 142 | + { |
|
| 143 | + |
|
| 144 | + // set array of EE_Admin_Page_Menu_Group objects |
|
| 145 | + $groups = array( |
|
| 146 | + 'main' => new EE_Admin_Page_Menu_Group( |
|
| 147 | + array( |
|
| 148 | + 'menu_label' => __('Main', 'event_espresso'), |
|
| 149 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::NONE, |
|
| 150 | + 'menu_slug' => 'main', |
|
| 151 | + 'capability' => 'ee_read_ee', |
|
| 152 | + 'menu_order' => 0, |
|
| 153 | + 'parent_slug' => 'espresso_events', |
|
| 154 | + ) |
|
| 155 | + ), |
|
| 156 | + 'management' => new EE_Admin_Page_Menu_Group( |
|
| 157 | + array( |
|
| 158 | + 'menu_label' => __('Management', 'event_espresso'), |
|
| 159 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 160 | + 'menu_slug' => 'management', |
|
| 161 | + 'capability' => 'ee_read_ee', |
|
| 162 | + 'menu_order' => 10, |
|
| 163 | + 'parent_slug' => 'espresso_events', |
|
| 164 | + ) |
|
| 165 | + ), |
|
| 166 | + 'settings' => new EE_Admin_Page_Menu_Group( |
|
| 167 | + array( |
|
| 168 | + 'menu_label' => __('Settings', 'event_espresso'), |
|
| 169 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 170 | + 'menu_slug' => 'settings', |
|
| 171 | + 'capability' => 'ee_read_ee', |
|
| 172 | + 'menu_order' => 30, |
|
| 173 | + 'parent_slug' => 'espresso_events', |
|
| 174 | + ) |
|
| 175 | + ), |
|
| 176 | + 'templates' => new EE_Admin_Page_Menu_Group( |
|
| 177 | + array( |
|
| 178 | + 'menu_label' => __('Templates', 'event_espresso'), |
|
| 179 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 180 | + 'menu_slug' => 'templates', |
|
| 181 | + 'capability' => 'ee_read_ee', |
|
| 182 | + 'menu_order' => 40, |
|
| 183 | + 'parent_slug' => 'espresso_events', |
|
| 184 | + ) |
|
| 185 | + ), |
|
| 186 | + 'extras' => new EE_Admin_Page_Menu_Group( |
|
| 187 | + array( |
|
| 188 | + 'menu_label' => __('Extras', 'event_espresso'), |
|
| 189 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN, |
|
| 190 | + 'menu_slug' => 'extras', |
|
| 191 | + 'capability' => 'ee_read_ee', |
|
| 192 | + 'menu_order' => 50, |
|
| 193 | + 'parent_slug' => 'espresso_events', |
|
| 194 | + 'maintenance_mode_parent' => 'espresso_maintenance_settings', |
|
| 195 | + ) |
|
| 196 | + ), |
|
| 197 | + 'tools' => new EE_Admin_Page_Menu_Group( |
|
| 198 | + array( |
|
| 199 | + 'menu_label' => __("Tools", "event_espresso"), |
|
| 200 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY, |
|
| 201 | + 'menu_slug' => 'tools', |
|
| 202 | + 'capability' => 'ee_read_ee', |
|
| 203 | + 'menu_order' => 60, |
|
| 204 | + 'parent_slug' => 'espresso_events', |
|
| 205 | + ) |
|
| 206 | + ), |
|
| 207 | + 'addons' => new EE_Admin_Page_Menu_Group( |
|
| 208 | + array( |
|
| 209 | + 'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN, |
|
| 210 | + 'menu_label' => __('Add-ons', 'event_espresso'), |
|
| 211 | + 'menu_slug' => 'addons', |
|
| 212 | + 'capability' => 'ee_read_ee', |
|
| 213 | + 'menu_order' => 20, |
|
| 214 | + 'parent_slug' => 'espresso_events', |
|
| 215 | + ) |
|
| 216 | + ), |
|
| 217 | + ); |
|
| 218 | + $this->_admin_menu_groups = apply_filters( |
|
| 219 | + 'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups', |
|
| 220 | + $groups |
|
| 221 | + ); |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + |
|
| 225 | + /** |
|
| 226 | + * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group |
|
| 227 | + * slug. The other utility with this function is it validates that all the groups are instances of |
|
| 228 | + * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons). |
|
| 229 | + * |
|
| 230 | + * @since 4.4.0 |
|
| 231 | + * @throws \EE_Error |
|
| 232 | + * @return EE_Admin_Page_Menu_Group[] |
|
| 233 | + */ |
|
| 234 | + private function _rearrange_menu_groups() |
|
| 235 | + { |
|
| 236 | + $groups = array(); |
|
| 237 | + // first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects ) |
|
| 238 | + usort($this->_admin_menu_groups, array($this, '_sort_menu_maps')); |
|
| 239 | + foreach ($this->_admin_menu_groups as $group) { |
|
| 240 | + if (! $group instanceof EE_Admin_Page_Menu_Group) { |
|
| 241 | + throw new EE_Error( |
|
| 242 | + sprintf( |
|
| 243 | + __( |
|
| 244 | + 'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups. All values in this array are required to be a EE_Admin_Page_Menu_Group object. Instead there was: %s', |
|
| 245 | + 'event_espresso' |
|
| 246 | + ), |
|
| 247 | + print_r($group, true) |
|
| 248 | + ) |
|
| 249 | + ); |
|
| 250 | + } |
|
| 251 | + $groups[ $group->menu_slug ] = $group; |
|
| 252 | + } |
|
| 253 | + return $groups; |
|
| 254 | + } |
|
| 255 | + |
|
| 256 | + |
|
| 257 | + /** |
|
| 258 | + * _get_installed_pages |
|
| 259 | + * This just gets the list of installed EE_Admin_pages. |
|
| 260 | + * |
|
| 261 | + * @access private |
|
| 262 | + * @throws EE_Error |
|
| 263 | + * @return void |
|
| 264 | + */ |
|
| 265 | + private function _get_installed_pages() |
|
| 266 | + { |
|
| 267 | + $installed_refs = array(); |
|
| 268 | + $exclude = array('assets', 'templates'); |
|
| 269 | + // grab everything in the admin core directory |
|
| 270 | + $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR); |
|
| 271 | + if ($admin_screens) { |
|
| 272 | + foreach ($admin_screens as $admin_screen) { |
|
| 273 | + // files and anything in the exclude array need not apply |
|
| 274 | + if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
|
| 275 | + // these folders represent the different EE admin pages |
|
| 276 | + $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 277 | + } |
|
| 278 | + } |
|
| 279 | + } |
|
| 280 | + if (empty($installed_refs)) { |
|
| 281 | + $error_msg[] = __( |
|
| 282 | + 'There are no EE_Admin pages detected, it looks like EE did not install properly', |
|
| 283 | + 'event_espresso' |
|
| 284 | + ); |
|
| 285 | + $error_msg[] = $error_msg[0] . "\r\n" |
|
| 286 | + . sprintf( |
|
| 287 | + __( |
|
| 288 | + 'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.', |
|
| 289 | + 'event_espresso' |
|
| 290 | + ), |
|
| 291 | + EE_ADMIN_PAGES |
|
| 292 | + ); |
|
| 293 | + throw new EE_Error(implode('||', $error_msg)); |
|
| 294 | + } |
|
| 295 | + // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff. |
|
| 296 | + $installed_refs = $this->_set_caffeinated($installed_refs); |
|
| 297 | + // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.; |
|
| 298 | + $installed_refs = apply_filters( |
|
| 299 | + 'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs', |
|
| 300 | + $installed_refs |
|
| 301 | + ); |
|
| 302 | + $this->_caffeinated_extends = apply_filters( |
|
| 303 | + 'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends', |
|
| 304 | + $this->_caffeinated_extends |
|
| 305 | + ); |
|
| 306 | + // loop through admin pages and setup the $_installed_pages array. |
|
| 307 | + $hooks_ref = array(); |
|
| 308 | + foreach ($installed_refs as $page => $path) { |
|
| 309 | + // set autoloaders for our admin page classes based on included path information |
|
| 310 | + EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path); |
|
| 311 | + // build list of installed pages |
|
| 312 | + $this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path); |
|
| 313 | + // verify returned object |
|
| 314 | + if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 315 | + if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) { |
|
| 316 | + continue; |
|
| 317 | + } |
|
| 318 | + // skip if in full maintenance mode and maintenance_mode_parent is set |
|
| 319 | + $maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent; |
|
| 320 | + if (empty($maintenance_mode_parent) |
|
| 321 | + && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance |
|
| 322 | + ) { |
|
| 323 | + unset($installed_refs[ $page ]); |
|
| 324 | + continue; |
|
| 325 | + } |
|
| 326 | + $menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug; |
|
| 327 | + $this->_menu_slugs[ $menu_slug ] = $page; |
|
| 328 | + // flag for register hooks on extended pages b/c extended pages use the default INIT. |
|
| 329 | + $extend = false; |
|
| 330 | + // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals. If there are then let's hook into the init admin filter and load our extend instead. |
|
| 331 | + if (isset($this->_caffeinated_extends[ $page ])) { |
|
| 332 | + $this->_current_caf_extend_slug = $page; |
|
| 333 | + $admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name(); |
|
| 334 | + $caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path']; |
|
| 335 | + $caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page']; |
|
| 336 | + add_filter( |
|
| 337 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}", |
|
| 338 | + function ($path_to_file) use ($caf_path) { |
|
| 339 | + return $caf_path; |
|
| 340 | + } |
|
| 341 | + ); |
|
| 342 | + add_filter( |
|
| 343 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}", |
|
| 344 | + function ($admin_page) use ($caf_admin_page) { |
|
| 345 | + return $caf_admin_page; |
|
| 346 | + } |
|
| 347 | + ); |
|
| 348 | + $extend = true; |
|
| 349 | + } |
|
| 350 | + // let's do the registered hooks |
|
| 351 | + $extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend); |
|
| 352 | + $hooks_ref = array_merge($hooks_ref, $extended_hooks); |
|
| 353 | + } |
|
| 354 | + } |
|
| 355 | + // the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder. So we want to make sure we load the file for the parent. |
|
| 356 | + // first make sure we've got unique values |
|
| 357 | + $hooks_ref = array_unique($hooks_ref); |
|
| 358 | + // now let's loop and require! |
|
| 359 | + foreach ($hooks_ref as $path) { |
|
| 360 | + require_once($path); |
|
| 361 | + } |
|
| 362 | + // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested. |
|
| 363 | + global $ee_menu_slugs; |
|
| 364 | + $ee_menu_slugs = $this->_menu_slugs; |
|
| 365 | + // we need to loop again to run any early code |
|
| 366 | + foreach ($installed_refs as $page => $path) { |
|
| 367 | + if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 368 | + $this->_installed_pages[ $page ]->do_initial_loads(); |
|
| 369 | + } |
|
| 370 | + } |
|
| 371 | + do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages); |
|
| 372 | + } |
|
| 373 | + |
|
| 374 | + |
|
| 375 | + /** |
|
| 376 | + * get_admin_page_object |
|
| 377 | + * |
|
| 378 | + * @param string $page_slug |
|
| 379 | + * @return EE_Admin_Page |
|
| 380 | + */ |
|
| 381 | + public function get_admin_page_object($page_slug = '') |
|
| 382 | + { |
|
| 383 | + if (isset($this->_installed_pages[ $page_slug ])) { |
|
| 384 | + return $this->_installed_pages[ $page_slug ]->loaded_page_object(); |
|
| 385 | + } |
|
| 386 | + return null; |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + |
|
| 390 | + /** |
|
| 391 | + * _get_classname_for_admin_page |
|
| 392 | + * generates an "Admin Page" class based on the directory name |
|
| 393 | + * |
|
| 394 | + * @param $dir_name |
|
| 395 | + * @return string |
|
| 396 | + */ |
|
| 397 | + private function _get_classname_for_admin_page($dir_name = '') |
|
| 398 | + { |
|
| 399 | + $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
| 400 | + return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page'; |
|
| 401 | + } |
|
| 402 | + |
|
| 403 | + |
|
| 404 | + /** |
|
| 405 | + * _get_classname_for_admin_init_page |
|
| 406 | + * generates an "Admin Page Init" class based on the directory name |
|
| 407 | + * |
|
| 408 | + * @param $dir_name |
|
| 409 | + * @return string |
|
| 410 | + */ |
|
| 411 | + private function _get_classname_for_admin_init_page($dir_name = '') |
|
| 412 | + { |
|
| 413 | + $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
| 414 | + return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init'; |
|
| 415 | + } |
|
| 416 | + |
|
| 417 | + |
|
| 418 | + /** |
|
| 419 | + * _load_admin_page |
|
| 420 | + * Loads and instantiates page_init object for a single EE_admin page. |
|
| 421 | + * |
|
| 422 | + * @param string $page page_reference |
|
| 423 | + * @param string $path |
|
| 424 | + * @throws EE_Error |
|
| 425 | + * @return object|bool return page object if valid, bool false if not. |
|
| 426 | + */ |
|
| 427 | + private function _load_admin_page($page = '', $path = '') |
|
| 428 | + { |
|
| 429 | + $class_name = $this->_get_classname_for_admin_init_page($page); |
|
| 430 | + EE_Registry::instance()->load_file($path, $class_name, 'core'); |
|
| 431 | + if (! class_exists($class_name)) { |
|
| 432 | + $inner_error_msg = '<br />' |
|
| 433 | + . sprintf( |
|
| 434 | + esc_html__( |
|
| 435 | + 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
| 436 | + 'event_espresso' |
|
| 437 | + ), |
|
| 438 | + '<strong>' . $class_name . '</strong>' |
|
| 439 | + ); |
|
| 440 | + $error_msg[] = sprintf( |
|
| 441 | + __('Something went wrong with loading the %s admin page.', 'event_espresso'), |
|
| 442 | + $page |
|
| 443 | + ); |
|
| 444 | + $error_msg[] = $error_msg[0] |
|
| 445 | + . "\r\n" |
|
| 446 | + . sprintf( |
|
| 447 | + esc_html__( |
|
| 448 | + 'There is no Init class in place for the %s admin page.', |
|
| 449 | + 'event_espresso' |
|
| 450 | + ), |
|
| 451 | + $page |
|
| 452 | + ) |
|
| 453 | + . $inner_error_msg; |
|
| 454 | + throw new EE_Error(implode('||', $error_msg)); |
|
| 455 | + } |
|
| 456 | + $a = new ReflectionClass($class_name); |
|
| 457 | + return $a->newInstance(); |
|
| 458 | + } |
|
| 459 | + |
|
| 460 | + |
|
| 461 | + /** |
|
| 462 | + * set_menus |
|
| 463 | + * This method sets up the menus for EE Admin Pages |
|
| 464 | + * |
|
| 465 | + * @access private |
|
| 466 | + * @return void |
|
| 467 | + */ |
|
| 468 | + public function set_menus() |
|
| 469 | + { |
|
| 470 | + // prep the menu pages (sort, group.) |
|
| 471 | + $this->_prep_pages(); |
|
| 472 | + foreach ($this->_prepped_menu_maps as $menu_map) { |
|
| 473 | + if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) { |
|
| 474 | + $menu_map->add_menu_page(false); |
|
| 475 | + } |
|
| 476 | + } |
|
| 477 | + } |
|
| 478 | + |
|
| 479 | + |
|
| 480 | + /** |
|
| 481 | + * set_network_menus |
|
| 482 | + * This method sets up the menus for network EE Admin Pages. |
|
| 483 | + * Almost identical to EE_Admin_Page_Loader::set_menus() except pages |
|
| 484 | + * are only added to the menu map if they are intended for the admin menu |
|
| 485 | + * |
|
| 486 | + * @return void |
|
| 487 | + */ |
|
| 488 | + public function set_network_menus() |
|
| 489 | + { |
|
| 490 | + $this->_prep_pages(); |
|
| 491 | + foreach ($this->_prepped_menu_maps as $menu_map) { |
|
| 492 | + if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) { |
|
| 493 | + $menu_map->add_menu_page(true); |
|
| 494 | + } |
|
| 495 | + } |
|
| 496 | + } |
|
| 497 | + |
|
| 498 | + |
|
| 499 | + /** |
|
| 500 | + * _prep_pages |
|
| 501 | + * sets the _prepped_menu_maps property |
|
| 502 | + * |
|
| 503 | + * @access private |
|
| 504 | + * @throws EE_Error |
|
| 505 | + * @return void |
|
| 506 | + */ |
|
| 507 | + private function _prep_pages() |
|
| 508 | + { |
|
| 509 | + $pages_array = array(); |
|
| 510 | + // rearrange _admin_menu_groups to be indexed by group slug. |
|
| 511 | + $menu_groups = $this->_rearrange_menu_groups(); |
|
| 512 | + foreach ($this->_installed_pages as $page) { |
|
| 513 | + if ($page instanceof EE_Admin_page_Init) { |
|
| 514 | + $page_map = $page->get_menu_map(); |
|
| 515 | + // if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item. |
|
| 516 | + if (is_array($page_map) || empty($page_map)) { |
|
| 517 | + new PersistentAdminNotice( |
|
| 518 | + 'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION, |
|
| 519 | + sprintf( |
|
| 520 | + __( |
|
| 521 | + 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core. This means that full functionality for this component is not available. This error message usually appears with an Add-on that is out of date. Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.', |
|
| 522 | + 'event_espresso' |
|
| 523 | + ), |
|
| 524 | + $page->label |
|
| 525 | + ) |
|
| 526 | + ); |
|
| 527 | + continue; |
|
| 528 | + } |
|
| 529 | + // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error. |
|
| 530 | + if (! $page_map instanceof EE_Admin_Page_Menu_Map) { |
|
| 531 | + throw new EE_Error( |
|
| 532 | + sprintf( |
|
| 533 | + __( |
|
| 534 | + 'The menu map for %s must be an EE_Admin_Page_Menu_Map object. Instead it is %s. Please double check that the menu map has been configured correctly.', |
|
| 535 | + 'event_espresso' |
|
| 536 | + ), |
|
| 537 | + $page->label, |
|
| 538 | + $page_map |
|
| 539 | + ) |
|
| 540 | + ); |
|
| 541 | + } |
|
| 542 | + // use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array. |
|
| 543 | + if (empty($page_map->maintenance_mode_parent) |
|
| 544 | + && EE_Maintenance_Mode::instance()->level() |
|
| 545 | + == EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
| 546 | + continue; |
|
| 547 | + } |
|
| 548 | + // assign to group (remember $page_map has the admin page stored in it). |
|
| 549 | + $pages_array[ $page_map->menu_group ][] = $page_map; |
|
| 550 | + } |
|
| 551 | + } |
|
| 552 | + if (empty($pages_array)) { |
|
| 553 | + throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso')); |
|
| 554 | + } |
|
| 555 | + // let's sort the groups, make sure it's a valid group, add header (if to show). |
|
| 556 | + foreach ($pages_array as $group => $menu_maps) { |
|
| 557 | + // valid_group? |
|
| 558 | + if (! array_key_exists($group, $menu_groups)) { |
|
| 559 | + continue; |
|
| 560 | + } |
|
| 561 | + // sort pages. |
|
| 562 | + usort($menu_maps, array($this, '_sort_menu_maps')); |
|
| 563 | + // prepend header |
|
| 564 | + array_unshift($menu_maps, $menu_groups[ $group ]); |
|
| 565 | + // reset $pages_array with prepped data |
|
| 566 | + $pages_array[ $group ] = $menu_maps; |
|
| 567 | + } |
|
| 568 | + // now let's setup the _prepped_menu_maps property |
|
| 569 | + foreach ($menu_groups as $group => $group_objs) { |
|
| 570 | + if (isset($pages_array[ $group ])) { |
|
| 571 | + $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]); |
|
| 572 | + } |
|
| 573 | + }/**/ |
|
| 574 | + } |
|
| 575 | + |
|
| 576 | + |
|
| 577 | + /** |
|
| 578 | + * This method is the "workhorse" for detecting and setting up caffeinated functionality. |
|
| 579 | + * In this method there are three checks being done: |
|
| 580 | + * 1. Do we have any NEW admin page sets. If we do, lets add them into the menu setup (via the $installed_refs |
|
| 581 | + * array) etc. (new page sets are found in caffeinated/new/{page}) |
|
| 582 | + * 2. Do we have any EXTENDED page sets. Basically an extended EE_Admin Page extends the core {child}_Admin_Page |
|
| 583 | + * class. eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class: |
|
| 584 | + * Extend_Events_Admin_Page extends Events_Admin_Page. |
|
| 585 | + * 3. Do we have any files just for setting up hooks into other core pages. The files can be any name in |
|
| 586 | + * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the |
|
| 587 | + * classname inside. These classes are instantiated really early so that any hooks in them are run before the |
|
| 588 | + * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated |
|
| 589 | + * admin_pages) |
|
| 590 | + * |
|
| 591 | + * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be |
|
| 592 | + * loaded. |
|
| 593 | + * @return array |
|
| 594 | + */ |
|
| 595 | + private function _set_caffeinated($installed_refs) |
|
| 596 | + { |
|
| 597 | + |
|
| 598 | + // first let's check if there IS a caffeinated folder. If there is not then lets get out. |
|
| 599 | + if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) { |
|
| 600 | + return $installed_refs; |
|
| 601 | + } |
|
| 602 | + $this->_define_caffeinated_constants(); |
|
| 603 | + $exclude = array('tickets'); |
|
| 604 | + // okay let's setup an "New" pages first (we'll return installed refs later) |
|
| 605 | + $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR); |
|
| 606 | + if ($new_admin_screens) { |
|
| 607 | + foreach ($new_admin_screens as $admin_screen) { |
|
| 608 | + // files and anything in the exclude array need not apply |
|
| 609 | + if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
|
| 610 | + // these folders represent the different NEW EE admin pages |
|
| 611 | + $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 612 | + // set autoloaders for our admin page classes based on included path information |
|
| 613 | + EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen); |
|
| 614 | + } |
|
| 615 | + } |
|
| 616 | + } |
|
| 617 | + // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page) |
|
| 618 | + $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR); |
|
| 619 | + if ($extends) { |
|
| 620 | + foreach ($extends as $extend) { |
|
| 621 | + if (is_dir($extend)) { |
|
| 622 | + $extend_ref = basename($extend); |
|
| 623 | + // now let's make sure there is a file that matches the expected format |
|
| 624 | + $filename = str_replace( |
|
| 625 | + ' ', |
|
| 626 | + '_', |
|
| 627 | + ucwords( |
|
| 628 | + str_replace( |
|
| 629 | + '_', |
|
| 630 | + ' ', |
|
| 631 | + $extend_ref |
|
| 632 | + ) |
|
| 633 | + ) |
|
| 634 | + ); |
|
| 635 | + $filename = 'Extend_' . $filename . '_Admin_Page'; |
|
| 636 | + $this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace( |
|
| 637 | + array('\\', '/'), |
|
| 638 | + '/', |
|
| 639 | + EE_CORE_CAF_ADMIN |
|
| 640 | + . 'extend/' |
|
| 641 | + . $extend_ref |
|
| 642 | + . '/' |
|
| 643 | + . $filename |
|
| 644 | + . '.core.php' |
|
| 645 | + ); |
|
| 646 | + $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename; |
|
| 647 | + // set autoloaders for our admin page classes based on included path information |
|
| 648 | + EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend); |
|
| 649 | + } |
|
| 650 | + } |
|
| 651 | + } |
|
| 652 | + // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!). |
|
| 653 | + $ee_admin_hooks = array(); |
|
| 654 | + $hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php'); |
|
| 655 | + if ($hooks) { |
|
| 656 | + foreach ($hooks as $hook) { |
|
| 657 | + if (is_readable($hook)) { |
|
| 658 | + require_once $hook; |
|
| 659 | + $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook); |
|
| 660 | + $classname = str_replace('.class.php', '', $classname); |
|
| 661 | + if (class_exists($classname)) { |
|
| 662 | + $a = new ReflectionClass($classname); |
|
| 663 | + $ee_admin_hooks[] = $a->newInstance(); |
|
| 664 | + } |
|
| 665 | + } |
|
| 666 | + } |
|
| 667 | + }/**/ |
|
| 668 | + $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks); |
|
| 669 | + return $installed_refs; |
|
| 670 | + } |
|
| 671 | + |
|
| 672 | + |
|
| 673 | + /** |
|
| 674 | + * Utility method for sorting the _menu_maps (callback for usort php function) |
|
| 675 | + * |
|
| 676 | + * @since 4.4.0 |
|
| 677 | + * @param EE_Admin_Page_Menu_Map $a menu_map object |
|
| 678 | + * @param EE_Admin_Page_Menu_Map $b being compared to |
|
| 679 | + * @return int sort order |
|
| 680 | + */ |
|
| 681 | + private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b) |
|
| 682 | + { |
|
| 683 | + if ($a->menu_order == $b->menu_order) { |
|
| 684 | + return 0; |
|
| 685 | + } |
|
| 686 | + return ($a->menu_order < $b->menu_order) ? -1 : 1; |
|
| 687 | + } |
|
| 688 | + |
|
| 689 | + |
|
| 690 | + /** |
|
| 691 | + * _default_header_link |
|
| 692 | + * This is just a dummy method to use with header submenu items |
|
| 693 | + * |
|
| 694 | + * @return bool false |
|
| 695 | + */ |
|
| 696 | + public function _default_header_link() |
|
| 697 | + { |
|
| 698 | + return false; |
|
| 699 | + } |
|
| 700 | 700 | } |
@@ -120,13 +120,13 @@ discard block |
||
| 120 | 120 | */ |
| 121 | 121 | private function _define_caffeinated_constants() |
| 122 | 122 | { |
| 123 | - if (! defined('EE_CORE_CAF_ADMIN')) { |
|
| 124 | - define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/'); |
|
| 125 | - define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/'); |
|
| 126 | - define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/'); |
|
| 127 | - define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/'); |
|
| 128 | - define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/'); |
|
| 129 | - define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/'); |
|
| 123 | + if ( ! defined('EE_CORE_CAF_ADMIN')) { |
|
| 124 | + define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/'); |
|
| 125 | + define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/'); |
|
| 126 | + define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/'); |
|
| 127 | + define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/'); |
|
| 128 | + define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/'); |
|
| 129 | + define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/'); |
|
| 130 | 130 | } |
| 131 | 131 | } |
| 132 | 132 | |
@@ -237,7 +237,7 @@ discard block |
||
| 237 | 237 | // first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects ) |
| 238 | 238 | usort($this->_admin_menu_groups, array($this, '_sort_menu_maps')); |
| 239 | 239 | foreach ($this->_admin_menu_groups as $group) { |
| 240 | - if (! $group instanceof EE_Admin_Page_Menu_Group) { |
|
| 240 | + if ( ! $group instanceof EE_Admin_Page_Menu_Group) { |
|
| 241 | 241 | throw new EE_Error( |
| 242 | 242 | sprintf( |
| 243 | 243 | __( |
@@ -248,7 +248,7 @@ discard block |
||
| 248 | 248 | ) |
| 249 | 249 | ); |
| 250 | 250 | } |
| 251 | - $groups[ $group->menu_slug ] = $group; |
|
| 251 | + $groups[$group->menu_slug] = $group; |
|
| 252 | 252 | } |
| 253 | 253 | return $groups; |
| 254 | 254 | } |
@@ -267,13 +267,13 @@ discard block |
||
| 267 | 267 | $installed_refs = array(); |
| 268 | 268 | $exclude = array('assets', 'templates'); |
| 269 | 269 | // grab everything in the admin core directory |
| 270 | - $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR); |
|
| 270 | + $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR); |
|
| 271 | 271 | if ($admin_screens) { |
| 272 | 272 | foreach ($admin_screens as $admin_screen) { |
| 273 | 273 | // files and anything in the exclude array need not apply |
| 274 | 274 | if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
| 275 | 275 | // these folders represent the different EE admin pages |
| 276 | - $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 276 | + $installed_refs[basename($admin_screen)] = $admin_screen; |
|
| 277 | 277 | } |
| 278 | 278 | } |
| 279 | 279 | } |
@@ -282,7 +282,7 @@ discard block |
||
| 282 | 282 | 'There are no EE_Admin pages detected, it looks like EE did not install properly', |
| 283 | 283 | 'event_espresso' |
| 284 | 284 | ); |
| 285 | - $error_msg[] = $error_msg[0] . "\r\n" |
|
| 285 | + $error_msg[] = $error_msg[0]."\r\n" |
|
| 286 | 286 | . sprintf( |
| 287 | 287 | __( |
| 288 | 288 | 'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.', |
@@ -309,46 +309,46 @@ discard block |
||
| 309 | 309 | // set autoloaders for our admin page classes based on included path information |
| 310 | 310 | EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path); |
| 311 | 311 | // build list of installed pages |
| 312 | - $this->_installed_pages[ $page ] = $this->_load_admin_page($page, $path); |
|
| 312 | + $this->_installed_pages[$page] = $this->_load_admin_page($page, $path); |
|
| 313 | 313 | // verify returned object |
| 314 | - if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 315 | - if (! $this->_installed_pages[ $page ]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) { |
|
| 314 | + if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) { |
|
| 315 | + if ( ! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) { |
|
| 316 | 316 | continue; |
| 317 | 317 | } |
| 318 | 318 | // skip if in full maintenance mode and maintenance_mode_parent is set |
| 319 | - $maintenance_mode_parent = $this->_installed_pages[ $page ]->get_menu_map()->maintenance_mode_parent; |
|
| 319 | + $maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent; |
|
| 320 | 320 | if (empty($maintenance_mode_parent) |
| 321 | 321 | && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance |
| 322 | 322 | ) { |
| 323 | - unset($installed_refs[ $page ]); |
|
| 323 | + unset($installed_refs[$page]); |
|
| 324 | 324 | continue; |
| 325 | 325 | } |
| 326 | - $menu_slug = $this->_installed_pages[ $page ]->get_menu_map()->menu_slug; |
|
| 327 | - $this->_menu_slugs[ $menu_slug ] = $page; |
|
| 326 | + $menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug; |
|
| 327 | + $this->_menu_slugs[$menu_slug] = $page; |
|
| 328 | 328 | // flag for register hooks on extended pages b/c extended pages use the default INIT. |
| 329 | 329 | $extend = false; |
| 330 | 330 | // now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals. If there are then let's hook into the init admin filter and load our extend instead. |
| 331 | - if (isset($this->_caffeinated_extends[ $page ])) { |
|
| 331 | + if (isset($this->_caffeinated_extends[$page])) { |
|
| 332 | 332 | $this->_current_caf_extend_slug = $page; |
| 333 | - $admin_page_name = $this->_installed_pages[ $page ]->get_admin_page_name(); |
|
| 334 | - $caf_path = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['path']; |
|
| 335 | - $caf_admin_page = $this->_caffeinated_extends[ $this->_current_caf_extend_slug ]['admin_page']; |
|
| 333 | + $admin_page_name = $this->_installed_pages[$page]->get_admin_page_name(); |
|
| 334 | + $caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path']; |
|
| 335 | + $caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page']; |
|
| 336 | 336 | add_filter( |
| 337 | 337 | "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}", |
| 338 | - function ($path_to_file) use ($caf_path) { |
|
| 338 | + function($path_to_file) use ($caf_path) { |
|
| 339 | 339 | return $caf_path; |
| 340 | 340 | } |
| 341 | 341 | ); |
| 342 | 342 | add_filter( |
| 343 | 343 | "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}", |
| 344 | - function ($admin_page) use ($caf_admin_page) { |
|
| 344 | + function($admin_page) use ($caf_admin_page) { |
|
| 345 | 345 | return $caf_admin_page; |
| 346 | 346 | } |
| 347 | 347 | ); |
| 348 | 348 | $extend = true; |
| 349 | 349 | } |
| 350 | 350 | // let's do the registered hooks |
| 351 | - $extended_hooks = $this->_installed_pages[ $page ]->register_hooks($extend); |
|
| 351 | + $extended_hooks = $this->_installed_pages[$page]->register_hooks($extend); |
|
| 352 | 352 | $hooks_ref = array_merge($hooks_ref, $extended_hooks); |
| 353 | 353 | } |
| 354 | 354 | } |
@@ -364,8 +364,8 @@ discard block |
||
| 364 | 364 | $ee_menu_slugs = $this->_menu_slugs; |
| 365 | 365 | // we need to loop again to run any early code |
| 366 | 366 | foreach ($installed_refs as $page => $path) { |
| 367 | - if ($this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init) { |
|
| 368 | - $this->_installed_pages[ $page ]->do_initial_loads(); |
|
| 367 | + if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) { |
|
| 368 | + $this->_installed_pages[$page]->do_initial_loads(); |
|
| 369 | 369 | } |
| 370 | 370 | } |
| 371 | 371 | do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages); |
@@ -380,8 +380,8 @@ discard block |
||
| 380 | 380 | */ |
| 381 | 381 | public function get_admin_page_object($page_slug = '') |
| 382 | 382 | { |
| 383 | - if (isset($this->_installed_pages[ $page_slug ])) { |
|
| 384 | - return $this->_installed_pages[ $page_slug ]->loaded_page_object(); |
|
| 383 | + if (isset($this->_installed_pages[$page_slug])) { |
|
| 384 | + return $this->_installed_pages[$page_slug]->loaded_page_object(); |
|
| 385 | 385 | } |
| 386 | 386 | return null; |
| 387 | 387 | } |
@@ -397,7 +397,7 @@ discard block |
||
| 397 | 397 | private function _get_classname_for_admin_page($dir_name = '') |
| 398 | 398 | { |
| 399 | 399 | $class_name = str_replace('_', ' ', strtolower($dir_name)); |
| 400 | - return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page'; |
|
| 400 | + return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page'; |
|
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | |
@@ -411,7 +411,7 @@ discard block |
||
| 411 | 411 | private function _get_classname_for_admin_init_page($dir_name = '') |
| 412 | 412 | { |
| 413 | 413 | $class_name = str_replace('_', ' ', strtolower($dir_name)); |
| 414 | - return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init'; |
|
| 414 | + return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init'; |
|
| 415 | 415 | } |
| 416 | 416 | |
| 417 | 417 | |
@@ -428,14 +428,14 @@ discard block |
||
| 428 | 428 | { |
| 429 | 429 | $class_name = $this->_get_classname_for_admin_init_page($page); |
| 430 | 430 | EE_Registry::instance()->load_file($path, $class_name, 'core'); |
| 431 | - if (! class_exists($class_name)) { |
|
| 431 | + if ( ! class_exists($class_name)) { |
|
| 432 | 432 | $inner_error_msg = '<br />' |
| 433 | 433 | . sprintf( |
| 434 | 434 | esc_html__( |
| 435 | 435 | 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
| 436 | 436 | 'event_espresso' |
| 437 | 437 | ), |
| 438 | - '<strong>' . $class_name . '</strong>' |
|
| 438 | + '<strong>'.$class_name.'</strong>' |
|
| 439 | 439 | ); |
| 440 | 440 | $error_msg[] = sprintf( |
| 441 | 441 | __('Something went wrong with loading the %s admin page.', 'event_espresso'), |
@@ -515,7 +515,7 @@ discard block |
||
| 515 | 515 | // if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item. |
| 516 | 516 | if (is_array($page_map) || empty($page_map)) { |
| 517 | 517 | new PersistentAdminNotice( |
| 518 | - 'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION, |
|
| 518 | + 'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION, |
|
| 519 | 519 | sprintf( |
| 520 | 520 | __( |
| 521 | 521 | 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core. This means that full functionality for this component is not available. This error message usually appears with an Add-on that is out of date. Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.', |
@@ -527,7 +527,7 @@ discard block |
||
| 527 | 527 | continue; |
| 528 | 528 | } |
| 529 | 529 | // if page map is NOT a EE_Admin_Page_Menu_Map object then throw error. |
| 530 | - if (! $page_map instanceof EE_Admin_Page_Menu_Map) { |
|
| 530 | + if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) { |
|
| 531 | 531 | throw new EE_Error( |
| 532 | 532 | sprintf( |
| 533 | 533 | __( |
@@ -546,7 +546,7 @@ discard block |
||
| 546 | 546 | continue; |
| 547 | 547 | } |
| 548 | 548 | // assign to group (remember $page_map has the admin page stored in it). |
| 549 | - $pages_array[ $page_map->menu_group ][] = $page_map; |
|
| 549 | + $pages_array[$page_map->menu_group][] = $page_map; |
|
| 550 | 550 | } |
| 551 | 551 | } |
| 552 | 552 | if (empty($pages_array)) { |
@@ -555,20 +555,20 @@ discard block |
||
| 555 | 555 | // let's sort the groups, make sure it's a valid group, add header (if to show). |
| 556 | 556 | foreach ($pages_array as $group => $menu_maps) { |
| 557 | 557 | // valid_group? |
| 558 | - if (! array_key_exists($group, $menu_groups)) { |
|
| 558 | + if ( ! array_key_exists($group, $menu_groups)) { |
|
| 559 | 559 | continue; |
| 560 | 560 | } |
| 561 | 561 | // sort pages. |
| 562 | 562 | usort($menu_maps, array($this, '_sort_menu_maps')); |
| 563 | 563 | // prepend header |
| 564 | - array_unshift($menu_maps, $menu_groups[ $group ]); |
|
| 564 | + array_unshift($menu_maps, $menu_groups[$group]); |
|
| 565 | 565 | // reset $pages_array with prepped data |
| 566 | - $pages_array[ $group ] = $menu_maps; |
|
| 566 | + $pages_array[$group] = $menu_maps; |
|
| 567 | 567 | } |
| 568 | 568 | // now let's setup the _prepped_menu_maps property |
| 569 | 569 | foreach ($menu_groups as $group => $group_objs) { |
| 570 | - if (isset($pages_array[ $group ])) { |
|
| 571 | - $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[ $group ]); |
|
| 570 | + if (isset($pages_array[$group])) { |
|
| 571 | + $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]); |
|
| 572 | 572 | } |
| 573 | 573 | }/**/ |
| 574 | 574 | } |
@@ -596,26 +596,26 @@ discard block |
||
| 596 | 596 | { |
| 597 | 597 | |
| 598 | 598 | // first let's check if there IS a caffeinated folder. If there is not then lets get out. |
| 599 | - if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) { |
|
| 599 | + if ( ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated/admin') || (defined('EE_DECAF') && EE_DECAF)) { |
|
| 600 | 600 | return $installed_refs; |
| 601 | 601 | } |
| 602 | 602 | $this->_define_caffeinated_constants(); |
| 603 | 603 | $exclude = array('tickets'); |
| 604 | 604 | // okay let's setup an "New" pages first (we'll return installed refs later) |
| 605 | - $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR); |
|
| 605 | + $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR); |
|
| 606 | 606 | if ($new_admin_screens) { |
| 607 | 607 | foreach ($new_admin_screens as $admin_screen) { |
| 608 | 608 | // files and anything in the exclude array need not apply |
| 609 | 609 | if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) { |
| 610 | 610 | // these folders represent the different NEW EE admin pages |
| 611 | - $installed_refs[ basename($admin_screen) ] = $admin_screen; |
|
| 611 | + $installed_refs[basename($admin_screen)] = $admin_screen; |
|
| 612 | 612 | // set autoloaders for our admin page classes based on included path information |
| 613 | 613 | EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen); |
| 614 | 614 | } |
| 615 | 615 | } |
| 616 | 616 | } |
| 617 | 617 | // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page) |
| 618 | - $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR); |
|
| 618 | + $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR); |
|
| 619 | 619 | if ($extends) { |
| 620 | 620 | foreach ($extends as $extend) { |
| 621 | 621 | if (is_dir($extend)) { |
@@ -632,8 +632,8 @@ discard block |
||
| 632 | 632 | ) |
| 633 | 633 | ) |
| 634 | 634 | ); |
| 635 | - $filename = 'Extend_' . $filename . '_Admin_Page'; |
|
| 636 | - $this->_caffeinated_extends[ $extend_ref ]['path'] = str_replace( |
|
| 635 | + $filename = 'Extend_'.$filename.'_Admin_Page'; |
|
| 636 | + $this->_caffeinated_extends[$extend_ref]['path'] = str_replace( |
|
| 637 | 637 | array('\\', '/'), |
| 638 | 638 | '/', |
| 639 | 639 | EE_CORE_CAF_ADMIN |
@@ -643,7 +643,7 @@ discard block |
||
| 643 | 643 | . $filename |
| 644 | 644 | . '.core.php' |
| 645 | 645 | ); |
| 646 | - $this->_caffeinated_extends[ $extend_ref ]['admin_page'] = $filename; |
|
| 646 | + $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename; |
|
| 647 | 647 | // set autoloaders for our admin page classes based on included path information |
| 648 | 648 | EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend); |
| 649 | 649 | } |
@@ -651,12 +651,12 @@ discard block |
||
| 651 | 651 | } |
| 652 | 652 | // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!). |
| 653 | 653 | $ee_admin_hooks = array(); |
| 654 | - $hooks = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php'); |
|
| 654 | + $hooks = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php'); |
|
| 655 | 655 | if ($hooks) { |
| 656 | 656 | foreach ($hooks as $hook) { |
| 657 | 657 | if (is_readable($hook)) { |
| 658 | 658 | require_once $hook; |
| 659 | - $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook); |
|
| 659 | + $classname = str_replace(EE_CORE_CAF_ADMIN.'hooks/', '', $hook); |
|
| 660 | 660 | $classname = str_replace('.class.php', '', $classname); |
| 661 | 661 | if (class_exists($classname)) { |
| 662 | 662 | $a = new ReflectionClass($classname); |
@@ -13,424 +13,424 @@ |
||
| 13 | 13 | abstract class EE_Admin_Page_Init extends EE_Base |
| 14 | 14 | { |
| 15 | 15 | |
| 16 | - // identity properties (set in _set_defaults and _set_init_properties) |
|
| 17 | - public $label; |
|
| 18 | - |
|
| 19 | - /** |
|
| 20 | - * Menu map has a capability. However, this allows admin pages to have separate capability requirements for menus |
|
| 21 | - * and accessing pages. If capability is NOT set, then it defaults to the menu_map capability. |
|
| 22 | - * |
|
| 23 | - * @var string |
|
| 24 | - */ |
|
| 25 | - public $capability; |
|
| 26 | - |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * This holds the menu map object for this admin page. |
|
| 30 | - * |
|
| 31 | - * @var EE_Admin_Page_Menu_Map |
|
| 32 | - */ |
|
| 33 | - protected $_menu_map; |
|
| 34 | - |
|
| 35 | - /** |
|
| 36 | - * deprecated |
|
| 37 | - */ |
|
| 38 | - public $menu_label; |
|
| 39 | - public $menu_slug; |
|
| 40 | - |
|
| 41 | - |
|
| 42 | - // set in _set_defaults |
|
| 43 | - protected $_folder_name; |
|
| 44 | - protected $_folder_path; |
|
| 45 | - protected $_file_name; |
|
| 46 | - public $hook_file; |
|
| 47 | - protected $_wp_page_slug; |
|
| 48 | - protected $_routing; |
|
| 49 | - |
|
| 50 | - |
|
| 51 | - // will hold page object. |
|
| 52 | - protected $_loaded_page_object; |
|
| 53 | - |
|
| 54 | - |
|
| 55 | - // for caf |
|
| 56 | - protected $_files_hooked; |
|
| 57 | - protected $_hook_paths; |
|
| 58 | - |
|
| 59 | - // load_page? |
|
| 60 | - private $_load_page; |
|
| 61 | - |
|
| 62 | - |
|
| 63 | - /** |
|
| 64 | - * @Constructor |
|
| 65 | - * @access public |
|
| 66 | - * @return void |
|
| 67 | - */ |
|
| 68 | - public function __construct() |
|
| 69 | - { |
|
| 70 | - // set global defaults |
|
| 71 | - $this->_set_defaults(); |
|
| 72 | - // set properties that are always available with objects. |
|
| 73 | - $this->_set_init_properties(); |
|
| 74 | - // global styles/scripts across all wp admin pages |
|
| 75 | - add_action('admin_enqueue_scripts', array($this, 'load_wp_global_scripts_styles'), 5); |
|
| 76 | - // load initial stuff. |
|
| 77 | - $this->_set_file_and_folder_name(); |
|
| 78 | - $this->_set_menu_map(); |
|
| 79 | - if (empty($this->_menu_map) || is_array($this->_menu_map)) { |
|
| 80 | - EE_Error::doing_it_wrong( |
|
| 81 | - get_class($this) . '::$_menu_map', |
|
| 82 | - sprintf( |
|
| 83 | - __( |
|
| 84 | - 'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core. Please see Admin_Page_Init class examples in core for the new way of setting this property up.', |
|
| 85 | - 'event_espresso' |
|
| 86 | - ), |
|
| 87 | - get_class($this) |
|
| 88 | - ), |
|
| 89 | - '4.4.0' |
|
| 90 | - ); |
|
| 91 | - return; |
|
| 92 | - } |
|
| 93 | - // set default capability |
|
| 94 | - $this->_set_capability(); |
|
| 95 | - } |
|
| 96 | - |
|
| 97 | - |
|
| 98 | - /** |
|
| 99 | - * _set_init_properties |
|
| 100 | - * Child classes use to set the following properties: |
|
| 101 | - * $label |
|
| 102 | - * |
|
| 103 | - * @abstract |
|
| 104 | - * @access protected |
|
| 105 | - * @return void |
|
| 106 | - */ |
|
| 107 | - abstract protected function _set_init_properties(); |
|
| 108 | - |
|
| 109 | - |
|
| 110 | - /** |
|
| 111 | - * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of |
|
| 112 | - * EE_Admin_Page_Menu_Map. Their menu can either be EE_Admin_Page_Main_Menu or EE_Admin_Page_Sub_Menu. |
|
| 113 | - * |
|
| 114 | - * @since 4.4.0 |
|
| 115 | - * @ return void. |
|
| 116 | - */ |
|
| 117 | - protected function _set_menu_map() |
|
| 118 | - { |
|
| 119 | - return array(); |
|
| 120 | - } |
|
| 121 | - |
|
| 122 | - |
|
| 123 | - /** |
|
| 124 | - * returns the menu map for this admin page |
|
| 125 | - * |
|
| 126 | - * @since 4.4.0 |
|
| 127 | - * @return EE_Admin_Page_Menu_Map |
|
| 128 | - */ |
|
| 129 | - public function get_menu_map() |
|
| 130 | - { |
|
| 131 | - return $this->_menu_map; |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - |
|
| 135 | - /** |
|
| 136 | - * This loads scripts and styles for the EE_Admin system |
|
| 137 | - * that must be available on ALL WP admin pages (i.e. EE_menu items) |
|
| 138 | - * |
|
| 139 | - * @return void |
|
| 140 | - */ |
|
| 141 | - public function load_wp_global_scripts_styles() |
|
| 142 | - { |
|
| 143 | - wp_register_style( |
|
| 144 | - 'espresso_menu', |
|
| 145 | - EE_ADMIN_URL . 'assets/admin-menu-styles.css', |
|
| 146 | - array('dashicons'), |
|
| 147 | - EVENT_ESPRESSO_VERSION |
|
| 148 | - ); |
|
| 149 | - wp_enqueue_style('espresso_menu'); |
|
| 150 | - } |
|
| 151 | - |
|
| 152 | - |
|
| 153 | - /** |
|
| 154 | - * this sets default properties (might be overridden in _set_init_properties); |
|
| 155 | - * |
|
| 156 | - * @access private |
|
| 157 | - * @return void |
|
| 158 | - */ |
|
| 159 | - private function _set_defaults() |
|
| 160 | - { |
|
| 161 | - $this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null; |
|
| 162 | - $this->_routing = true; |
|
| 163 | - $this->_load_page = false; |
|
| 164 | - $this->_files_hooked = $this->_hook_paths = array(); |
|
| 165 | - // menu_map |
|
| 166 | - $this->_menu_map = $this->get_menu_map(); |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - |
|
| 170 | - protected function _set_capability() |
|
| 171 | - { |
|
| 172 | - $capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability; |
|
| 173 | - $this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability); |
|
| 174 | - } |
|
| 175 | - |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * initialize_admin_page |
|
| 179 | - * This method is what executes the loading of the specific page class for the given dir_name as called by the |
|
| 180 | - * EE_Admin_Init class. |
|
| 181 | - * |
|
| 182 | - * @access public |
|
| 183 | - * @uses _initialize_admin_page() |
|
| 184 | - * @param string $dir_name directory name for specific admin_page being loaded. |
|
| 185 | - * @return void |
|
| 186 | - */ |
|
| 187 | - public function initialize_admin_page() |
|
| 188 | - { |
|
| 189 | - // let's check user access first |
|
| 190 | - $this->_check_user_access(); |
|
| 191 | - if (! is_object($this->_loaded_page_object)) { |
|
| 192 | - return; |
|
| 193 | - } |
|
| 194 | - $this->_loaded_page_object->route_admin_request(); |
|
| 195 | - return; |
|
| 196 | - } |
|
| 197 | - |
|
| 198 | - |
|
| 199 | - public function set_page_dependencies($wp_page_slug) |
|
| 200 | - { |
|
| 201 | - if (! $this->_load_page) { |
|
| 202 | - return; |
|
| 203 | - } |
|
| 204 | - if (! is_object($this->_loaded_page_object)) { |
|
| 205 | - $msg[] = __( |
|
| 206 | - 'We can\'t load the page because we\'re missing a valid page object that tells us what to load', |
|
| 207 | - 'event_espresso' |
|
| 208 | - ); |
|
| 209 | - $msg[] = $msg[0] . "\r\n" |
|
| 210 | - . sprintf( |
|
| 211 | - __( |
|
| 212 | - 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory', |
|
| 213 | - 'event_espresso' |
|
| 214 | - ), |
|
| 215 | - $this->_file_name, |
|
| 216 | - $this->_file_name, |
|
| 217 | - $this->_folder_path . $this->_file_name, |
|
| 218 | - $this->_menu_map->menu_slug |
|
| 219 | - ); |
|
| 220 | - throw new EE_Error(implode('||', $msg)); |
|
| 221 | - } |
|
| 222 | - $this->_loaded_page_object->set_wp_page_slug($wp_page_slug); |
|
| 223 | - $page_hook = 'load-' . $wp_page_slug; |
|
| 224 | - // hook into page load hook so all page specific stuff get's loaded. |
|
| 225 | - if (! empty($wp_page_slug)) { |
|
| 226 | - add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies')); |
|
| 227 | - } |
|
| 228 | - } |
|
| 229 | - |
|
| 230 | - |
|
| 231 | - /** |
|
| 232 | - * This executes the intial page loads for EE_Admin pages to take care of any ajax or other code needing to run |
|
| 233 | - * before the load-page... hook. Note, the page loads are happening around the wp_init hook. |
|
| 234 | - * |
|
| 235 | - * @return void |
|
| 236 | - */ |
|
| 237 | - public function do_initial_loads() |
|
| 238 | - { |
|
| 239 | - // no loading or initializing if menu map is setup incorrectly. |
|
| 240 | - if (empty($this->_menu_map) || is_array($this->_menu_map)) { |
|
| 241 | - return; |
|
| 242 | - } |
|
| 243 | - $this->_initialize_admin_page(); |
|
| 244 | - } |
|
| 245 | - |
|
| 246 | - |
|
| 247 | - /** |
|
| 248 | - * all we're doing here is setting the $_file_name property for later use. |
|
| 249 | - * |
|
| 250 | - * @access private |
|
| 251 | - * @return void |
|
| 252 | - */ |
|
| 253 | - private function _set_file_and_folder_name() |
|
| 254 | - { |
|
| 255 | - $bt = debug_backtrace(); |
|
| 256 | - // for more reliable determination of folder name |
|
| 257 | - // we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this). Why? Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins) |
|
| 258 | - $class = get_class($this); |
|
| 259 | - foreach ($bt as $index => $values) { |
|
| 260 | - if (isset($values['class']) && $values['class'] == $class) { |
|
| 261 | - $file_index = $index - 1; |
|
| 262 | - $this->_folder_name = basename(dirname($bt[ $file_index ]['file'])); |
|
| 263 | - if (! empty($this->_folder_name)) { |
|
| 264 | - break; |
|
| 265 | - } |
|
| 266 | - } |
|
| 267 | - } |
|
| 268 | - $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/'; |
|
| 269 | - $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name); |
|
| 270 | - $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name)); |
|
| 271 | - $this->_file_name = str_replace(' ', '_', $this->_file_name); |
|
| 272 | - } |
|
| 273 | - |
|
| 274 | - |
|
| 275 | - /** |
|
| 276 | - * This automatically checks if we have a hook class in the loaded child directory. If we DO then we will register |
|
| 277 | - * it with the appropriate pages. That way all we have to do is make sure the file is named correctly and |
|
| 278 | - * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do: |
|
| 279 | - * events_Messages_Hooks.class.php |
|
| 280 | - * |
|
| 281 | - * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks |
|
| 282 | - * files/classes |
|
| 283 | - * @return array |
|
| 284 | - */ |
|
| 285 | - public function register_hooks($extend = false) |
|
| 286 | - { |
|
| 287 | - |
|
| 288 | - // get a list of files in the directory that have the "Hook" in their name an |
|
| 289 | - // if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property. Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf. |
|
| 290 | - if ($extend) { |
|
| 291 | - $hook_files_glob_path = apply_filters( |
|
| 292 | - 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend', |
|
| 293 | - EE_CORE_CAF_ADMIN_EXTEND |
|
| 294 | - . $this->_folder_name |
|
| 295 | - . '/*' |
|
| 296 | - . $this->_file_name |
|
| 297 | - . '_Hooks_Extend.class.php' |
|
| 298 | - ); |
|
| 299 | - $this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend); |
|
| 300 | - } |
|
| 301 | - // loop through decaf folders |
|
| 302 | - $hook_files_glob_path = apply_filters( |
|
| 303 | - 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path', |
|
| 304 | - $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php' |
|
| 305 | - ); |
|
| 306 | - $this->_hook_paths = array_merge( |
|
| 307 | - $this->_register_hook_files($hook_files_glob_path), |
|
| 308 | - $this->_hook_paths |
|
| 309 | - ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
| 310 | - return $this->_hook_paths; |
|
| 311 | - } |
|
| 312 | - |
|
| 313 | - |
|
| 314 | - protected function _register_hook_files($hook_files_glob_path, $extend = false) |
|
| 315 | - { |
|
| 316 | - $hook_paths = array(); |
|
| 317 | - if ($hook_files = glob($hook_files_glob_path)) { |
|
| 318 | - if (empty($hook_files)) { |
|
| 319 | - return array(); |
|
| 320 | - } |
|
| 321 | - foreach ($hook_files as $file) { |
|
| 322 | - // lets get the linked admin. |
|
| 323 | - $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file) |
|
| 324 | - : str_replace($this->_folder_path, '', $file); |
|
| 325 | - $replace = $extend |
|
| 326 | - ? '_' . $this->_file_name . '_Hooks_Extend.class.php' |
|
| 327 | - : '_' |
|
| 328 | - . $this->_file_name |
|
| 329 | - . '_Hooks.class.php'; |
|
| 330 | - $rel_admin = str_replace($replace, '', $hook_file); |
|
| 331 | - $rel_admin = strtolower($rel_admin); |
|
| 332 | - $hook_paths[] = $file; |
|
| 333 | - // make sure we haven't already got a hook setup for this page path |
|
| 334 | - if (in_array($rel_admin, $this->_files_hooked)) { |
|
| 335 | - continue; |
|
| 336 | - } |
|
| 337 | - $this->hook_file = $hook_file; |
|
| 338 | - $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin; |
|
| 339 | - $filter = add_filter($rel_admin_hook, array($this, 'load_admin_hook')); |
|
| 340 | - $this->_files_hooked[] = $rel_admin; |
|
| 341 | - } |
|
| 342 | - } |
|
| 343 | - return $hook_paths; |
|
| 344 | - } |
|
| 345 | - |
|
| 346 | - |
|
| 347 | - public function load_admin_hook($registered_pages) |
|
| 348 | - { |
|
| 349 | - $this->hook_file; |
|
| 350 | - $hook_file = (array) $this->hook_file; |
|
| 351 | - return array_merge($hook_file, $registered_pages); |
|
| 352 | - } |
|
| 353 | - |
|
| 354 | - |
|
| 355 | - /** |
|
| 356 | - * _initialize_admin_page |
|
| 357 | - * |
|
| 358 | - * @see initialize_admin_page() for info |
|
| 359 | - */ |
|
| 360 | - protected function _initialize_admin_page() |
|
| 361 | - { |
|
| 362 | - |
|
| 363 | - // JUST CHECK WE'RE ON RIGHT PAGE. |
|
| 364 | - if ((! isset($_REQUEST['page']) || $_REQUEST['page'] != $this->_menu_map->menu_slug) && $this->_routing) { |
|
| 365 | - return; |
|
| 366 | - } //not on the right page so let's get out. |
|
| 367 | - $this->_load_page = true; |
|
| 368 | - |
|
| 369 | - // we don't need to do a page_request check here because it's only called via WP menu system. |
|
| 370 | - $admin_page = $this->_file_name . '_Admin_Page'; |
|
| 371 | - $hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page; |
|
| 372 | - $admin_page = apply_filters( |
|
| 373 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}", |
|
| 374 | - $admin_page |
|
| 375 | - ); |
|
| 376 | - // define requested admin page class name then load the file and instantiate |
|
| 377 | - $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php'); |
|
| 378 | - $path_to_file = apply_filters( |
|
| 379 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}", |
|
| 380 | - $path_to_file |
|
| 381 | - );// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
| 382 | - if (is_readable($path_to_file)) { |
|
| 383 | - // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place |
|
| 384 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization'); |
|
| 385 | - do_action( |
|
| 386 | - 'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug |
|
| 387 | - ); |
|
| 388 | - require_once($path_to_file); |
|
| 389 | - $a = new ReflectionClass($admin_page); |
|
| 390 | - $this->_loaded_page_object = $a->newInstance($this->_routing); |
|
| 391 | - } |
|
| 392 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization'); |
|
| 393 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug); |
|
| 394 | - } |
|
| 395 | - |
|
| 396 | - |
|
| 397 | - public function get_admin_page_name() |
|
| 398 | - { |
|
| 399 | - return $this->_file_name . '_Admin_Page'; |
|
| 400 | - } |
|
| 401 | - |
|
| 402 | - |
|
| 403 | - /** |
|
| 404 | - * @return mixed |
|
| 405 | - */ |
|
| 406 | - public function loaded_page_object() |
|
| 407 | - { |
|
| 408 | - return $this->_loaded_page_object; |
|
| 409 | - } |
|
| 410 | - |
|
| 411 | - |
|
| 412 | - // public function set_autoloaders($className) |
|
| 413 | - // { |
|
| 414 | - // $dir_ref = array( |
|
| 415 | - // $this->_folder_path => array('core', 'class'), |
|
| 416 | - // ); |
|
| 417 | - // EEH_Autoloader::try_autoload($dir_ref, $className); |
|
| 418 | - // } |
|
| 419 | - /** |
|
| 420 | - * _check_user_access |
|
| 421 | - * verifies user access for this admin page. If no user access is available then let's gracefully exit with a |
|
| 422 | - * WordPress die message. |
|
| 423 | - * |
|
| 424 | - * @return bool|die true if pass (or admin) wp_die if fail |
|
| 425 | - */ |
|
| 426 | - private function _check_user_access() |
|
| 427 | - { |
|
| 428 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 429 | - $this->_menu_map->capability, |
|
| 430 | - $this->_menu_map->menu_slug |
|
| 431 | - )) { |
|
| 432 | - wp_die(__('You don\'t have access to this page.', 'event_espresso'), '', array('back_link' => true)); |
|
| 433 | - } |
|
| 434 | - return true; |
|
| 435 | - } |
|
| 16 | + // identity properties (set in _set_defaults and _set_init_properties) |
|
| 17 | + public $label; |
|
| 18 | + |
|
| 19 | + /** |
|
| 20 | + * Menu map has a capability. However, this allows admin pages to have separate capability requirements for menus |
|
| 21 | + * and accessing pages. If capability is NOT set, then it defaults to the menu_map capability. |
|
| 22 | + * |
|
| 23 | + * @var string |
|
| 24 | + */ |
|
| 25 | + public $capability; |
|
| 26 | + |
|
| 27 | + |
|
| 28 | + /** |
|
| 29 | + * This holds the menu map object for this admin page. |
|
| 30 | + * |
|
| 31 | + * @var EE_Admin_Page_Menu_Map |
|
| 32 | + */ |
|
| 33 | + protected $_menu_map; |
|
| 34 | + |
|
| 35 | + /** |
|
| 36 | + * deprecated |
|
| 37 | + */ |
|
| 38 | + public $menu_label; |
|
| 39 | + public $menu_slug; |
|
| 40 | + |
|
| 41 | + |
|
| 42 | + // set in _set_defaults |
|
| 43 | + protected $_folder_name; |
|
| 44 | + protected $_folder_path; |
|
| 45 | + protected $_file_name; |
|
| 46 | + public $hook_file; |
|
| 47 | + protected $_wp_page_slug; |
|
| 48 | + protected $_routing; |
|
| 49 | + |
|
| 50 | + |
|
| 51 | + // will hold page object. |
|
| 52 | + protected $_loaded_page_object; |
|
| 53 | + |
|
| 54 | + |
|
| 55 | + // for caf |
|
| 56 | + protected $_files_hooked; |
|
| 57 | + protected $_hook_paths; |
|
| 58 | + |
|
| 59 | + // load_page? |
|
| 60 | + private $_load_page; |
|
| 61 | + |
|
| 62 | + |
|
| 63 | + /** |
|
| 64 | + * @Constructor |
|
| 65 | + * @access public |
|
| 66 | + * @return void |
|
| 67 | + */ |
|
| 68 | + public function __construct() |
|
| 69 | + { |
|
| 70 | + // set global defaults |
|
| 71 | + $this->_set_defaults(); |
|
| 72 | + // set properties that are always available with objects. |
|
| 73 | + $this->_set_init_properties(); |
|
| 74 | + // global styles/scripts across all wp admin pages |
|
| 75 | + add_action('admin_enqueue_scripts', array($this, 'load_wp_global_scripts_styles'), 5); |
|
| 76 | + // load initial stuff. |
|
| 77 | + $this->_set_file_and_folder_name(); |
|
| 78 | + $this->_set_menu_map(); |
|
| 79 | + if (empty($this->_menu_map) || is_array($this->_menu_map)) { |
|
| 80 | + EE_Error::doing_it_wrong( |
|
| 81 | + get_class($this) . '::$_menu_map', |
|
| 82 | + sprintf( |
|
| 83 | + __( |
|
| 84 | + 'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core. Please see Admin_Page_Init class examples in core for the new way of setting this property up.', |
|
| 85 | + 'event_espresso' |
|
| 86 | + ), |
|
| 87 | + get_class($this) |
|
| 88 | + ), |
|
| 89 | + '4.4.0' |
|
| 90 | + ); |
|
| 91 | + return; |
|
| 92 | + } |
|
| 93 | + // set default capability |
|
| 94 | + $this->_set_capability(); |
|
| 95 | + } |
|
| 96 | + |
|
| 97 | + |
|
| 98 | + /** |
|
| 99 | + * _set_init_properties |
|
| 100 | + * Child classes use to set the following properties: |
|
| 101 | + * $label |
|
| 102 | + * |
|
| 103 | + * @abstract |
|
| 104 | + * @access protected |
|
| 105 | + * @return void |
|
| 106 | + */ |
|
| 107 | + abstract protected function _set_init_properties(); |
|
| 108 | + |
|
| 109 | + |
|
| 110 | + /** |
|
| 111 | + * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of |
|
| 112 | + * EE_Admin_Page_Menu_Map. Their menu can either be EE_Admin_Page_Main_Menu or EE_Admin_Page_Sub_Menu. |
|
| 113 | + * |
|
| 114 | + * @since 4.4.0 |
|
| 115 | + * @ return void. |
|
| 116 | + */ |
|
| 117 | + protected function _set_menu_map() |
|
| 118 | + { |
|
| 119 | + return array(); |
|
| 120 | + } |
|
| 121 | + |
|
| 122 | + |
|
| 123 | + /** |
|
| 124 | + * returns the menu map for this admin page |
|
| 125 | + * |
|
| 126 | + * @since 4.4.0 |
|
| 127 | + * @return EE_Admin_Page_Menu_Map |
|
| 128 | + */ |
|
| 129 | + public function get_menu_map() |
|
| 130 | + { |
|
| 131 | + return $this->_menu_map; |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + |
|
| 135 | + /** |
|
| 136 | + * This loads scripts and styles for the EE_Admin system |
|
| 137 | + * that must be available on ALL WP admin pages (i.e. EE_menu items) |
|
| 138 | + * |
|
| 139 | + * @return void |
|
| 140 | + */ |
|
| 141 | + public function load_wp_global_scripts_styles() |
|
| 142 | + { |
|
| 143 | + wp_register_style( |
|
| 144 | + 'espresso_menu', |
|
| 145 | + EE_ADMIN_URL . 'assets/admin-menu-styles.css', |
|
| 146 | + array('dashicons'), |
|
| 147 | + EVENT_ESPRESSO_VERSION |
|
| 148 | + ); |
|
| 149 | + wp_enqueue_style('espresso_menu'); |
|
| 150 | + } |
|
| 151 | + |
|
| 152 | + |
|
| 153 | + /** |
|
| 154 | + * this sets default properties (might be overridden in _set_init_properties); |
|
| 155 | + * |
|
| 156 | + * @access private |
|
| 157 | + * @return void |
|
| 158 | + */ |
|
| 159 | + private function _set_defaults() |
|
| 160 | + { |
|
| 161 | + $this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null; |
|
| 162 | + $this->_routing = true; |
|
| 163 | + $this->_load_page = false; |
|
| 164 | + $this->_files_hooked = $this->_hook_paths = array(); |
|
| 165 | + // menu_map |
|
| 166 | + $this->_menu_map = $this->get_menu_map(); |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + |
|
| 170 | + protected function _set_capability() |
|
| 171 | + { |
|
| 172 | + $capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability; |
|
| 173 | + $this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability); |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * initialize_admin_page |
|
| 179 | + * This method is what executes the loading of the specific page class for the given dir_name as called by the |
|
| 180 | + * EE_Admin_Init class. |
|
| 181 | + * |
|
| 182 | + * @access public |
|
| 183 | + * @uses _initialize_admin_page() |
|
| 184 | + * @param string $dir_name directory name for specific admin_page being loaded. |
|
| 185 | + * @return void |
|
| 186 | + */ |
|
| 187 | + public function initialize_admin_page() |
|
| 188 | + { |
|
| 189 | + // let's check user access first |
|
| 190 | + $this->_check_user_access(); |
|
| 191 | + if (! is_object($this->_loaded_page_object)) { |
|
| 192 | + return; |
|
| 193 | + } |
|
| 194 | + $this->_loaded_page_object->route_admin_request(); |
|
| 195 | + return; |
|
| 196 | + } |
|
| 197 | + |
|
| 198 | + |
|
| 199 | + public function set_page_dependencies($wp_page_slug) |
|
| 200 | + { |
|
| 201 | + if (! $this->_load_page) { |
|
| 202 | + return; |
|
| 203 | + } |
|
| 204 | + if (! is_object($this->_loaded_page_object)) { |
|
| 205 | + $msg[] = __( |
|
| 206 | + 'We can\'t load the page because we\'re missing a valid page object that tells us what to load', |
|
| 207 | + 'event_espresso' |
|
| 208 | + ); |
|
| 209 | + $msg[] = $msg[0] . "\r\n" |
|
| 210 | + . sprintf( |
|
| 211 | + __( |
|
| 212 | + 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory', |
|
| 213 | + 'event_espresso' |
|
| 214 | + ), |
|
| 215 | + $this->_file_name, |
|
| 216 | + $this->_file_name, |
|
| 217 | + $this->_folder_path . $this->_file_name, |
|
| 218 | + $this->_menu_map->menu_slug |
|
| 219 | + ); |
|
| 220 | + throw new EE_Error(implode('||', $msg)); |
|
| 221 | + } |
|
| 222 | + $this->_loaded_page_object->set_wp_page_slug($wp_page_slug); |
|
| 223 | + $page_hook = 'load-' . $wp_page_slug; |
|
| 224 | + // hook into page load hook so all page specific stuff get's loaded. |
|
| 225 | + if (! empty($wp_page_slug)) { |
|
| 226 | + add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies')); |
|
| 227 | + } |
|
| 228 | + } |
|
| 229 | + |
|
| 230 | + |
|
| 231 | + /** |
|
| 232 | + * This executes the intial page loads for EE_Admin pages to take care of any ajax or other code needing to run |
|
| 233 | + * before the load-page... hook. Note, the page loads are happening around the wp_init hook. |
|
| 234 | + * |
|
| 235 | + * @return void |
|
| 236 | + */ |
|
| 237 | + public function do_initial_loads() |
|
| 238 | + { |
|
| 239 | + // no loading or initializing if menu map is setup incorrectly. |
|
| 240 | + if (empty($this->_menu_map) || is_array($this->_menu_map)) { |
|
| 241 | + return; |
|
| 242 | + } |
|
| 243 | + $this->_initialize_admin_page(); |
|
| 244 | + } |
|
| 245 | + |
|
| 246 | + |
|
| 247 | + /** |
|
| 248 | + * all we're doing here is setting the $_file_name property for later use. |
|
| 249 | + * |
|
| 250 | + * @access private |
|
| 251 | + * @return void |
|
| 252 | + */ |
|
| 253 | + private function _set_file_and_folder_name() |
|
| 254 | + { |
|
| 255 | + $bt = debug_backtrace(); |
|
| 256 | + // for more reliable determination of folder name |
|
| 257 | + // we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this). Why? Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins) |
|
| 258 | + $class = get_class($this); |
|
| 259 | + foreach ($bt as $index => $values) { |
|
| 260 | + if (isset($values['class']) && $values['class'] == $class) { |
|
| 261 | + $file_index = $index - 1; |
|
| 262 | + $this->_folder_name = basename(dirname($bt[ $file_index ]['file'])); |
|
| 263 | + if (! empty($this->_folder_name)) { |
|
| 264 | + break; |
|
| 265 | + } |
|
| 266 | + } |
|
| 267 | + } |
|
| 268 | + $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/'; |
|
| 269 | + $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name); |
|
| 270 | + $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name)); |
|
| 271 | + $this->_file_name = str_replace(' ', '_', $this->_file_name); |
|
| 272 | + } |
|
| 273 | + |
|
| 274 | + |
|
| 275 | + /** |
|
| 276 | + * This automatically checks if we have a hook class in the loaded child directory. If we DO then we will register |
|
| 277 | + * it with the appropriate pages. That way all we have to do is make sure the file is named correctly and |
|
| 278 | + * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do: |
|
| 279 | + * events_Messages_Hooks.class.php |
|
| 280 | + * |
|
| 281 | + * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks |
|
| 282 | + * files/classes |
|
| 283 | + * @return array |
|
| 284 | + */ |
|
| 285 | + public function register_hooks($extend = false) |
|
| 286 | + { |
|
| 287 | + |
|
| 288 | + // get a list of files in the directory that have the "Hook" in their name an |
|
| 289 | + // if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property. Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf. |
|
| 290 | + if ($extend) { |
|
| 291 | + $hook_files_glob_path = apply_filters( |
|
| 292 | + 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend', |
|
| 293 | + EE_CORE_CAF_ADMIN_EXTEND |
|
| 294 | + . $this->_folder_name |
|
| 295 | + . '/*' |
|
| 296 | + . $this->_file_name |
|
| 297 | + . '_Hooks_Extend.class.php' |
|
| 298 | + ); |
|
| 299 | + $this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend); |
|
| 300 | + } |
|
| 301 | + // loop through decaf folders |
|
| 302 | + $hook_files_glob_path = apply_filters( |
|
| 303 | + 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path', |
|
| 304 | + $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php' |
|
| 305 | + ); |
|
| 306 | + $this->_hook_paths = array_merge( |
|
| 307 | + $this->_register_hook_files($hook_files_glob_path), |
|
| 308 | + $this->_hook_paths |
|
| 309 | + ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
| 310 | + return $this->_hook_paths; |
|
| 311 | + } |
|
| 312 | + |
|
| 313 | + |
|
| 314 | + protected function _register_hook_files($hook_files_glob_path, $extend = false) |
|
| 315 | + { |
|
| 316 | + $hook_paths = array(); |
|
| 317 | + if ($hook_files = glob($hook_files_glob_path)) { |
|
| 318 | + if (empty($hook_files)) { |
|
| 319 | + return array(); |
|
| 320 | + } |
|
| 321 | + foreach ($hook_files as $file) { |
|
| 322 | + // lets get the linked admin. |
|
| 323 | + $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file) |
|
| 324 | + : str_replace($this->_folder_path, '', $file); |
|
| 325 | + $replace = $extend |
|
| 326 | + ? '_' . $this->_file_name . '_Hooks_Extend.class.php' |
|
| 327 | + : '_' |
|
| 328 | + . $this->_file_name |
|
| 329 | + . '_Hooks.class.php'; |
|
| 330 | + $rel_admin = str_replace($replace, '', $hook_file); |
|
| 331 | + $rel_admin = strtolower($rel_admin); |
|
| 332 | + $hook_paths[] = $file; |
|
| 333 | + // make sure we haven't already got a hook setup for this page path |
|
| 334 | + if (in_array($rel_admin, $this->_files_hooked)) { |
|
| 335 | + continue; |
|
| 336 | + } |
|
| 337 | + $this->hook_file = $hook_file; |
|
| 338 | + $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin; |
|
| 339 | + $filter = add_filter($rel_admin_hook, array($this, 'load_admin_hook')); |
|
| 340 | + $this->_files_hooked[] = $rel_admin; |
|
| 341 | + } |
|
| 342 | + } |
|
| 343 | + return $hook_paths; |
|
| 344 | + } |
|
| 345 | + |
|
| 346 | + |
|
| 347 | + public function load_admin_hook($registered_pages) |
|
| 348 | + { |
|
| 349 | + $this->hook_file; |
|
| 350 | + $hook_file = (array) $this->hook_file; |
|
| 351 | + return array_merge($hook_file, $registered_pages); |
|
| 352 | + } |
|
| 353 | + |
|
| 354 | + |
|
| 355 | + /** |
|
| 356 | + * _initialize_admin_page |
|
| 357 | + * |
|
| 358 | + * @see initialize_admin_page() for info |
|
| 359 | + */ |
|
| 360 | + protected function _initialize_admin_page() |
|
| 361 | + { |
|
| 362 | + |
|
| 363 | + // JUST CHECK WE'RE ON RIGHT PAGE. |
|
| 364 | + if ((! isset($_REQUEST['page']) || $_REQUEST['page'] != $this->_menu_map->menu_slug) && $this->_routing) { |
|
| 365 | + return; |
|
| 366 | + } //not on the right page so let's get out. |
|
| 367 | + $this->_load_page = true; |
|
| 368 | + |
|
| 369 | + // we don't need to do a page_request check here because it's only called via WP menu system. |
|
| 370 | + $admin_page = $this->_file_name . '_Admin_Page'; |
|
| 371 | + $hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page; |
|
| 372 | + $admin_page = apply_filters( |
|
| 373 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}", |
|
| 374 | + $admin_page |
|
| 375 | + ); |
|
| 376 | + // define requested admin page class name then load the file and instantiate |
|
| 377 | + $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php'); |
|
| 378 | + $path_to_file = apply_filters( |
|
| 379 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}", |
|
| 380 | + $path_to_file |
|
| 381 | + );// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
| 382 | + if (is_readable($path_to_file)) { |
|
| 383 | + // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place |
|
| 384 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization'); |
|
| 385 | + do_action( |
|
| 386 | + 'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug |
|
| 387 | + ); |
|
| 388 | + require_once($path_to_file); |
|
| 389 | + $a = new ReflectionClass($admin_page); |
|
| 390 | + $this->_loaded_page_object = $a->newInstance($this->_routing); |
|
| 391 | + } |
|
| 392 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization'); |
|
| 393 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug); |
|
| 394 | + } |
|
| 395 | + |
|
| 396 | + |
|
| 397 | + public function get_admin_page_name() |
|
| 398 | + { |
|
| 399 | + return $this->_file_name . '_Admin_Page'; |
|
| 400 | + } |
|
| 401 | + |
|
| 402 | + |
|
| 403 | + /** |
|
| 404 | + * @return mixed |
|
| 405 | + */ |
|
| 406 | + public function loaded_page_object() |
|
| 407 | + { |
|
| 408 | + return $this->_loaded_page_object; |
|
| 409 | + } |
|
| 410 | + |
|
| 411 | + |
|
| 412 | + // public function set_autoloaders($className) |
|
| 413 | + // { |
|
| 414 | + // $dir_ref = array( |
|
| 415 | + // $this->_folder_path => array('core', 'class'), |
|
| 416 | + // ); |
|
| 417 | + // EEH_Autoloader::try_autoload($dir_ref, $className); |
|
| 418 | + // } |
|
| 419 | + /** |
|
| 420 | + * _check_user_access |
|
| 421 | + * verifies user access for this admin page. If no user access is available then let's gracefully exit with a |
|
| 422 | + * WordPress die message. |
|
| 423 | + * |
|
| 424 | + * @return bool|die true if pass (or admin) wp_die if fail |
|
| 425 | + */ |
|
| 426 | + private function _check_user_access() |
|
| 427 | + { |
|
| 428 | + if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 429 | + $this->_menu_map->capability, |
|
| 430 | + $this->_menu_map->menu_slug |
|
| 431 | + )) { |
|
| 432 | + wp_die(__('You don\'t have access to this page.', 'event_espresso'), '', array('back_link' => true)); |
|
| 433 | + } |
|
| 434 | + return true; |
|
| 435 | + } |
|
| 436 | 436 | } |
@@ -78,7 +78,7 @@ discard block |
||
| 78 | 78 | $this->_set_menu_map(); |
| 79 | 79 | if (empty($this->_menu_map) || is_array($this->_menu_map)) { |
| 80 | 80 | EE_Error::doing_it_wrong( |
| 81 | - get_class($this) . '::$_menu_map', |
|
| 81 | + get_class($this).'::$_menu_map', |
|
| 82 | 82 | sprintf( |
| 83 | 83 | __( |
| 84 | 84 | 'The EE4 addon with the class %s is setting up the _menu_map property incorrectly for this version of EE core. Please see Admin_Page_Init class examples in core for the new way of setting this property up.', |
@@ -142,7 +142,7 @@ discard block |
||
| 142 | 142 | { |
| 143 | 143 | wp_register_style( |
| 144 | 144 | 'espresso_menu', |
| 145 | - EE_ADMIN_URL . 'assets/admin-menu-styles.css', |
|
| 145 | + EE_ADMIN_URL.'assets/admin-menu-styles.css', |
|
| 146 | 146 | array('dashicons'), |
| 147 | 147 | EVENT_ESPRESSO_VERSION |
| 148 | 148 | ); |
@@ -170,7 +170,7 @@ discard block |
||
| 170 | 170 | protected function _set_capability() |
| 171 | 171 | { |
| 172 | 172 | $capability = empty($this->capability) ? $this->_menu_map->capability : $this->capability; |
| 173 | - $this->capability = apply_filters('FHEE_' . $this->_menu_map->menu_slug . '_capability', $capability); |
|
| 173 | + $this->capability = apply_filters('FHEE_'.$this->_menu_map->menu_slug.'_capability', $capability); |
|
| 174 | 174 | } |
| 175 | 175 | |
| 176 | 176 | |
@@ -188,7 +188,7 @@ discard block |
||
| 188 | 188 | { |
| 189 | 189 | // let's check user access first |
| 190 | 190 | $this->_check_user_access(); |
| 191 | - if (! is_object($this->_loaded_page_object)) { |
|
| 191 | + if ( ! is_object($this->_loaded_page_object)) { |
|
| 192 | 192 | return; |
| 193 | 193 | } |
| 194 | 194 | $this->_loaded_page_object->route_admin_request(); |
@@ -198,15 +198,15 @@ discard block |
||
| 198 | 198 | |
| 199 | 199 | public function set_page_dependencies($wp_page_slug) |
| 200 | 200 | { |
| 201 | - if (! $this->_load_page) { |
|
| 201 | + if ( ! $this->_load_page) { |
|
| 202 | 202 | return; |
| 203 | 203 | } |
| 204 | - if (! is_object($this->_loaded_page_object)) { |
|
| 204 | + if ( ! is_object($this->_loaded_page_object)) { |
|
| 205 | 205 | $msg[] = __( |
| 206 | 206 | 'We can\'t load the page because we\'re missing a valid page object that tells us what to load', |
| 207 | 207 | 'event_espresso' |
| 208 | 208 | ); |
| 209 | - $msg[] = $msg[0] . "\r\n" |
|
| 209 | + $msg[] = $msg[0]."\r\n" |
|
| 210 | 210 | . sprintf( |
| 211 | 211 | __( |
| 212 | 212 | 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory', |
@@ -214,15 +214,15 @@ discard block |
||
| 214 | 214 | ), |
| 215 | 215 | $this->_file_name, |
| 216 | 216 | $this->_file_name, |
| 217 | - $this->_folder_path . $this->_file_name, |
|
| 217 | + $this->_folder_path.$this->_file_name, |
|
| 218 | 218 | $this->_menu_map->menu_slug |
| 219 | 219 | ); |
| 220 | 220 | throw new EE_Error(implode('||', $msg)); |
| 221 | 221 | } |
| 222 | 222 | $this->_loaded_page_object->set_wp_page_slug($wp_page_slug); |
| 223 | - $page_hook = 'load-' . $wp_page_slug; |
|
| 223 | + $page_hook = 'load-'.$wp_page_slug; |
|
| 224 | 224 | // hook into page load hook so all page specific stuff get's loaded. |
| 225 | - if (! empty($wp_page_slug)) { |
|
| 225 | + if ( ! empty($wp_page_slug)) { |
|
| 226 | 226 | add_action($page_hook, array($this->_loaded_page_object, 'load_page_dependencies')); |
| 227 | 227 | } |
| 228 | 228 | } |
@@ -259,13 +259,13 @@ discard block |
||
| 259 | 259 | foreach ($bt as $index => $values) { |
| 260 | 260 | if (isset($values['class']) && $values['class'] == $class) { |
| 261 | 261 | $file_index = $index - 1; |
| 262 | - $this->_folder_name = basename(dirname($bt[ $file_index ]['file'])); |
|
| 263 | - if (! empty($this->_folder_name)) { |
|
| 262 | + $this->_folder_name = basename(dirname($bt[$file_index]['file'])); |
|
| 263 | + if ( ! empty($this->_folder_name)) { |
|
| 264 | 264 | break; |
| 265 | 265 | } |
| 266 | 266 | } |
| 267 | 267 | } |
| 268 | - $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/'; |
|
| 268 | + $this->_folder_path = EE_ADMIN_PAGES.$this->_folder_name.'/'; |
|
| 269 | 269 | $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name); |
| 270 | 270 | $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name)); |
| 271 | 271 | $this->_file_name = str_replace(' ', '_', $this->_file_name); |
@@ -301,12 +301,12 @@ discard block |
||
| 301 | 301 | // loop through decaf folders |
| 302 | 302 | $hook_files_glob_path = apply_filters( |
| 303 | 303 | 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path', |
| 304 | - $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php' |
|
| 304 | + $this->_folder_path.'*'.$this->_file_name.'_Hooks.class.php' |
|
| 305 | 305 | ); |
| 306 | 306 | $this->_hook_paths = array_merge( |
| 307 | 307 | $this->_register_hook_files($hook_files_glob_path), |
| 308 | 308 | $this->_hook_paths |
| 309 | - ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
| 309 | + ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
| 310 | 310 | return $this->_hook_paths; |
| 311 | 311 | } |
| 312 | 312 | |
@@ -320,10 +320,10 @@ discard block |
||
| 320 | 320 | } |
| 321 | 321 | foreach ($hook_files as $file) { |
| 322 | 322 | // lets get the linked admin. |
| 323 | - $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file) |
|
| 323 | + $hook_file = $extend ? str_replace(EE_CORE_CAF_ADMIN_EXTEND.$this->_folder_name.'/', '', $file) |
|
| 324 | 324 | : str_replace($this->_folder_path, '', $file); |
| 325 | 325 | $replace = $extend |
| 326 | - ? '_' . $this->_file_name . '_Hooks_Extend.class.php' |
|
| 326 | + ? '_'.$this->_file_name.'_Hooks_Extend.class.php' |
|
| 327 | 327 | : '_' |
| 328 | 328 | . $this->_file_name |
| 329 | 329 | . '_Hooks.class.php'; |
@@ -335,7 +335,7 @@ discard block |
||
| 335 | 335 | continue; |
| 336 | 336 | } |
| 337 | 337 | $this->hook_file = $hook_file; |
| 338 | - $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin; |
|
| 338 | + $rel_admin_hook = 'FHEE_do_other_page_hooks_'.$rel_admin; |
|
| 339 | 339 | $filter = add_filter($rel_admin_hook, array($this, 'load_admin_hook')); |
| 340 | 340 | $this->_files_hooked[] = $rel_admin; |
| 341 | 341 | } |
@@ -361,42 +361,42 @@ discard block |
||
| 361 | 361 | { |
| 362 | 362 | |
| 363 | 363 | // JUST CHECK WE'RE ON RIGHT PAGE. |
| 364 | - if ((! isset($_REQUEST['page']) || $_REQUEST['page'] != $this->_menu_map->menu_slug) && $this->_routing) { |
|
| 364 | + if (( ! isset($_REQUEST['page']) || $_REQUEST['page'] != $this->_menu_map->menu_slug) && $this->_routing) { |
|
| 365 | 365 | return; |
| 366 | 366 | } //not on the right page so let's get out. |
| 367 | 367 | $this->_load_page = true; |
| 368 | 368 | |
| 369 | 369 | // we don't need to do a page_request check here because it's only called via WP menu system. |
| 370 | - $admin_page = $this->_file_name . '_Admin_Page'; |
|
| 371 | - $hook_suffix = $this->_menu_map->menu_slug . '_' . $admin_page; |
|
| 370 | + $admin_page = $this->_file_name.'_Admin_Page'; |
|
| 371 | + $hook_suffix = $this->_menu_map->menu_slug.'_'.$admin_page; |
|
| 372 | 372 | $admin_page = apply_filters( |
| 373 | 373 | "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$hook_suffix}", |
| 374 | 374 | $admin_page |
| 375 | 375 | ); |
| 376 | 376 | // define requested admin page class name then load the file and instantiate |
| 377 | - $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path . $admin_page . '.core.php'); |
|
| 377 | + $path_to_file = str_replace(array('\\', '/'), '/', $this->_folder_path.$admin_page.'.core.php'); |
|
| 378 | 378 | $path_to_file = apply_filters( |
| 379 | 379 | "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$hook_suffix}", |
| 380 | 380 | $path_to_file |
| 381 | - );// so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
| 381 | + ); // so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
| 382 | 382 | if (is_readable($path_to_file)) { |
| 383 | 383 | // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place |
| 384 | 384 | do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization'); |
| 385 | 385 | do_action( |
| 386 | - 'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_' . $this->_menu_map->menu_slug |
|
| 386 | + 'AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_'.$this->_menu_map->menu_slug |
|
| 387 | 387 | ); |
| 388 | 388 | require_once($path_to_file); |
| 389 | 389 | $a = new ReflectionClass($admin_page); |
| 390 | 390 | $this->_loaded_page_object = $a->newInstance($this->_routing); |
| 391 | 391 | } |
| 392 | 392 | do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization'); |
| 393 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_' . $this->_menu_map->menu_slug); |
|
| 393 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_'.$this->_menu_map->menu_slug); |
|
| 394 | 394 | } |
| 395 | 395 | |
| 396 | 396 | |
| 397 | 397 | public function get_admin_page_name() |
| 398 | 398 | { |
| 399 | - return $this->_file_name . '_Admin_Page'; |
|
| 399 | + return $this->_file_name.'_Admin_Page'; |
|
| 400 | 400 | } |
| 401 | 401 | |
| 402 | 402 | |
@@ -425,7 +425,7 @@ discard block |
||
| 425 | 425 | */ |
| 426 | 426 | private function _check_user_access() |
| 427 | 427 | { |
| 428 | - if (! EE_Registry::instance()->CAP->current_user_can( |
|
| 428 | + if ( ! EE_Registry::instance()->CAP->current_user_can( |
|
| 429 | 429 | $this->_menu_map->capability, |
| 430 | 430 | $this->_menu_map->menu_slug |
| 431 | 431 | )) { |
@@ -13,722 +13,722 @@ |
||
| 13 | 13 | { |
| 14 | 14 | |
| 15 | 15 | |
| 16 | - /** |
|
| 17 | - * we're just going to use this to hold the name of the caller class (child class name) |
|
| 18 | - * |
|
| 19 | - * @var string |
|
| 20 | - */ |
|
| 21 | - public $caller; |
|
| 22 | - |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * this is just a flag set automatically to indicate whether we've got an extended hook class running (i.e. |
|
| 26 | - * espresso_events_Registration_Form_Hooks_Extend extends espresso_events_Registration_Form_Hooks). This flag is |
|
| 27 | - * used later to make sure we require the needed files. |
|
| 28 | - * |
|
| 29 | - * @var bool |
|
| 30 | - */ |
|
| 31 | - protected $_extend; |
|
| 32 | - |
|
| 33 | - |
|
| 34 | - /** |
|
| 35 | - * child classes MUST set this property so that the page object can be loaded correctly |
|
| 36 | - * |
|
| 37 | - * @var string |
|
| 38 | - */ |
|
| 39 | - protected $_name; |
|
| 40 | - |
|
| 41 | - |
|
| 42 | - /** |
|
| 43 | - * This is set by child classes and is an associative array of ajax hooks in the format: |
|
| 44 | - * array( |
|
| 45 | - * 'ajax_action_ref' => 'executing_method'; //must be public |
|
| 46 | - * ) |
|
| 47 | - * |
|
| 48 | - * @var array |
|
| 49 | - */ |
|
| 50 | - protected $_ajax_func; |
|
| 51 | - |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * This is an array of methods that get executed on a page routes admin_init hook. Use the following format: |
|
| 55 | - * array( |
|
| 56 | - * 'page_route' => 'executing_method' //must be public |
|
| 57 | - * ) |
|
| 58 | - * |
|
| 59 | - * @var array |
|
| 60 | - */ |
|
| 61 | - protected $_init_func; |
|
| 62 | - |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * This is an array of methods that output metabox content for the given page route. Use the following format: |
|
| 66 | - * array( |
|
| 67 | - * 0 => array( |
|
| 68 | - * 'page_route' => 'string_for_page_route', //must correspond to a page route in the class being connected |
|
| 69 | - * with (i.e. "edit_event") If this is in an array then the same params below will be used but the metabox |
|
| 70 | - * will be added to each route. |
|
| 71 | - * 'func' => 'executing_method', //must be public (i.e. public function executing_method($post, |
|
| 72 | - * $callback_args){} ). Note if you include callback args in the array then you need to declare them in the |
|
| 73 | - * method arguments. |
|
| 74 | - * 'id' => 'identifier_for_metabox', //so it can be removed by addons (optional, class will set it |
|
| 75 | - * automatically) |
|
| 76 | - * 'priority' => 'default', //default 'default' (optional) |
|
| 77 | - * 'label' => __('Localized Title', 'event_espresso'), |
|
| 78 | - * 'context' => 'advanced' //advanced is default (optional), |
|
| 79 | - * 'callback_args' => array() //any callback args to include (optional) |
|
| 80 | - * ) |
|
| 81 | - * Why are we indexing numerically? Because it's possible there may be more than one metabox per page_route. |
|
| 82 | - * |
|
| 83 | - * @var array |
|
| 84 | - */ |
|
| 85 | - protected $_metaboxes; |
|
| 86 | - |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * This is an array of values that indicate any metaboxes we want removed from a given page route. Usually this is |
|
| 90 | - * used when caffeinated functionality is replacing decaffeinated functionality. Use the following format for the |
|
| 91 | - * array: array( |
|
| 92 | - * 0 => array( |
|
| 93 | - * 'page_route' => 'string_for_page_route' //can be string or array of strings that match a page_route(s) |
|
| 94 | - * that are in the class being connected with (i.e. 'edit', or 'create_new'). |
|
| 95 | - * 'id' => 'identifier_for_metabox', //what the id is of the metabox being removed |
|
| 96 | - * 'context' => 'normal', //the context for the metabox being removed (has to match) |
|
| 97 | - * 'screen' => 'screen_id', //(optional), if not included then this class will attempt to remove the metabox |
|
| 98 | - * using the currently loaded screen object->id however, there may be cases where you have to specify the |
|
| 99 | - * id for the screen the metabox is on. |
|
| 100 | - * ) |
|
| 101 | - * ) |
|
| 102 | - * |
|
| 103 | - * @var array |
|
| 104 | - */ |
|
| 105 | - protected $_remove_metaboxes; |
|
| 106 | - |
|
| 107 | - |
|
| 108 | - /** |
|
| 109 | - * This parent class takes care of loading the scripts and styles if the child class has set the properties for |
|
| 110 | - * them in the following format. Note, the first array index ('register') is for defining all the registers. The |
|
| 111 | - * second array index is for indicating what routes each script/style loads on. array( |
|
| 112 | - * 'registers' => array( |
|
| 113 | - * 'script_ref' => array( // if more than one script is to be loaded its best to use the 'dependency' |
|
| 114 | - * argument to link scripts together. |
|
| 115 | - * 'type' => 'js' // 'js' or 'css' (defaults to js). This tells us what type of wp_function to use |
|
| 116 | - * 'url' => 'http://urltoscript.css.js', |
|
| 117 | - * 'depends' => array('jquery'), //an array of dependencies for the scripts. REMEMBER, if a script has |
|
| 118 | - * already been registered elsewhere in the system. You can just use the depends array to make sure it |
|
| 119 | - * gets loaded before the one you are setting here. |
|
| 120 | - * 'footer' => TRUE //defaults to true (styles don't use this parameter) |
|
| 121 | - * ), |
|
| 122 | - * 'enqueues' => array( //this time each key corresponds to the script ref followed by an array of page routes |
|
| 123 | - * the script gets enqueued on. |
|
| 124 | - * 'script_ref' => array('route_one', 'route_two') |
|
| 125 | - * ), |
|
| 126 | - * 'localize' => array( //this allows you to set a localize object. Indicate which script the object is being |
|
| 127 | - * attached to and then include an array indexed by the name of the object and the array of key/value pairs for |
|
| 128 | - * the object. |
|
| 129 | - * 'scrip_ref' => array( |
|
| 130 | - * 'NAME_OF_JS_OBJECT' => array( |
|
| 131 | - * 'translate_ref' => __('localized_string', 'event_espresso'), |
|
| 132 | - * 'some_data' => 5 |
|
| 133 | - * ) |
|
| 134 | - * ) |
|
| 135 | - * ) |
|
| 136 | - * ) |
|
| 137 | - * |
|
| 138 | - * @var array |
|
| 139 | - */ |
|
| 140 | - protected $_scripts_styles; |
|
| 141 | - |
|
| 142 | - |
|
| 143 | - /** |
|
| 144 | - * This is a property that will contain the current route. |
|
| 145 | - * |
|
| 146 | - * @var string; |
|
| 147 | - */ |
|
| 148 | - protected $_current_route; |
|
| 149 | - |
|
| 150 | - |
|
| 151 | - /** |
|
| 152 | - * this optional property can be set by child classes to override the priority for the automatic action/filter hook |
|
| 153 | - * loading in the `_load_routed_hooks()` method. Please follow this format: array( |
|
| 154 | - * 'wp_hook_reference' => 1 |
|
| 155 | - * ) |
|
| 156 | - * ) |
|
| 157 | - * |
|
| 158 | - * @var array |
|
| 159 | - */ |
|
| 160 | - protected $_wp_action_filters_priority; |
|
| 161 | - |
|
| 162 | - |
|
| 163 | - /** |
|
| 164 | - * This just holds a merged array of the $_POST and $_GET vars in favor of $_POST |
|
| 165 | - * |
|
| 166 | - * @var array |
|
| 167 | - */ |
|
| 168 | - protected $_req_data; |
|
| 169 | - |
|
| 170 | - |
|
| 171 | - /** |
|
| 172 | - * This just holds an instance of the page object for this hook |
|
| 173 | - * |
|
| 174 | - * @var EE_Admin_Page |
|
| 175 | - */ |
|
| 176 | - protected $_page_object; |
|
| 177 | - |
|
| 178 | - |
|
| 179 | - /** |
|
| 180 | - * This holds the EE_Admin_Page object from the calling admin page that this object hooks into. |
|
| 181 | - * |
|
| 182 | - * @var EE_Admin_Page|EE_Admin_Page_CPT |
|
| 183 | - */ |
|
| 184 | - protected $_adminpage_obj; |
|
| 185 | - |
|
| 186 | - |
|
| 187 | - /** |
|
| 188 | - * Holds EE_Registry object |
|
| 189 | - * |
|
| 190 | - * @var EE_Registry |
|
| 191 | - */ |
|
| 192 | - protected $EE = null; |
|
| 193 | - |
|
| 194 | - |
|
| 195 | - /** |
|
| 196 | - * constructor |
|
| 197 | - * |
|
| 198 | - * @param EE_Admin_Page $admin_page the calling admin_page_object |
|
| 199 | - */ |
|
| 200 | - public function __construct(EE_Admin_Page $adminpage) |
|
| 201 | - { |
|
| 202 | - |
|
| 203 | - $this->_adminpage_obj = $adminpage; |
|
| 204 | - $this->_req_data = array_merge($_GET, $_POST); |
|
| 205 | - $this->_set_defaults(); |
|
| 206 | - $this->_set_hooks_properties(); |
|
| 207 | - // first let's verify we're on the right page |
|
| 208 | - if (! isset($this->_req_data['page']) |
|
| 209 | - || (isset($this->_req_data['page']) |
|
| 210 | - && $this->_adminpage_obj->page_slug |
|
| 211 | - != $this->_req_data['page'])) { |
|
| 212 | - return; |
|
| 213 | - } //get out nothing more to be done here. |
|
| 214 | - // allow for extends to modify properties |
|
| 215 | - if (method_exists($this, '_extend_properties')) { |
|
| 216 | - $this->_extend_properties(); |
|
| 217 | - } |
|
| 218 | - $this->_set_page_object(); |
|
| 219 | - $this->_init_hooks(); |
|
| 220 | - $this->_load_custom_methods(); |
|
| 221 | - $this->_load_routed_hooks(); |
|
| 222 | - add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts_styles')); |
|
| 223 | - add_action('admin_enqueue_scripts', array($this, 'add_metaboxes'), 20); |
|
| 224 | - add_action('admin_enqueue_scripts', array($this, 'remove_metaboxes'), 15); |
|
| 225 | - $this->_ajax_hooks(); |
|
| 226 | - } |
|
| 227 | - |
|
| 228 | - |
|
| 229 | - /** |
|
| 230 | - * used by child classes to set the following properties: |
|
| 231 | - * $_ajax_func (optional) |
|
| 232 | - * $_init_func (optional) |
|
| 233 | - * $_metaboxes (optional) |
|
| 234 | - * $_scripts (optional) |
|
| 235 | - * $_styles (optional) |
|
| 236 | - * $_name (required) |
|
| 237 | - * Also in this method will be registered any scripts or styles loaded on the targeted page (as indicated in the |
|
| 238 | - * _scripts/_styles properties) Also children should place in this method any filters/actions that have to happen |
|
| 239 | - * really early on page load (just after admin_init) if they want to have them registered for handling early. |
|
| 240 | - * |
|
| 241 | - * @access protected |
|
| 242 | - * @abstract |
|
| 243 | - * @return void |
|
| 244 | - */ |
|
| 245 | - abstract protected function _set_hooks_properties(); |
|
| 246 | - |
|
| 247 | - |
|
| 248 | - /** |
|
| 249 | - * The hooks for enqueue_scripts and enqueue_styles will be run in here. Child classes need to define their |
|
| 250 | - * scripts and styles in the relevant $_scripts and $_styles properties. Child classes must have also already |
|
| 251 | - * registered the scripts and styles using wp_register_script and wp_register_style functions. |
|
| 252 | - * |
|
| 253 | - * @access public |
|
| 254 | - * @return void |
|
| 255 | - */ |
|
| 256 | - public function enqueue_scripts_styles() |
|
| 257 | - { |
|
| 258 | - |
|
| 259 | - if (! empty($this->_scripts_styles)) { |
|
| 260 | - // first let's do all the registrations |
|
| 261 | - if (! isset($this->_scripts_styles['registers'])) { |
|
| 262 | - $msg[] = __( |
|
| 263 | - 'There is no "registers" index in the <code>$this->_scripts_styles</code> property.', |
|
| 264 | - 'event_espresso' |
|
| 265 | - ); |
|
| 266 | - $msg[] = sprintf( |
|
| 267 | - __( |
|
| 268 | - 'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child', |
|
| 269 | - 'event_espresso' |
|
| 270 | - ), |
|
| 271 | - '<strong>' . $this->caller . '</strong>' |
|
| 272 | - ); |
|
| 273 | - throw new EE_Error(implode('||', $msg)); |
|
| 274 | - } |
|
| 275 | - foreach ($this->_scripts_styles['registers'] as $ref => $details) { |
|
| 276 | - $defaults = array( |
|
| 277 | - 'type' => 'js', |
|
| 278 | - 'url' => '', |
|
| 279 | - 'depends' => array(), |
|
| 280 | - 'version' => EVENT_ESPRESSO_VERSION, |
|
| 281 | - 'footer' => true, |
|
| 282 | - ); |
|
| 283 | - $details = wp_parse_args($details, $defaults); |
|
| 284 | - extract($details); |
|
| 285 | - // let's make sure that we set the 'registers' type if it's not set! We need it later to determine whhich enqueu we do |
|
| 286 | - $this->_scripts_styles['registers'][ $ref ]['type'] = $type; |
|
| 287 | - // let's make sure we're not missing any REQUIRED parameters |
|
| 288 | - if (empty($url)) { |
|
| 289 | - $msg[] = sprintf( |
|
| 290 | - __('Missing the url for the requested %s', 'event_espresso'), |
|
| 291 | - $type == 'js' ? 'script' : 'stylesheet' |
|
| 292 | - ); |
|
| 293 | - $msg[] = sprintf( |
|
| 294 | - __( |
|
| 295 | - 'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref', |
|
| 296 | - 'event_espresso' |
|
| 297 | - ), |
|
| 298 | - '<strong>' . $this->caller . '</strong>', |
|
| 299 | - $ref |
|
| 300 | - ); |
|
| 301 | - throw new EE_Error(implode('||', $msg)); |
|
| 302 | - } |
|
| 303 | - // made it here so let's do the appropriate registration |
|
| 304 | - $type == 'js' |
|
| 305 | - ? wp_register_script($ref, $url, $depends, $version, $footer) |
|
| 306 | - : wp_register_style( |
|
| 307 | - $ref, |
|
| 308 | - $url, |
|
| 309 | - $depends, |
|
| 310 | - $version |
|
| 311 | - ); |
|
| 312 | - } |
|
| 313 | - // k now lets do the enqueues |
|
| 314 | - if (! isset($this->_scripts_styles['enqueues'])) { |
|
| 315 | - return; |
|
| 316 | - } //not sure if we should throw an error here or not. |
|
| 317 | - |
|
| 318 | - foreach ($this->_scripts_styles['enqueues'] as $ref => $routes) { |
|
| 319 | - // make sure $routes is an array |
|
| 320 | - $routes = (array) $routes; |
|
| 321 | - if (in_array($this->_current_route, $routes)) { |
|
| 322 | - $this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref) |
|
| 323 | - : wp_enqueue_style($ref); |
|
| 324 | - // if we have a localization for the script let's do that too. |
|
| 325 | - if (isset($this->_scripts_styles['localize'][ $ref ])) { |
|
| 326 | - foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) { |
|
| 327 | - wp_localize_script( |
|
| 328 | - $ref, |
|
| 329 | - $object_name, |
|
| 330 | - $this->_scripts_styles['localize'][ $ref ][ $object_name ] |
|
| 331 | - ); |
|
| 332 | - } |
|
| 333 | - } |
|
| 334 | - } |
|
| 335 | - } |
|
| 336 | - // let's do the deregisters |
|
| 337 | - if (! isset($this->_scripts_styles['deregisters'])) { |
|
| 338 | - return; |
|
| 339 | - } |
|
| 340 | - foreach ($this->_scripts_styles['deregisters'] as $ref => $details) { |
|
| 341 | - $defaults = array( |
|
| 342 | - 'type' => 'js', |
|
| 343 | - ); |
|
| 344 | - $details = wp_parse_args($details, $defaults); |
|
| 345 | - extract($details); |
|
| 346 | - $type == 'js' ? wp_deregister_script($ref) : wp_deregister_style($ref); |
|
| 347 | - } |
|
| 348 | - } |
|
| 349 | - } |
|
| 350 | - |
|
| 351 | - |
|
| 352 | - /** |
|
| 353 | - * just set the defaults for the hooks properties. |
|
| 354 | - * |
|
| 355 | - * @access private |
|
| 356 | - * @return void |
|
| 357 | - */ |
|
| 358 | - private function _set_defaults() |
|
| 359 | - { |
|
| 360 | - $this->_ajax_func = $this->_init_func = $this->_metaboxes = $this->_scripts = $this->_styles = $this->_wp_action_filters_priority = array(); |
|
| 361 | - $this->_current_route = $this->getCurrentRoute(); |
|
| 362 | - $this->caller = get_class($this); |
|
| 363 | - $this->_extend = stripos($this->caller, 'Extend') ? true : false; |
|
| 364 | - } |
|
| 365 | - |
|
| 366 | - |
|
| 367 | - /** |
|
| 368 | - * A helper for determining the current route. |
|
| 369 | - * @return string |
|
| 370 | - */ |
|
| 371 | - private function getCurrentRoute() |
|
| 372 | - { |
|
| 373 | - // list tables do something else with 'action' for bulk actions. |
|
| 374 | - $action = ! empty($_REQUEST['action']) && $_REQUEST['action'] !== '-1' ? $_REQUEST['action'] : 'default'; |
|
| 375 | - // we set a 'route' variable in some cases where action is being used by something else. |
|
| 376 | - $action = $action === 'default' && isset($_REQUEST['route']) ? $_REQUEST['route'] : $action; |
|
| 377 | - return sanitize_key($action); |
|
| 378 | - } |
|
| 379 | - |
|
| 380 | - |
|
| 381 | - /** |
|
| 382 | - * this sets the _page_object property |
|
| 383 | - * |
|
| 384 | - * @access protected |
|
| 385 | - * @return void |
|
| 386 | - */ |
|
| 387 | - protected function _set_page_object() |
|
| 388 | - { |
|
| 389 | - // first make sure $this->_name is set |
|
| 390 | - if (empty($this->_name)) { |
|
| 391 | - $msg[] = __('We can\'t load the page object', 'event_espresso'); |
|
| 392 | - $msg[] = sprintf( |
|
| 393 | - __("This is because the %s child class has not set the '_name' property", 'event_espresso'), |
|
| 394 | - $this->caller |
|
| 395 | - ); |
|
| 396 | - throw new EE_Error(implode('||', $msg)); |
|
| 397 | - } |
|
| 398 | - $ref = str_replace('_', ' ', $this->_name); // take the_message -> the message |
|
| 399 | - $ref = str_replace(' ', '_', ucwords($ref)) . '_Admin_Page'; // take the message -> The_Message |
|
| 400 | - // first default file (if exists) |
|
| 401 | - $decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $ref . '.core.php'; |
|
| 402 | - if (is_readable($decaf_file)) { |
|
| 403 | - require_once($decaf_file); |
|
| 404 | - } |
|
| 405 | - // now we have to do require for extended file (if needed) |
|
| 406 | - if ($this->_extend) { |
|
| 407 | - require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $ref . '.core.php'); |
|
| 408 | - } |
|
| 409 | - // if we've got an extended class we use that! |
|
| 410 | - $ref = $this->_extend ? 'Extend_' . $ref : $ref; |
|
| 411 | - // let's make sure the class exists |
|
| 412 | - if (! class_exists($ref)) { |
|
| 413 | - $msg[] = __('We can\'t load the page object', 'event_espresso'); |
|
| 414 | - $msg[] = sprintf( |
|
| 415 | - __( |
|
| 416 | - 'The class name that was given is %s. Check the spelling and make sure its correct, also there needs to be an autoloader setup for the class', |
|
| 417 | - 'event_espresso' |
|
| 418 | - ), |
|
| 419 | - $ref |
|
| 420 | - ); |
|
| 421 | - throw new EE_Error(implode('||', $msg)); |
|
| 422 | - } |
|
| 423 | - $a = new ReflectionClass($ref); |
|
| 424 | - $this->_page_object = $a->newInstance(false); |
|
| 425 | - } |
|
| 426 | - |
|
| 427 | - |
|
| 428 | - /** |
|
| 429 | - * Child "hook" classes can declare any methods that they want executed when a specific page route is loaded. The |
|
| 430 | - * advantage of this is when doing things like running our own db interactions on saves etc. Remember that |
|
| 431 | - * $this->_req_data (all the _POST and _GET data) is available to your methods. |
|
| 432 | - * |
|
| 433 | - * @access private |
|
| 434 | - * @return void |
|
| 435 | - */ |
|
| 436 | - private function _load_custom_methods() |
|
| 437 | - { |
|
| 438 | - /** |
|
| 439 | - * method cannot be named 'default' (@see http://us3.php |
|
| 440 | - * .net/manual/en/reserved.keywords.php) so need to |
|
| 441 | - * handle routes that are "default" |
|
| 442 | - * |
|
| 443 | - * @since 4.3.0 |
|
| 444 | - */ |
|
| 445 | - $method_callback = $this->_current_route == 'default' ? 'default_callback' : $this->_current_route; |
|
| 446 | - // these run before the Admin_Page route executes. |
|
| 447 | - if (method_exists($this, $method_callback)) { |
|
| 448 | - call_user_func(array($this, $method_callback)); |
|
| 449 | - } |
|
| 450 | - // these run via the _redirect_after_action method in EE_Admin_Page which usually happens after non_UI methods in EE_Admin_Page classes. There are two redirect actions, the first fires before $query_args might be manipulated by "save and close" actions and the seond fires right before the actual redirect happens. |
|
| 451 | - // first the actions |
|
| 452 | - // note that these action hooks will have the $query_args value available. |
|
| 453 | - $admin_class_name = get_class($this->_adminpage_obj); |
|
| 454 | - if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) { |
|
| 455 | - add_action( |
|
| 456 | - 'AHEE__' |
|
| 457 | - . $admin_class_name |
|
| 458 | - . '___redirect_after_action__before_redirect_modification_' |
|
| 459 | - . $this->_current_route, |
|
| 460 | - array($this, '_redirect_action_early_' . $this->_current_route), |
|
| 461 | - 10 |
|
| 462 | - ); |
|
| 463 | - } |
|
| 464 | - if (method_exists($this, '_redirect_action_' . $this->_current_route)) { |
|
| 465 | - add_action( |
|
| 466 | - 'AHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 467 | - array($this, '_redirect_action_' . $this->_current_route), |
|
| 468 | - 10 |
|
| 469 | - ); |
|
| 470 | - } |
|
| 471 | - // let's hook into the _redirect itself and allow for changing where the user goes after redirect. This will have $query_args and $redirect_url available. |
|
| 472 | - if (method_exists($this, '_redirect_filter_' . $this->_current_route)) { |
|
| 473 | - add_filter( |
|
| 474 | - 'FHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 475 | - array($this, '_redirect_filter_' . $this->_current_route), |
|
| 476 | - 10, |
|
| 477 | - 2 |
|
| 478 | - ); |
|
| 479 | - } |
|
| 480 | - } |
|
| 481 | - |
|
| 482 | - |
|
| 483 | - /** |
|
| 484 | - * This method will search for a corresponding method with a name matching the route and the wp_hook to run. This |
|
| 485 | - * allows child hook classes to target hooking into a specific wp action or filter hook ONLY on a certain route. |
|
| 486 | - * just remember, methods MUST be public Future hooks should be added in here to be access by child classes. |
|
| 487 | - * |
|
| 488 | - * @return void |
|
| 489 | - */ |
|
| 490 | - private function _load_routed_hooks() |
|
| 491 | - { |
|
| 492 | - |
|
| 493 | - // this array provides the hook action names that will be referenced. Key is the action. Value is an array with the type (action or filter) and the number of parameters for the hook. We'll default all priorities for automatic hooks to 10. |
|
| 494 | - $hook_filter_array = array( |
|
| 495 | - 'admin_footer' => array( |
|
| 496 | - 'type' => 'action', |
|
| 497 | - 'argnum' => 1, |
|
| 498 | - 'priority' => 10, |
|
| 499 | - ), |
|
| 500 | - 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => array( |
|
| 501 | - 'type' => 'filter', |
|
| 502 | - 'argnum' => 1, |
|
| 503 | - 'priority' => 10, |
|
| 504 | - ), |
|
| 505 | - 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug => array( |
|
| 506 | - 'type' => 'filter', |
|
| 507 | - 'argnum' => 1, |
|
| 508 | - 'priority' => 10, |
|
| 509 | - ), |
|
| 510 | - 'FHEE_list_table_views' => array( |
|
| 511 | - 'type' => 'filter', |
|
| 512 | - 'argnum' => 1, |
|
| 513 | - 'priority' => 10, |
|
| 514 | - ), |
|
| 515 | - 'AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes' => array( |
|
| 516 | - 'type' => 'action', |
|
| 517 | - 'argnum' => 1, |
|
| 518 | - 'priority' => 10, |
|
| 519 | - ), |
|
| 520 | - ); |
|
| 521 | - foreach ($hook_filter_array as $hook => $args) { |
|
| 522 | - if (method_exists($this, $this->_current_route . '_' . $hook)) { |
|
| 523 | - if (isset($this->_wp_action_filters_priority[ $hook ])) { |
|
| 524 | - $args['priority'] = $this->_wp_action_filters_priority[ $hook ]; |
|
| 525 | - } |
|
| 526 | - if ($args['type'] == 'action') { |
|
| 527 | - add_action( |
|
| 528 | - $hook, |
|
| 529 | - array($this, $this->_current_route . '_' . $hook), |
|
| 530 | - $args['priority'], |
|
| 531 | - $args['argnum'] |
|
| 532 | - ); |
|
| 533 | - } else { |
|
| 534 | - add_filter( |
|
| 535 | - $hook, |
|
| 536 | - array($this, $this->_current_route . '_' . $hook), |
|
| 537 | - $args['priority'], |
|
| 538 | - $args['argnum'] |
|
| 539 | - ); |
|
| 540 | - } |
|
| 541 | - } |
|
| 542 | - } |
|
| 543 | - } |
|
| 544 | - |
|
| 545 | - |
|
| 546 | - /** |
|
| 547 | - * Loop throught the $_ajax_func array and add_actions for the array. |
|
| 548 | - * |
|
| 549 | - * @return void |
|
| 550 | - */ |
|
| 551 | - private function _ajax_hooks() |
|
| 552 | - { |
|
| 553 | - |
|
| 554 | - if (empty($this->_ajax_func)) { |
|
| 555 | - return; |
|
| 556 | - } //get out there's nothing to take care of. |
|
| 557 | - foreach ($this->_ajax_func as $action => $method) { |
|
| 558 | - // make sure method exists |
|
| 559 | - if (! method_exists($this, $method)) { |
|
| 560 | - $msg[] = __( |
|
| 561 | - 'There is no corresponding method for the hook labeled in the _ajax_func array', |
|
| 562 | - 'event_espresso' |
|
| 563 | - ) . '<br />'; |
|
| 564 | - $msg[] = sprintf( |
|
| 565 | - __( |
|
| 566 | - 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 567 | - 'event_espresso' |
|
| 568 | - ), |
|
| 569 | - $method, |
|
| 570 | - $this->caller |
|
| 571 | - ); |
|
| 572 | - throw new EE_Error(implode('||', $msg)); |
|
| 573 | - } |
|
| 574 | - add_action('wp_ajax_' . $action, array($this, $method)); |
|
| 575 | - } |
|
| 576 | - } |
|
| 577 | - |
|
| 578 | - |
|
| 579 | - /** |
|
| 580 | - * Loop throught the $_init_func array and add_actions for the array. |
|
| 581 | - * |
|
| 582 | - * @return void |
|
| 583 | - */ |
|
| 584 | - protected function _init_hooks() |
|
| 585 | - { |
|
| 586 | - if (empty($this->_init_func)) { |
|
| 587 | - return; |
|
| 588 | - } //get out there's nothing to take care of. |
|
| 589 | - // We need to determine what page_route we are on! |
|
| 590 | - $current_route = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'default'; |
|
| 591 | - foreach ($this->_init_func as $route => $method) { |
|
| 592 | - // make sure method exists |
|
| 593 | - if (! method_exists($this, $method)) { |
|
| 594 | - $msg[] = __( |
|
| 595 | - 'There is no corresponding method for the hook labeled in the _init_func array', |
|
| 596 | - 'event_espresso' |
|
| 597 | - ) . '<br />'; |
|
| 598 | - $msg[] = sprintf( |
|
| 599 | - __( |
|
| 600 | - 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 601 | - 'event_espresso' |
|
| 602 | - ), |
|
| 603 | - $method, |
|
| 604 | - $this->caller |
|
| 605 | - ); |
|
| 606 | - throw new EE_Error(implode('||', $msg)); |
|
| 607 | - } |
|
| 608 | - if ($route == $this->_current_route) { |
|
| 609 | - add_action('admin_init', array($this, $method)); |
|
| 610 | - } |
|
| 611 | - } |
|
| 612 | - } |
|
| 613 | - |
|
| 614 | - |
|
| 615 | - /** |
|
| 616 | - * Loop through the _metaboxes property and add_metaboxes accordingly |
|
| 617 | - * //todo we could eventually make this a config component class (i.e. new EE_Metabox); |
|
| 618 | - * |
|
| 619 | - * @access public |
|
| 620 | - * @return void |
|
| 621 | - */ |
|
| 622 | - public function add_metaboxes() |
|
| 623 | - { |
|
| 624 | - if (empty($this->_metaboxes)) { |
|
| 625 | - return; |
|
| 626 | - } //get out we don't have any metaboxes to set for this connection |
|
| 627 | - $this->_handle_metabox_array($this->_metaboxes); |
|
| 628 | - } |
|
| 629 | - |
|
| 630 | - |
|
| 631 | - private function _handle_metabox_array($boxes, $add = true) |
|
| 632 | - { |
|
| 633 | - |
|
| 634 | - foreach ($boxes as $box) { |
|
| 635 | - if (! isset($box['page_route'])) { |
|
| 636 | - continue; |
|
| 637 | - } //we dont' have a valid array |
|
| 638 | - // let's make sure $box['page_route'] is an array so the "foreach" will work. |
|
| 639 | - $box['page_route'] = (array) $box['page_route']; |
|
| 640 | - foreach ($box['page_route'] as $route) { |
|
| 641 | - if ($route != $this->_current_route) { |
|
| 642 | - continue; |
|
| 643 | - } //get out we only add metaboxes for set route. |
|
| 644 | - if ($add) { |
|
| 645 | - $this->_add_metabox($box); |
|
| 646 | - } else { |
|
| 647 | - $this->_remove_metabox($box); |
|
| 648 | - } |
|
| 649 | - } |
|
| 650 | - } |
|
| 651 | - } |
|
| 652 | - |
|
| 653 | - |
|
| 654 | - /** |
|
| 655 | - * Loop through the _remove_metaboxes property and remove metaboxes accordingly. |
|
| 656 | - * |
|
| 657 | - * @access public |
|
| 658 | - * @return void |
|
| 659 | - */ |
|
| 660 | - public function remove_metaboxes() |
|
| 661 | - { |
|
| 662 | - |
|
| 663 | - if (empty($this->_remove_metaboxes)) { |
|
| 664 | - return; |
|
| 665 | - } //get out there are no metaboxes to remove |
|
| 666 | - $this->_handle_metabox_array($this->_remove_metaboxes, false); |
|
| 667 | - } |
|
| 668 | - |
|
| 669 | - |
|
| 670 | - /** |
|
| 671 | - * This just handles adding a metabox |
|
| 672 | - * |
|
| 673 | - * @access private |
|
| 674 | - * @param array $args an array of args that have been set for this metabox by the child class |
|
| 675 | - */ |
|
| 676 | - private function _add_metabox($args) |
|
| 677 | - { |
|
| 678 | - $current_screen = get_current_screen(); |
|
| 679 | - $screen_id = is_object($current_screen) ? $current_screen->id : null; |
|
| 680 | - $func = isset($args['func']) ? $args['func'] : 'some_invalid_callback'; |
|
| 681 | - // set defaults |
|
| 682 | - $defaults = array( |
|
| 683 | - 'func' => $func, |
|
| 684 | - 'id' => $this->caller . '_' . $func . '_metabox', |
|
| 685 | - 'priority' => 'default', |
|
| 686 | - 'label' => $this->caller, |
|
| 687 | - 'context' => 'advanced', |
|
| 688 | - 'callback_args' => array(), |
|
| 689 | - 'page' => isset($args['page']) ? $args['page'] : $screen_id, |
|
| 690 | - ); |
|
| 691 | - $args = wp_parse_args($args, $defaults); |
|
| 692 | - extract($args); |
|
| 693 | - // make sure method exists |
|
| 694 | - if (! method_exists($this, $func)) { |
|
| 695 | - $msg[] = __('There is no corresponding method to display the metabox content', 'event_espresso') . '<br />'; |
|
| 696 | - $msg[] = sprintf( |
|
| 697 | - __( |
|
| 698 | - 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 699 | - 'event_espresso' |
|
| 700 | - ), |
|
| 701 | - $func, |
|
| 702 | - $this->caller |
|
| 703 | - ); |
|
| 704 | - throw new EE_Error(implode('||', $msg)); |
|
| 705 | - } |
|
| 706 | - // everything checks out so lets add the metabox |
|
| 707 | - add_meta_box($id, $label, array($this, $func), $page, $context, $priority, $callback_args); |
|
| 708 | - } |
|
| 709 | - |
|
| 710 | - |
|
| 711 | - private function _remove_metabox($args) |
|
| 712 | - { |
|
| 713 | - $current_screen = get_current_screen(); |
|
| 714 | - $screen_id = is_object($current_screen) ? $current_screen->id : null; |
|
| 715 | - $func = isset($args['func']) ? $args['func'] : 'some_invalid_callback'; |
|
| 716 | - // set defaults |
|
| 717 | - $defaults = array( |
|
| 718 | - 'id' => isset($args['id']) |
|
| 719 | - ? $args['id'] |
|
| 720 | - : $this->_current_route |
|
| 721 | - . '_' |
|
| 722 | - . $this->caller |
|
| 723 | - . '_' |
|
| 724 | - . $func |
|
| 725 | - . '_metabox', |
|
| 726 | - 'context' => 'default', |
|
| 727 | - 'screen' => isset($args['screen']) ? $args['screen'] : $screen_id, |
|
| 728 | - ); |
|
| 729 | - $args = wp_parse_args($args, $defaults); |
|
| 730 | - extract($args); |
|
| 731 | - // everything checks out so lets remove the box! |
|
| 732 | - remove_meta_box($id, $screen, $context); |
|
| 733 | - } |
|
| 16 | + /** |
|
| 17 | + * we're just going to use this to hold the name of the caller class (child class name) |
|
| 18 | + * |
|
| 19 | + * @var string |
|
| 20 | + */ |
|
| 21 | + public $caller; |
|
| 22 | + |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * this is just a flag set automatically to indicate whether we've got an extended hook class running (i.e. |
|
| 26 | + * espresso_events_Registration_Form_Hooks_Extend extends espresso_events_Registration_Form_Hooks). This flag is |
|
| 27 | + * used later to make sure we require the needed files. |
|
| 28 | + * |
|
| 29 | + * @var bool |
|
| 30 | + */ |
|
| 31 | + protected $_extend; |
|
| 32 | + |
|
| 33 | + |
|
| 34 | + /** |
|
| 35 | + * child classes MUST set this property so that the page object can be loaded correctly |
|
| 36 | + * |
|
| 37 | + * @var string |
|
| 38 | + */ |
|
| 39 | + protected $_name; |
|
| 40 | + |
|
| 41 | + |
|
| 42 | + /** |
|
| 43 | + * This is set by child classes and is an associative array of ajax hooks in the format: |
|
| 44 | + * array( |
|
| 45 | + * 'ajax_action_ref' => 'executing_method'; //must be public |
|
| 46 | + * ) |
|
| 47 | + * |
|
| 48 | + * @var array |
|
| 49 | + */ |
|
| 50 | + protected $_ajax_func; |
|
| 51 | + |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * This is an array of methods that get executed on a page routes admin_init hook. Use the following format: |
|
| 55 | + * array( |
|
| 56 | + * 'page_route' => 'executing_method' //must be public |
|
| 57 | + * ) |
|
| 58 | + * |
|
| 59 | + * @var array |
|
| 60 | + */ |
|
| 61 | + protected $_init_func; |
|
| 62 | + |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * This is an array of methods that output metabox content for the given page route. Use the following format: |
|
| 66 | + * array( |
|
| 67 | + * 0 => array( |
|
| 68 | + * 'page_route' => 'string_for_page_route', //must correspond to a page route in the class being connected |
|
| 69 | + * with (i.e. "edit_event") If this is in an array then the same params below will be used but the metabox |
|
| 70 | + * will be added to each route. |
|
| 71 | + * 'func' => 'executing_method', //must be public (i.e. public function executing_method($post, |
|
| 72 | + * $callback_args){} ). Note if you include callback args in the array then you need to declare them in the |
|
| 73 | + * method arguments. |
|
| 74 | + * 'id' => 'identifier_for_metabox', //so it can be removed by addons (optional, class will set it |
|
| 75 | + * automatically) |
|
| 76 | + * 'priority' => 'default', //default 'default' (optional) |
|
| 77 | + * 'label' => __('Localized Title', 'event_espresso'), |
|
| 78 | + * 'context' => 'advanced' //advanced is default (optional), |
|
| 79 | + * 'callback_args' => array() //any callback args to include (optional) |
|
| 80 | + * ) |
|
| 81 | + * Why are we indexing numerically? Because it's possible there may be more than one metabox per page_route. |
|
| 82 | + * |
|
| 83 | + * @var array |
|
| 84 | + */ |
|
| 85 | + protected $_metaboxes; |
|
| 86 | + |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * This is an array of values that indicate any metaboxes we want removed from a given page route. Usually this is |
|
| 90 | + * used when caffeinated functionality is replacing decaffeinated functionality. Use the following format for the |
|
| 91 | + * array: array( |
|
| 92 | + * 0 => array( |
|
| 93 | + * 'page_route' => 'string_for_page_route' //can be string or array of strings that match a page_route(s) |
|
| 94 | + * that are in the class being connected with (i.e. 'edit', or 'create_new'). |
|
| 95 | + * 'id' => 'identifier_for_metabox', //what the id is of the metabox being removed |
|
| 96 | + * 'context' => 'normal', //the context for the metabox being removed (has to match) |
|
| 97 | + * 'screen' => 'screen_id', //(optional), if not included then this class will attempt to remove the metabox |
|
| 98 | + * using the currently loaded screen object->id however, there may be cases where you have to specify the |
|
| 99 | + * id for the screen the metabox is on. |
|
| 100 | + * ) |
|
| 101 | + * ) |
|
| 102 | + * |
|
| 103 | + * @var array |
|
| 104 | + */ |
|
| 105 | + protected $_remove_metaboxes; |
|
| 106 | + |
|
| 107 | + |
|
| 108 | + /** |
|
| 109 | + * This parent class takes care of loading the scripts and styles if the child class has set the properties for |
|
| 110 | + * them in the following format. Note, the first array index ('register') is for defining all the registers. The |
|
| 111 | + * second array index is for indicating what routes each script/style loads on. array( |
|
| 112 | + * 'registers' => array( |
|
| 113 | + * 'script_ref' => array( // if more than one script is to be loaded its best to use the 'dependency' |
|
| 114 | + * argument to link scripts together. |
|
| 115 | + * 'type' => 'js' // 'js' or 'css' (defaults to js). This tells us what type of wp_function to use |
|
| 116 | + * 'url' => 'http://urltoscript.css.js', |
|
| 117 | + * 'depends' => array('jquery'), //an array of dependencies for the scripts. REMEMBER, if a script has |
|
| 118 | + * already been registered elsewhere in the system. You can just use the depends array to make sure it |
|
| 119 | + * gets loaded before the one you are setting here. |
|
| 120 | + * 'footer' => TRUE //defaults to true (styles don't use this parameter) |
|
| 121 | + * ), |
|
| 122 | + * 'enqueues' => array( //this time each key corresponds to the script ref followed by an array of page routes |
|
| 123 | + * the script gets enqueued on. |
|
| 124 | + * 'script_ref' => array('route_one', 'route_two') |
|
| 125 | + * ), |
|
| 126 | + * 'localize' => array( //this allows you to set a localize object. Indicate which script the object is being |
|
| 127 | + * attached to and then include an array indexed by the name of the object and the array of key/value pairs for |
|
| 128 | + * the object. |
|
| 129 | + * 'scrip_ref' => array( |
|
| 130 | + * 'NAME_OF_JS_OBJECT' => array( |
|
| 131 | + * 'translate_ref' => __('localized_string', 'event_espresso'), |
|
| 132 | + * 'some_data' => 5 |
|
| 133 | + * ) |
|
| 134 | + * ) |
|
| 135 | + * ) |
|
| 136 | + * ) |
|
| 137 | + * |
|
| 138 | + * @var array |
|
| 139 | + */ |
|
| 140 | + protected $_scripts_styles; |
|
| 141 | + |
|
| 142 | + |
|
| 143 | + /** |
|
| 144 | + * This is a property that will contain the current route. |
|
| 145 | + * |
|
| 146 | + * @var string; |
|
| 147 | + */ |
|
| 148 | + protected $_current_route; |
|
| 149 | + |
|
| 150 | + |
|
| 151 | + /** |
|
| 152 | + * this optional property can be set by child classes to override the priority for the automatic action/filter hook |
|
| 153 | + * loading in the `_load_routed_hooks()` method. Please follow this format: array( |
|
| 154 | + * 'wp_hook_reference' => 1 |
|
| 155 | + * ) |
|
| 156 | + * ) |
|
| 157 | + * |
|
| 158 | + * @var array |
|
| 159 | + */ |
|
| 160 | + protected $_wp_action_filters_priority; |
|
| 161 | + |
|
| 162 | + |
|
| 163 | + /** |
|
| 164 | + * This just holds a merged array of the $_POST and $_GET vars in favor of $_POST |
|
| 165 | + * |
|
| 166 | + * @var array |
|
| 167 | + */ |
|
| 168 | + protected $_req_data; |
|
| 169 | + |
|
| 170 | + |
|
| 171 | + /** |
|
| 172 | + * This just holds an instance of the page object for this hook |
|
| 173 | + * |
|
| 174 | + * @var EE_Admin_Page |
|
| 175 | + */ |
|
| 176 | + protected $_page_object; |
|
| 177 | + |
|
| 178 | + |
|
| 179 | + /** |
|
| 180 | + * This holds the EE_Admin_Page object from the calling admin page that this object hooks into. |
|
| 181 | + * |
|
| 182 | + * @var EE_Admin_Page|EE_Admin_Page_CPT |
|
| 183 | + */ |
|
| 184 | + protected $_adminpage_obj; |
|
| 185 | + |
|
| 186 | + |
|
| 187 | + /** |
|
| 188 | + * Holds EE_Registry object |
|
| 189 | + * |
|
| 190 | + * @var EE_Registry |
|
| 191 | + */ |
|
| 192 | + protected $EE = null; |
|
| 193 | + |
|
| 194 | + |
|
| 195 | + /** |
|
| 196 | + * constructor |
|
| 197 | + * |
|
| 198 | + * @param EE_Admin_Page $admin_page the calling admin_page_object |
|
| 199 | + */ |
|
| 200 | + public function __construct(EE_Admin_Page $adminpage) |
|
| 201 | + { |
|
| 202 | + |
|
| 203 | + $this->_adminpage_obj = $adminpage; |
|
| 204 | + $this->_req_data = array_merge($_GET, $_POST); |
|
| 205 | + $this->_set_defaults(); |
|
| 206 | + $this->_set_hooks_properties(); |
|
| 207 | + // first let's verify we're on the right page |
|
| 208 | + if (! isset($this->_req_data['page']) |
|
| 209 | + || (isset($this->_req_data['page']) |
|
| 210 | + && $this->_adminpage_obj->page_slug |
|
| 211 | + != $this->_req_data['page'])) { |
|
| 212 | + return; |
|
| 213 | + } //get out nothing more to be done here. |
|
| 214 | + // allow for extends to modify properties |
|
| 215 | + if (method_exists($this, '_extend_properties')) { |
|
| 216 | + $this->_extend_properties(); |
|
| 217 | + } |
|
| 218 | + $this->_set_page_object(); |
|
| 219 | + $this->_init_hooks(); |
|
| 220 | + $this->_load_custom_methods(); |
|
| 221 | + $this->_load_routed_hooks(); |
|
| 222 | + add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts_styles')); |
|
| 223 | + add_action('admin_enqueue_scripts', array($this, 'add_metaboxes'), 20); |
|
| 224 | + add_action('admin_enqueue_scripts', array($this, 'remove_metaboxes'), 15); |
|
| 225 | + $this->_ajax_hooks(); |
|
| 226 | + } |
|
| 227 | + |
|
| 228 | + |
|
| 229 | + /** |
|
| 230 | + * used by child classes to set the following properties: |
|
| 231 | + * $_ajax_func (optional) |
|
| 232 | + * $_init_func (optional) |
|
| 233 | + * $_metaboxes (optional) |
|
| 234 | + * $_scripts (optional) |
|
| 235 | + * $_styles (optional) |
|
| 236 | + * $_name (required) |
|
| 237 | + * Also in this method will be registered any scripts or styles loaded on the targeted page (as indicated in the |
|
| 238 | + * _scripts/_styles properties) Also children should place in this method any filters/actions that have to happen |
|
| 239 | + * really early on page load (just after admin_init) if they want to have them registered for handling early. |
|
| 240 | + * |
|
| 241 | + * @access protected |
|
| 242 | + * @abstract |
|
| 243 | + * @return void |
|
| 244 | + */ |
|
| 245 | + abstract protected function _set_hooks_properties(); |
|
| 246 | + |
|
| 247 | + |
|
| 248 | + /** |
|
| 249 | + * The hooks for enqueue_scripts and enqueue_styles will be run in here. Child classes need to define their |
|
| 250 | + * scripts and styles in the relevant $_scripts and $_styles properties. Child classes must have also already |
|
| 251 | + * registered the scripts and styles using wp_register_script and wp_register_style functions. |
|
| 252 | + * |
|
| 253 | + * @access public |
|
| 254 | + * @return void |
|
| 255 | + */ |
|
| 256 | + public function enqueue_scripts_styles() |
|
| 257 | + { |
|
| 258 | + |
|
| 259 | + if (! empty($this->_scripts_styles)) { |
|
| 260 | + // first let's do all the registrations |
|
| 261 | + if (! isset($this->_scripts_styles['registers'])) { |
|
| 262 | + $msg[] = __( |
|
| 263 | + 'There is no "registers" index in the <code>$this->_scripts_styles</code> property.', |
|
| 264 | + 'event_espresso' |
|
| 265 | + ); |
|
| 266 | + $msg[] = sprintf( |
|
| 267 | + __( |
|
| 268 | + 'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child', |
|
| 269 | + 'event_espresso' |
|
| 270 | + ), |
|
| 271 | + '<strong>' . $this->caller . '</strong>' |
|
| 272 | + ); |
|
| 273 | + throw new EE_Error(implode('||', $msg)); |
|
| 274 | + } |
|
| 275 | + foreach ($this->_scripts_styles['registers'] as $ref => $details) { |
|
| 276 | + $defaults = array( |
|
| 277 | + 'type' => 'js', |
|
| 278 | + 'url' => '', |
|
| 279 | + 'depends' => array(), |
|
| 280 | + 'version' => EVENT_ESPRESSO_VERSION, |
|
| 281 | + 'footer' => true, |
|
| 282 | + ); |
|
| 283 | + $details = wp_parse_args($details, $defaults); |
|
| 284 | + extract($details); |
|
| 285 | + // let's make sure that we set the 'registers' type if it's not set! We need it later to determine whhich enqueu we do |
|
| 286 | + $this->_scripts_styles['registers'][ $ref ]['type'] = $type; |
|
| 287 | + // let's make sure we're not missing any REQUIRED parameters |
|
| 288 | + if (empty($url)) { |
|
| 289 | + $msg[] = sprintf( |
|
| 290 | + __('Missing the url for the requested %s', 'event_espresso'), |
|
| 291 | + $type == 'js' ? 'script' : 'stylesheet' |
|
| 292 | + ); |
|
| 293 | + $msg[] = sprintf( |
|
| 294 | + __( |
|
| 295 | + 'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref', |
|
| 296 | + 'event_espresso' |
|
| 297 | + ), |
|
| 298 | + '<strong>' . $this->caller . '</strong>', |
|
| 299 | + $ref |
|
| 300 | + ); |
|
| 301 | + throw new EE_Error(implode('||', $msg)); |
|
| 302 | + } |
|
| 303 | + // made it here so let's do the appropriate registration |
|
| 304 | + $type == 'js' |
|
| 305 | + ? wp_register_script($ref, $url, $depends, $version, $footer) |
|
| 306 | + : wp_register_style( |
|
| 307 | + $ref, |
|
| 308 | + $url, |
|
| 309 | + $depends, |
|
| 310 | + $version |
|
| 311 | + ); |
|
| 312 | + } |
|
| 313 | + // k now lets do the enqueues |
|
| 314 | + if (! isset($this->_scripts_styles['enqueues'])) { |
|
| 315 | + return; |
|
| 316 | + } //not sure if we should throw an error here or not. |
|
| 317 | + |
|
| 318 | + foreach ($this->_scripts_styles['enqueues'] as $ref => $routes) { |
|
| 319 | + // make sure $routes is an array |
|
| 320 | + $routes = (array) $routes; |
|
| 321 | + if (in_array($this->_current_route, $routes)) { |
|
| 322 | + $this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref) |
|
| 323 | + : wp_enqueue_style($ref); |
|
| 324 | + // if we have a localization for the script let's do that too. |
|
| 325 | + if (isset($this->_scripts_styles['localize'][ $ref ])) { |
|
| 326 | + foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) { |
|
| 327 | + wp_localize_script( |
|
| 328 | + $ref, |
|
| 329 | + $object_name, |
|
| 330 | + $this->_scripts_styles['localize'][ $ref ][ $object_name ] |
|
| 331 | + ); |
|
| 332 | + } |
|
| 333 | + } |
|
| 334 | + } |
|
| 335 | + } |
|
| 336 | + // let's do the deregisters |
|
| 337 | + if (! isset($this->_scripts_styles['deregisters'])) { |
|
| 338 | + return; |
|
| 339 | + } |
|
| 340 | + foreach ($this->_scripts_styles['deregisters'] as $ref => $details) { |
|
| 341 | + $defaults = array( |
|
| 342 | + 'type' => 'js', |
|
| 343 | + ); |
|
| 344 | + $details = wp_parse_args($details, $defaults); |
|
| 345 | + extract($details); |
|
| 346 | + $type == 'js' ? wp_deregister_script($ref) : wp_deregister_style($ref); |
|
| 347 | + } |
|
| 348 | + } |
|
| 349 | + } |
|
| 350 | + |
|
| 351 | + |
|
| 352 | + /** |
|
| 353 | + * just set the defaults for the hooks properties. |
|
| 354 | + * |
|
| 355 | + * @access private |
|
| 356 | + * @return void |
|
| 357 | + */ |
|
| 358 | + private function _set_defaults() |
|
| 359 | + { |
|
| 360 | + $this->_ajax_func = $this->_init_func = $this->_metaboxes = $this->_scripts = $this->_styles = $this->_wp_action_filters_priority = array(); |
|
| 361 | + $this->_current_route = $this->getCurrentRoute(); |
|
| 362 | + $this->caller = get_class($this); |
|
| 363 | + $this->_extend = stripos($this->caller, 'Extend') ? true : false; |
|
| 364 | + } |
|
| 365 | + |
|
| 366 | + |
|
| 367 | + /** |
|
| 368 | + * A helper for determining the current route. |
|
| 369 | + * @return string |
|
| 370 | + */ |
|
| 371 | + private function getCurrentRoute() |
|
| 372 | + { |
|
| 373 | + // list tables do something else with 'action' for bulk actions. |
|
| 374 | + $action = ! empty($_REQUEST['action']) && $_REQUEST['action'] !== '-1' ? $_REQUEST['action'] : 'default'; |
|
| 375 | + // we set a 'route' variable in some cases where action is being used by something else. |
|
| 376 | + $action = $action === 'default' && isset($_REQUEST['route']) ? $_REQUEST['route'] : $action; |
|
| 377 | + return sanitize_key($action); |
|
| 378 | + } |
|
| 379 | + |
|
| 380 | + |
|
| 381 | + /** |
|
| 382 | + * this sets the _page_object property |
|
| 383 | + * |
|
| 384 | + * @access protected |
|
| 385 | + * @return void |
|
| 386 | + */ |
|
| 387 | + protected function _set_page_object() |
|
| 388 | + { |
|
| 389 | + // first make sure $this->_name is set |
|
| 390 | + if (empty($this->_name)) { |
|
| 391 | + $msg[] = __('We can\'t load the page object', 'event_espresso'); |
|
| 392 | + $msg[] = sprintf( |
|
| 393 | + __("This is because the %s child class has not set the '_name' property", 'event_espresso'), |
|
| 394 | + $this->caller |
|
| 395 | + ); |
|
| 396 | + throw new EE_Error(implode('||', $msg)); |
|
| 397 | + } |
|
| 398 | + $ref = str_replace('_', ' ', $this->_name); // take the_message -> the message |
|
| 399 | + $ref = str_replace(' ', '_', ucwords($ref)) . '_Admin_Page'; // take the message -> The_Message |
|
| 400 | + // first default file (if exists) |
|
| 401 | + $decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $ref . '.core.php'; |
|
| 402 | + if (is_readable($decaf_file)) { |
|
| 403 | + require_once($decaf_file); |
|
| 404 | + } |
|
| 405 | + // now we have to do require for extended file (if needed) |
|
| 406 | + if ($this->_extend) { |
|
| 407 | + require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $ref . '.core.php'); |
|
| 408 | + } |
|
| 409 | + // if we've got an extended class we use that! |
|
| 410 | + $ref = $this->_extend ? 'Extend_' . $ref : $ref; |
|
| 411 | + // let's make sure the class exists |
|
| 412 | + if (! class_exists($ref)) { |
|
| 413 | + $msg[] = __('We can\'t load the page object', 'event_espresso'); |
|
| 414 | + $msg[] = sprintf( |
|
| 415 | + __( |
|
| 416 | + 'The class name that was given is %s. Check the spelling and make sure its correct, also there needs to be an autoloader setup for the class', |
|
| 417 | + 'event_espresso' |
|
| 418 | + ), |
|
| 419 | + $ref |
|
| 420 | + ); |
|
| 421 | + throw new EE_Error(implode('||', $msg)); |
|
| 422 | + } |
|
| 423 | + $a = new ReflectionClass($ref); |
|
| 424 | + $this->_page_object = $a->newInstance(false); |
|
| 425 | + } |
|
| 426 | + |
|
| 427 | + |
|
| 428 | + /** |
|
| 429 | + * Child "hook" classes can declare any methods that they want executed when a specific page route is loaded. The |
|
| 430 | + * advantage of this is when doing things like running our own db interactions on saves etc. Remember that |
|
| 431 | + * $this->_req_data (all the _POST and _GET data) is available to your methods. |
|
| 432 | + * |
|
| 433 | + * @access private |
|
| 434 | + * @return void |
|
| 435 | + */ |
|
| 436 | + private function _load_custom_methods() |
|
| 437 | + { |
|
| 438 | + /** |
|
| 439 | + * method cannot be named 'default' (@see http://us3.php |
|
| 440 | + * .net/manual/en/reserved.keywords.php) so need to |
|
| 441 | + * handle routes that are "default" |
|
| 442 | + * |
|
| 443 | + * @since 4.3.0 |
|
| 444 | + */ |
|
| 445 | + $method_callback = $this->_current_route == 'default' ? 'default_callback' : $this->_current_route; |
|
| 446 | + // these run before the Admin_Page route executes. |
|
| 447 | + if (method_exists($this, $method_callback)) { |
|
| 448 | + call_user_func(array($this, $method_callback)); |
|
| 449 | + } |
|
| 450 | + // these run via the _redirect_after_action method in EE_Admin_Page which usually happens after non_UI methods in EE_Admin_Page classes. There are two redirect actions, the first fires before $query_args might be manipulated by "save and close" actions and the seond fires right before the actual redirect happens. |
|
| 451 | + // first the actions |
|
| 452 | + // note that these action hooks will have the $query_args value available. |
|
| 453 | + $admin_class_name = get_class($this->_adminpage_obj); |
|
| 454 | + if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) { |
|
| 455 | + add_action( |
|
| 456 | + 'AHEE__' |
|
| 457 | + . $admin_class_name |
|
| 458 | + . '___redirect_after_action__before_redirect_modification_' |
|
| 459 | + . $this->_current_route, |
|
| 460 | + array($this, '_redirect_action_early_' . $this->_current_route), |
|
| 461 | + 10 |
|
| 462 | + ); |
|
| 463 | + } |
|
| 464 | + if (method_exists($this, '_redirect_action_' . $this->_current_route)) { |
|
| 465 | + add_action( |
|
| 466 | + 'AHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 467 | + array($this, '_redirect_action_' . $this->_current_route), |
|
| 468 | + 10 |
|
| 469 | + ); |
|
| 470 | + } |
|
| 471 | + // let's hook into the _redirect itself and allow for changing where the user goes after redirect. This will have $query_args and $redirect_url available. |
|
| 472 | + if (method_exists($this, '_redirect_filter_' . $this->_current_route)) { |
|
| 473 | + add_filter( |
|
| 474 | + 'FHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 475 | + array($this, '_redirect_filter_' . $this->_current_route), |
|
| 476 | + 10, |
|
| 477 | + 2 |
|
| 478 | + ); |
|
| 479 | + } |
|
| 480 | + } |
|
| 481 | + |
|
| 482 | + |
|
| 483 | + /** |
|
| 484 | + * This method will search for a corresponding method with a name matching the route and the wp_hook to run. This |
|
| 485 | + * allows child hook classes to target hooking into a specific wp action or filter hook ONLY on a certain route. |
|
| 486 | + * just remember, methods MUST be public Future hooks should be added in here to be access by child classes. |
|
| 487 | + * |
|
| 488 | + * @return void |
|
| 489 | + */ |
|
| 490 | + private function _load_routed_hooks() |
|
| 491 | + { |
|
| 492 | + |
|
| 493 | + // this array provides the hook action names that will be referenced. Key is the action. Value is an array with the type (action or filter) and the number of parameters for the hook. We'll default all priorities for automatic hooks to 10. |
|
| 494 | + $hook_filter_array = array( |
|
| 495 | + 'admin_footer' => array( |
|
| 496 | + 'type' => 'action', |
|
| 497 | + 'argnum' => 1, |
|
| 498 | + 'priority' => 10, |
|
| 499 | + ), |
|
| 500 | + 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => array( |
|
| 501 | + 'type' => 'filter', |
|
| 502 | + 'argnum' => 1, |
|
| 503 | + 'priority' => 10, |
|
| 504 | + ), |
|
| 505 | + 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug => array( |
|
| 506 | + 'type' => 'filter', |
|
| 507 | + 'argnum' => 1, |
|
| 508 | + 'priority' => 10, |
|
| 509 | + ), |
|
| 510 | + 'FHEE_list_table_views' => array( |
|
| 511 | + 'type' => 'filter', |
|
| 512 | + 'argnum' => 1, |
|
| 513 | + 'priority' => 10, |
|
| 514 | + ), |
|
| 515 | + 'AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes' => array( |
|
| 516 | + 'type' => 'action', |
|
| 517 | + 'argnum' => 1, |
|
| 518 | + 'priority' => 10, |
|
| 519 | + ), |
|
| 520 | + ); |
|
| 521 | + foreach ($hook_filter_array as $hook => $args) { |
|
| 522 | + if (method_exists($this, $this->_current_route . '_' . $hook)) { |
|
| 523 | + if (isset($this->_wp_action_filters_priority[ $hook ])) { |
|
| 524 | + $args['priority'] = $this->_wp_action_filters_priority[ $hook ]; |
|
| 525 | + } |
|
| 526 | + if ($args['type'] == 'action') { |
|
| 527 | + add_action( |
|
| 528 | + $hook, |
|
| 529 | + array($this, $this->_current_route . '_' . $hook), |
|
| 530 | + $args['priority'], |
|
| 531 | + $args['argnum'] |
|
| 532 | + ); |
|
| 533 | + } else { |
|
| 534 | + add_filter( |
|
| 535 | + $hook, |
|
| 536 | + array($this, $this->_current_route . '_' . $hook), |
|
| 537 | + $args['priority'], |
|
| 538 | + $args['argnum'] |
|
| 539 | + ); |
|
| 540 | + } |
|
| 541 | + } |
|
| 542 | + } |
|
| 543 | + } |
|
| 544 | + |
|
| 545 | + |
|
| 546 | + /** |
|
| 547 | + * Loop throught the $_ajax_func array and add_actions for the array. |
|
| 548 | + * |
|
| 549 | + * @return void |
|
| 550 | + */ |
|
| 551 | + private function _ajax_hooks() |
|
| 552 | + { |
|
| 553 | + |
|
| 554 | + if (empty($this->_ajax_func)) { |
|
| 555 | + return; |
|
| 556 | + } //get out there's nothing to take care of. |
|
| 557 | + foreach ($this->_ajax_func as $action => $method) { |
|
| 558 | + // make sure method exists |
|
| 559 | + if (! method_exists($this, $method)) { |
|
| 560 | + $msg[] = __( |
|
| 561 | + 'There is no corresponding method for the hook labeled in the _ajax_func array', |
|
| 562 | + 'event_espresso' |
|
| 563 | + ) . '<br />'; |
|
| 564 | + $msg[] = sprintf( |
|
| 565 | + __( |
|
| 566 | + 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 567 | + 'event_espresso' |
|
| 568 | + ), |
|
| 569 | + $method, |
|
| 570 | + $this->caller |
|
| 571 | + ); |
|
| 572 | + throw new EE_Error(implode('||', $msg)); |
|
| 573 | + } |
|
| 574 | + add_action('wp_ajax_' . $action, array($this, $method)); |
|
| 575 | + } |
|
| 576 | + } |
|
| 577 | + |
|
| 578 | + |
|
| 579 | + /** |
|
| 580 | + * Loop throught the $_init_func array and add_actions for the array. |
|
| 581 | + * |
|
| 582 | + * @return void |
|
| 583 | + */ |
|
| 584 | + protected function _init_hooks() |
|
| 585 | + { |
|
| 586 | + if (empty($this->_init_func)) { |
|
| 587 | + return; |
|
| 588 | + } //get out there's nothing to take care of. |
|
| 589 | + // We need to determine what page_route we are on! |
|
| 590 | + $current_route = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'default'; |
|
| 591 | + foreach ($this->_init_func as $route => $method) { |
|
| 592 | + // make sure method exists |
|
| 593 | + if (! method_exists($this, $method)) { |
|
| 594 | + $msg[] = __( |
|
| 595 | + 'There is no corresponding method for the hook labeled in the _init_func array', |
|
| 596 | + 'event_espresso' |
|
| 597 | + ) . '<br />'; |
|
| 598 | + $msg[] = sprintf( |
|
| 599 | + __( |
|
| 600 | + 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 601 | + 'event_espresso' |
|
| 602 | + ), |
|
| 603 | + $method, |
|
| 604 | + $this->caller |
|
| 605 | + ); |
|
| 606 | + throw new EE_Error(implode('||', $msg)); |
|
| 607 | + } |
|
| 608 | + if ($route == $this->_current_route) { |
|
| 609 | + add_action('admin_init', array($this, $method)); |
|
| 610 | + } |
|
| 611 | + } |
|
| 612 | + } |
|
| 613 | + |
|
| 614 | + |
|
| 615 | + /** |
|
| 616 | + * Loop through the _metaboxes property and add_metaboxes accordingly |
|
| 617 | + * //todo we could eventually make this a config component class (i.e. new EE_Metabox); |
|
| 618 | + * |
|
| 619 | + * @access public |
|
| 620 | + * @return void |
|
| 621 | + */ |
|
| 622 | + public function add_metaboxes() |
|
| 623 | + { |
|
| 624 | + if (empty($this->_metaboxes)) { |
|
| 625 | + return; |
|
| 626 | + } //get out we don't have any metaboxes to set for this connection |
|
| 627 | + $this->_handle_metabox_array($this->_metaboxes); |
|
| 628 | + } |
|
| 629 | + |
|
| 630 | + |
|
| 631 | + private function _handle_metabox_array($boxes, $add = true) |
|
| 632 | + { |
|
| 633 | + |
|
| 634 | + foreach ($boxes as $box) { |
|
| 635 | + if (! isset($box['page_route'])) { |
|
| 636 | + continue; |
|
| 637 | + } //we dont' have a valid array |
|
| 638 | + // let's make sure $box['page_route'] is an array so the "foreach" will work. |
|
| 639 | + $box['page_route'] = (array) $box['page_route']; |
|
| 640 | + foreach ($box['page_route'] as $route) { |
|
| 641 | + if ($route != $this->_current_route) { |
|
| 642 | + continue; |
|
| 643 | + } //get out we only add metaboxes for set route. |
|
| 644 | + if ($add) { |
|
| 645 | + $this->_add_metabox($box); |
|
| 646 | + } else { |
|
| 647 | + $this->_remove_metabox($box); |
|
| 648 | + } |
|
| 649 | + } |
|
| 650 | + } |
|
| 651 | + } |
|
| 652 | + |
|
| 653 | + |
|
| 654 | + /** |
|
| 655 | + * Loop through the _remove_metaboxes property and remove metaboxes accordingly. |
|
| 656 | + * |
|
| 657 | + * @access public |
|
| 658 | + * @return void |
|
| 659 | + */ |
|
| 660 | + public function remove_metaboxes() |
|
| 661 | + { |
|
| 662 | + |
|
| 663 | + if (empty($this->_remove_metaboxes)) { |
|
| 664 | + return; |
|
| 665 | + } //get out there are no metaboxes to remove |
|
| 666 | + $this->_handle_metabox_array($this->_remove_metaboxes, false); |
|
| 667 | + } |
|
| 668 | + |
|
| 669 | + |
|
| 670 | + /** |
|
| 671 | + * This just handles adding a metabox |
|
| 672 | + * |
|
| 673 | + * @access private |
|
| 674 | + * @param array $args an array of args that have been set for this metabox by the child class |
|
| 675 | + */ |
|
| 676 | + private function _add_metabox($args) |
|
| 677 | + { |
|
| 678 | + $current_screen = get_current_screen(); |
|
| 679 | + $screen_id = is_object($current_screen) ? $current_screen->id : null; |
|
| 680 | + $func = isset($args['func']) ? $args['func'] : 'some_invalid_callback'; |
|
| 681 | + // set defaults |
|
| 682 | + $defaults = array( |
|
| 683 | + 'func' => $func, |
|
| 684 | + 'id' => $this->caller . '_' . $func . '_metabox', |
|
| 685 | + 'priority' => 'default', |
|
| 686 | + 'label' => $this->caller, |
|
| 687 | + 'context' => 'advanced', |
|
| 688 | + 'callback_args' => array(), |
|
| 689 | + 'page' => isset($args['page']) ? $args['page'] : $screen_id, |
|
| 690 | + ); |
|
| 691 | + $args = wp_parse_args($args, $defaults); |
|
| 692 | + extract($args); |
|
| 693 | + // make sure method exists |
|
| 694 | + if (! method_exists($this, $func)) { |
|
| 695 | + $msg[] = __('There is no corresponding method to display the metabox content', 'event_espresso') . '<br />'; |
|
| 696 | + $msg[] = sprintf( |
|
| 697 | + __( |
|
| 698 | + 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
|
| 699 | + 'event_espresso' |
|
| 700 | + ), |
|
| 701 | + $func, |
|
| 702 | + $this->caller |
|
| 703 | + ); |
|
| 704 | + throw new EE_Error(implode('||', $msg)); |
|
| 705 | + } |
|
| 706 | + // everything checks out so lets add the metabox |
|
| 707 | + add_meta_box($id, $label, array($this, $func), $page, $context, $priority, $callback_args); |
|
| 708 | + } |
|
| 709 | + |
|
| 710 | + |
|
| 711 | + private function _remove_metabox($args) |
|
| 712 | + { |
|
| 713 | + $current_screen = get_current_screen(); |
|
| 714 | + $screen_id = is_object($current_screen) ? $current_screen->id : null; |
|
| 715 | + $func = isset($args['func']) ? $args['func'] : 'some_invalid_callback'; |
|
| 716 | + // set defaults |
|
| 717 | + $defaults = array( |
|
| 718 | + 'id' => isset($args['id']) |
|
| 719 | + ? $args['id'] |
|
| 720 | + : $this->_current_route |
|
| 721 | + . '_' |
|
| 722 | + . $this->caller |
|
| 723 | + . '_' |
|
| 724 | + . $func |
|
| 725 | + . '_metabox', |
|
| 726 | + 'context' => 'default', |
|
| 727 | + 'screen' => isset($args['screen']) ? $args['screen'] : $screen_id, |
|
| 728 | + ); |
|
| 729 | + $args = wp_parse_args($args, $defaults); |
|
| 730 | + extract($args); |
|
| 731 | + // everything checks out so lets remove the box! |
|
| 732 | + remove_meta_box($id, $screen, $context); |
|
| 733 | + } |
|
| 734 | 734 | } |
@@ -205,7 +205,7 @@ discard block |
||
| 205 | 205 | $this->_set_defaults(); |
| 206 | 206 | $this->_set_hooks_properties(); |
| 207 | 207 | // first let's verify we're on the right page |
| 208 | - if (! isset($this->_req_data['page']) |
|
| 208 | + if ( ! isset($this->_req_data['page']) |
|
| 209 | 209 | || (isset($this->_req_data['page']) |
| 210 | 210 | && $this->_adminpage_obj->page_slug |
| 211 | 211 | != $this->_req_data['page'])) { |
@@ -256,9 +256,9 @@ discard block |
||
| 256 | 256 | public function enqueue_scripts_styles() |
| 257 | 257 | { |
| 258 | 258 | |
| 259 | - if (! empty($this->_scripts_styles)) { |
|
| 259 | + if ( ! empty($this->_scripts_styles)) { |
|
| 260 | 260 | // first let's do all the registrations |
| 261 | - if (! isset($this->_scripts_styles['registers'])) { |
|
| 261 | + if ( ! isset($this->_scripts_styles['registers'])) { |
|
| 262 | 262 | $msg[] = __( |
| 263 | 263 | 'There is no "registers" index in the <code>$this->_scripts_styles</code> property.', |
| 264 | 264 | 'event_espresso' |
@@ -268,7 +268,7 @@ discard block |
||
| 268 | 268 | 'Make sure you read the phpdoc comments above the definition of the $_scripts_styles property in the <code>EE_Admin_Hooks</code> class and modify according in the %s child', |
| 269 | 269 | 'event_espresso' |
| 270 | 270 | ), |
| 271 | - '<strong>' . $this->caller . '</strong>' |
|
| 271 | + '<strong>'.$this->caller.'</strong>' |
|
| 272 | 272 | ); |
| 273 | 273 | throw new EE_Error(implode('||', $msg)); |
| 274 | 274 | } |
@@ -283,7 +283,7 @@ discard block |
||
| 283 | 283 | $details = wp_parse_args($details, $defaults); |
| 284 | 284 | extract($details); |
| 285 | 285 | // let's make sure that we set the 'registers' type if it's not set! We need it later to determine whhich enqueu we do |
| 286 | - $this->_scripts_styles['registers'][ $ref ]['type'] = $type; |
|
| 286 | + $this->_scripts_styles['registers'][$ref]['type'] = $type; |
|
| 287 | 287 | // let's make sure we're not missing any REQUIRED parameters |
| 288 | 288 | if (empty($url)) { |
| 289 | 289 | $msg[] = sprintf( |
@@ -295,7 +295,7 @@ discard block |
||
| 295 | 295 | 'Doublecheck your <code>$this->_scripts_styles</code> array in %s and make sure that there is a "url" set for the %s ref', |
| 296 | 296 | 'event_espresso' |
| 297 | 297 | ), |
| 298 | - '<strong>' . $this->caller . '</strong>', |
|
| 298 | + '<strong>'.$this->caller.'</strong>', |
|
| 299 | 299 | $ref |
| 300 | 300 | ); |
| 301 | 301 | throw new EE_Error(implode('||', $msg)); |
@@ -311,7 +311,7 @@ discard block |
||
| 311 | 311 | ); |
| 312 | 312 | } |
| 313 | 313 | // k now lets do the enqueues |
| 314 | - if (! isset($this->_scripts_styles['enqueues'])) { |
|
| 314 | + if ( ! isset($this->_scripts_styles['enqueues'])) { |
|
| 315 | 315 | return; |
| 316 | 316 | } //not sure if we should throw an error here or not. |
| 317 | 317 | |
@@ -319,22 +319,22 @@ discard block |
||
| 319 | 319 | // make sure $routes is an array |
| 320 | 320 | $routes = (array) $routes; |
| 321 | 321 | if (in_array($this->_current_route, $routes)) { |
| 322 | - $this->_scripts_styles['registers'][ $ref ]['type'] == 'js' ? wp_enqueue_script($ref) |
|
| 322 | + $this->_scripts_styles['registers'][$ref]['type'] == 'js' ? wp_enqueue_script($ref) |
|
| 323 | 323 | : wp_enqueue_style($ref); |
| 324 | 324 | // if we have a localization for the script let's do that too. |
| 325 | - if (isset($this->_scripts_styles['localize'][ $ref ])) { |
|
| 326 | - foreach ($this->_scripts_styles['localize'][ $ref ] as $object_name => $indexes) { |
|
| 325 | + if (isset($this->_scripts_styles['localize'][$ref])) { |
|
| 326 | + foreach ($this->_scripts_styles['localize'][$ref] as $object_name => $indexes) { |
|
| 327 | 327 | wp_localize_script( |
| 328 | 328 | $ref, |
| 329 | 329 | $object_name, |
| 330 | - $this->_scripts_styles['localize'][ $ref ][ $object_name ] |
|
| 330 | + $this->_scripts_styles['localize'][$ref][$object_name] |
|
| 331 | 331 | ); |
| 332 | 332 | } |
| 333 | 333 | } |
| 334 | 334 | } |
| 335 | 335 | } |
| 336 | 336 | // let's do the deregisters |
| 337 | - if (! isset($this->_scripts_styles['deregisters'])) { |
|
| 337 | + if ( ! isset($this->_scripts_styles['deregisters'])) { |
|
| 338 | 338 | return; |
| 339 | 339 | } |
| 340 | 340 | foreach ($this->_scripts_styles['deregisters'] as $ref => $details) { |
@@ -396,20 +396,20 @@ discard block |
||
| 396 | 396 | throw new EE_Error(implode('||', $msg)); |
| 397 | 397 | } |
| 398 | 398 | $ref = str_replace('_', ' ', $this->_name); // take the_message -> the message |
| 399 | - $ref = str_replace(' ', '_', ucwords($ref)) . '_Admin_Page'; // take the message -> The_Message |
|
| 399 | + $ref = str_replace(' ', '_', ucwords($ref)).'_Admin_Page'; // take the message -> The_Message |
|
| 400 | 400 | // first default file (if exists) |
| 401 | - $decaf_file = EE_ADMIN_PAGES . $this->_name . '/' . $ref . '.core.php'; |
|
| 401 | + $decaf_file = EE_ADMIN_PAGES.$this->_name.'/'.$ref.'.core.php'; |
|
| 402 | 402 | if (is_readable($decaf_file)) { |
| 403 | 403 | require_once($decaf_file); |
| 404 | 404 | } |
| 405 | 405 | // now we have to do require for extended file (if needed) |
| 406 | 406 | if ($this->_extend) { |
| 407 | - require_once(EE_CORE_CAF_ADMIN_EXTEND . $this->_name . '/Extend_' . $ref . '.core.php'); |
|
| 407 | + require_once(EE_CORE_CAF_ADMIN_EXTEND.$this->_name.'/Extend_'.$ref.'.core.php'); |
|
| 408 | 408 | } |
| 409 | 409 | // if we've got an extended class we use that! |
| 410 | - $ref = $this->_extend ? 'Extend_' . $ref : $ref; |
|
| 410 | + $ref = $this->_extend ? 'Extend_'.$ref : $ref; |
|
| 411 | 411 | // let's make sure the class exists |
| 412 | - if (! class_exists($ref)) { |
|
| 412 | + if ( ! class_exists($ref)) { |
|
| 413 | 413 | $msg[] = __('We can\'t load the page object', 'event_espresso'); |
| 414 | 414 | $msg[] = sprintf( |
| 415 | 415 | __( |
@@ -451,28 +451,28 @@ discard block |
||
| 451 | 451 | // first the actions |
| 452 | 452 | // note that these action hooks will have the $query_args value available. |
| 453 | 453 | $admin_class_name = get_class($this->_adminpage_obj); |
| 454 | - if (method_exists($this, '_redirect_action_early_' . $this->_current_route)) { |
|
| 454 | + if (method_exists($this, '_redirect_action_early_'.$this->_current_route)) { |
|
| 455 | 455 | add_action( |
| 456 | 456 | 'AHEE__' |
| 457 | 457 | . $admin_class_name |
| 458 | 458 | . '___redirect_after_action__before_redirect_modification_' |
| 459 | 459 | . $this->_current_route, |
| 460 | - array($this, '_redirect_action_early_' . $this->_current_route), |
|
| 460 | + array($this, '_redirect_action_early_'.$this->_current_route), |
|
| 461 | 461 | 10 |
| 462 | 462 | ); |
| 463 | 463 | } |
| 464 | - if (method_exists($this, '_redirect_action_' . $this->_current_route)) { |
|
| 464 | + if (method_exists($this, '_redirect_action_'.$this->_current_route)) { |
|
| 465 | 465 | add_action( |
| 466 | - 'AHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 467 | - array($this, '_redirect_action_' . $this->_current_route), |
|
| 466 | + 'AHEE_redirect_'.$admin_class_name.$this->_current_route, |
|
| 467 | + array($this, '_redirect_action_'.$this->_current_route), |
|
| 468 | 468 | 10 |
| 469 | 469 | ); |
| 470 | 470 | } |
| 471 | 471 | // let's hook into the _redirect itself and allow for changing where the user goes after redirect. This will have $query_args and $redirect_url available. |
| 472 | - if (method_exists($this, '_redirect_filter_' . $this->_current_route)) { |
|
| 472 | + if (method_exists($this, '_redirect_filter_'.$this->_current_route)) { |
|
| 473 | 473 | add_filter( |
| 474 | - 'FHEE_redirect_' . $admin_class_name . $this->_current_route, |
|
| 475 | - array($this, '_redirect_filter_' . $this->_current_route), |
|
| 474 | + 'FHEE_redirect_'.$admin_class_name.$this->_current_route, |
|
| 475 | + array($this, '_redirect_filter_'.$this->_current_route), |
|
| 476 | 476 | 10, |
| 477 | 477 | 2 |
| 478 | 478 | ); |
@@ -497,12 +497,12 @@ discard block |
||
| 497 | 497 | 'argnum' => 1, |
| 498 | 498 | 'priority' => 10, |
| 499 | 499 | ), |
| 500 | - 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug . '_' . $this->_current_route => array( |
|
| 500 | + 'FHEE_list_table_views_'.$this->_adminpage_obj->page_slug.'_'.$this->_current_route => array( |
|
| 501 | 501 | 'type' => 'filter', |
| 502 | 502 | 'argnum' => 1, |
| 503 | 503 | 'priority' => 10, |
| 504 | 504 | ), |
| 505 | - 'FHEE_list_table_views_' . $this->_adminpage_obj->page_slug => array( |
|
| 505 | + 'FHEE_list_table_views_'.$this->_adminpage_obj->page_slug => array( |
|
| 506 | 506 | 'type' => 'filter', |
| 507 | 507 | 'argnum' => 1, |
| 508 | 508 | 'priority' => 10, |
@@ -519,21 +519,21 @@ discard block |
||
| 519 | 519 | ), |
| 520 | 520 | ); |
| 521 | 521 | foreach ($hook_filter_array as $hook => $args) { |
| 522 | - if (method_exists($this, $this->_current_route . '_' . $hook)) { |
|
| 523 | - if (isset($this->_wp_action_filters_priority[ $hook ])) { |
|
| 524 | - $args['priority'] = $this->_wp_action_filters_priority[ $hook ]; |
|
| 522 | + if (method_exists($this, $this->_current_route.'_'.$hook)) { |
|
| 523 | + if (isset($this->_wp_action_filters_priority[$hook])) { |
|
| 524 | + $args['priority'] = $this->_wp_action_filters_priority[$hook]; |
|
| 525 | 525 | } |
| 526 | 526 | if ($args['type'] == 'action') { |
| 527 | 527 | add_action( |
| 528 | 528 | $hook, |
| 529 | - array($this, $this->_current_route . '_' . $hook), |
|
| 529 | + array($this, $this->_current_route.'_'.$hook), |
|
| 530 | 530 | $args['priority'], |
| 531 | 531 | $args['argnum'] |
| 532 | 532 | ); |
| 533 | 533 | } else { |
| 534 | 534 | add_filter( |
| 535 | 535 | $hook, |
| 536 | - array($this, $this->_current_route . '_' . $hook), |
|
| 536 | + array($this, $this->_current_route.'_'.$hook), |
|
| 537 | 537 | $args['priority'], |
| 538 | 538 | $args['argnum'] |
| 539 | 539 | ); |
@@ -556,11 +556,11 @@ discard block |
||
| 556 | 556 | } //get out there's nothing to take care of. |
| 557 | 557 | foreach ($this->_ajax_func as $action => $method) { |
| 558 | 558 | // make sure method exists |
| 559 | - if (! method_exists($this, $method)) { |
|
| 559 | + if ( ! method_exists($this, $method)) { |
|
| 560 | 560 | $msg[] = __( |
| 561 | 561 | 'There is no corresponding method for the hook labeled in the _ajax_func array', |
| 562 | 562 | 'event_espresso' |
| 563 | - ) . '<br />'; |
|
| 563 | + ).'<br />'; |
|
| 564 | 564 | $msg[] = sprintf( |
| 565 | 565 | __( |
| 566 | 566 | 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
@@ -571,7 +571,7 @@ discard block |
||
| 571 | 571 | ); |
| 572 | 572 | throw new EE_Error(implode('||', $msg)); |
| 573 | 573 | } |
| 574 | - add_action('wp_ajax_' . $action, array($this, $method)); |
|
| 574 | + add_action('wp_ajax_'.$action, array($this, $method)); |
|
| 575 | 575 | } |
| 576 | 576 | } |
| 577 | 577 | |
@@ -590,11 +590,11 @@ discard block |
||
| 590 | 590 | $current_route = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'default'; |
| 591 | 591 | foreach ($this->_init_func as $route => $method) { |
| 592 | 592 | // make sure method exists |
| 593 | - if (! method_exists($this, $method)) { |
|
| 593 | + if ( ! method_exists($this, $method)) { |
|
| 594 | 594 | $msg[] = __( |
| 595 | 595 | 'There is no corresponding method for the hook labeled in the _init_func array', |
| 596 | 596 | 'event_espresso' |
| 597 | - ) . '<br />'; |
|
| 597 | + ).'<br />'; |
|
| 598 | 598 | $msg[] = sprintf( |
| 599 | 599 | __( |
| 600 | 600 | 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
@@ -632,7 +632,7 @@ discard block |
||
| 632 | 632 | { |
| 633 | 633 | |
| 634 | 634 | foreach ($boxes as $box) { |
| 635 | - if (! isset($box['page_route'])) { |
|
| 635 | + if ( ! isset($box['page_route'])) { |
|
| 636 | 636 | continue; |
| 637 | 637 | } //we dont' have a valid array |
| 638 | 638 | // let's make sure $box['page_route'] is an array so the "foreach" will work. |
@@ -681,7 +681,7 @@ discard block |
||
| 681 | 681 | // set defaults |
| 682 | 682 | $defaults = array( |
| 683 | 683 | 'func' => $func, |
| 684 | - 'id' => $this->caller . '_' . $func . '_metabox', |
|
| 684 | + 'id' => $this->caller.'_'.$func.'_metabox', |
|
| 685 | 685 | 'priority' => 'default', |
| 686 | 686 | 'label' => $this->caller, |
| 687 | 687 | 'context' => 'advanced', |
@@ -691,8 +691,8 @@ discard block |
||
| 691 | 691 | $args = wp_parse_args($args, $defaults); |
| 692 | 692 | extract($args); |
| 693 | 693 | // make sure method exists |
| 694 | - if (! method_exists($this, $func)) { |
|
| 695 | - $msg[] = __('There is no corresponding method to display the metabox content', 'event_espresso') . '<br />'; |
|
| 694 | + if ( ! method_exists($this, $func)) { |
|
| 695 | + $msg[] = __('There is no corresponding method to display the metabox content', 'event_espresso').'<br />'; |
|
| 696 | 696 | $msg[] = sprintf( |
| 697 | 697 | __( |
| 698 | 698 | 'The method name given in the array is %s, check the spelling and make sure it exists in the %s class', |
@@ -14,91 +14,91 @@ discard block |
||
| 14 | 14 | class EE_Import implements ResettableInterface |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - const do_insert = 'insert'; |
|
| 18 | - const do_update = 'update'; |
|
| 19 | - const do_nothing = 'nothing'; |
|
| 20 | - |
|
| 21 | - |
|
| 22 | - // instance of the EE_Import object |
|
| 23 | - private static $_instance = null; |
|
| 24 | - |
|
| 25 | - private static $_csv_array = array(); |
|
| 26 | - |
|
| 27 | - /** |
|
| 28 | - * |
|
| 29 | - * @var array of model names |
|
| 30 | - */ |
|
| 31 | - private static $_model_list = array(); |
|
| 32 | - |
|
| 33 | - private static $_columns_to_save = array(); |
|
| 34 | - |
|
| 35 | - protected $_total_inserts = 0; |
|
| 36 | - protected $_total_updates = 0; |
|
| 37 | - protected $_total_insert_errors = 0; |
|
| 38 | - protected $_total_update_errors = 0; |
|
| 39 | - |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * private constructor to prevent direct creation |
|
| 43 | - * |
|
| 44 | - * @Constructor |
|
| 45 | - * @access private |
|
| 46 | - * @return void |
|
| 47 | - */ |
|
| 48 | - private function __construct() |
|
| 49 | - { |
|
| 50 | - $this->_total_inserts = 0; |
|
| 51 | - $this->_total_updates = 0; |
|
| 52 | - $this->_total_insert_errors = 0; |
|
| 53 | - $this->_total_update_errors = 0; |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - |
|
| 57 | - /** |
|
| 58 | - * @ singleton method used to instantiate class object |
|
| 59 | - * @ access public |
|
| 60 | - * |
|
| 61 | - * @return EE_Import |
|
| 62 | - */ |
|
| 63 | - public static function instance() |
|
| 64 | - { |
|
| 65 | - // check if class object is instantiated |
|
| 66 | - if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) { |
|
| 67 | - self::$_instance = new self(); |
|
| 68 | - } |
|
| 69 | - return self::$_instance; |
|
| 70 | - } |
|
| 71 | - |
|
| 72 | - /** |
|
| 73 | - * Resets the importer |
|
| 74 | - * |
|
| 75 | - * @return EE_Import |
|
| 76 | - */ |
|
| 77 | - public static function reset() |
|
| 78 | - { |
|
| 79 | - self::$_instance = null; |
|
| 80 | - return self::instance(); |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - |
|
| 84 | - /** |
|
| 85 | - * @ generates HTML for a file upload input and form |
|
| 86 | - * @ access public |
|
| 87 | - * |
|
| 88 | - * @param string $title - heading for the form |
|
| 89 | - * @param string $intro - additional text explaing what to do |
|
| 90 | - * @param string $page - EE Admin page to direct form to - in the form "espresso_{pageslug}" |
|
| 91 | - * @param string $action - EE Admin page route array "action" that form will direct to |
|
| 92 | - * @param string $type - type of file to import |
|
| 93 | - * @ return string |
|
| 94 | - */ |
|
| 95 | - public function upload_form($title, $intro, $form_url, $action, $type) |
|
| 96 | - { |
|
| 97 | - |
|
| 98 | - $form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url); |
|
| 99 | - |
|
| 100 | - ob_start(); |
|
| 101 | - ?> |
|
| 17 | + const do_insert = 'insert'; |
|
| 18 | + const do_update = 'update'; |
|
| 19 | + const do_nothing = 'nothing'; |
|
| 20 | + |
|
| 21 | + |
|
| 22 | + // instance of the EE_Import object |
|
| 23 | + private static $_instance = null; |
|
| 24 | + |
|
| 25 | + private static $_csv_array = array(); |
|
| 26 | + |
|
| 27 | + /** |
|
| 28 | + * |
|
| 29 | + * @var array of model names |
|
| 30 | + */ |
|
| 31 | + private static $_model_list = array(); |
|
| 32 | + |
|
| 33 | + private static $_columns_to_save = array(); |
|
| 34 | + |
|
| 35 | + protected $_total_inserts = 0; |
|
| 36 | + protected $_total_updates = 0; |
|
| 37 | + protected $_total_insert_errors = 0; |
|
| 38 | + protected $_total_update_errors = 0; |
|
| 39 | + |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * private constructor to prevent direct creation |
|
| 43 | + * |
|
| 44 | + * @Constructor |
|
| 45 | + * @access private |
|
| 46 | + * @return void |
|
| 47 | + */ |
|
| 48 | + private function __construct() |
|
| 49 | + { |
|
| 50 | + $this->_total_inserts = 0; |
|
| 51 | + $this->_total_updates = 0; |
|
| 52 | + $this->_total_insert_errors = 0; |
|
| 53 | + $this->_total_update_errors = 0; |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + |
|
| 57 | + /** |
|
| 58 | + * @ singleton method used to instantiate class object |
|
| 59 | + * @ access public |
|
| 60 | + * |
|
| 61 | + * @return EE_Import |
|
| 62 | + */ |
|
| 63 | + public static function instance() |
|
| 64 | + { |
|
| 65 | + // check if class object is instantiated |
|
| 66 | + if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) { |
|
| 67 | + self::$_instance = new self(); |
|
| 68 | + } |
|
| 69 | + return self::$_instance; |
|
| 70 | + } |
|
| 71 | + |
|
| 72 | + /** |
|
| 73 | + * Resets the importer |
|
| 74 | + * |
|
| 75 | + * @return EE_Import |
|
| 76 | + */ |
|
| 77 | + public static function reset() |
|
| 78 | + { |
|
| 79 | + self::$_instance = null; |
|
| 80 | + return self::instance(); |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + |
|
| 84 | + /** |
|
| 85 | + * @ generates HTML for a file upload input and form |
|
| 86 | + * @ access public |
|
| 87 | + * |
|
| 88 | + * @param string $title - heading for the form |
|
| 89 | + * @param string $intro - additional text explaing what to do |
|
| 90 | + * @param string $page - EE Admin page to direct form to - in the form "espresso_{pageslug}" |
|
| 91 | + * @param string $action - EE Admin page route array "action" that form will direct to |
|
| 92 | + * @param string $type - type of file to import |
|
| 93 | + * @ return string |
|
| 94 | + */ |
|
| 95 | + public function upload_form($title, $intro, $form_url, $action, $type) |
|
| 96 | + { |
|
| 97 | + |
|
| 98 | + $form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url); |
|
| 99 | + |
|
| 100 | + ob_start(); |
|
| 101 | + ?> |
|
| 102 | 102 | <div class="ee-upload-form-dv"> |
| 103 | 103 | <h3><?php echo $title; ?></h3> |
| 104 | 104 | <p><?php echo $intro; ?></p> |
@@ -114,874 +114,874 @@ discard block |
||
| 114 | 114 | <b><?php _e('Attention', 'event_espresso'); ?></b><br/> |
| 115 | 115 | <?php echo sprintf(__('Accepts .%s file types only.', 'event_espresso'), $type); ?> |
| 116 | 116 | <?php echo __( |
| 117 | - 'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.', |
|
| 118 | - 'event_espresso' |
|
| 119 | - ); ?> |
|
| 117 | + 'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.', |
|
| 118 | + 'event_espresso' |
|
| 119 | + ); ?> |
|
| 120 | 120 | </p> |
| 121 | 121 | |
| 122 | 122 | </div> |
| 123 | 123 | |
| 124 | 124 | <?php |
| 125 | - $uploader = ob_get_clean(); |
|
| 126 | - return $uploader; |
|
| 127 | - } |
|
| 128 | - |
|
| 129 | - |
|
| 130 | - /** |
|
| 131 | - * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php |
|
| 132 | - * @access public |
|
| 133 | - * @return boolean success |
|
| 134 | - */ |
|
| 135 | - public function import() |
|
| 136 | - { |
|
| 137 | - |
|
| 138 | - require_once(EE_CLASSES . 'EE_CSV.class.php'); |
|
| 139 | - $this->EE_CSV = EE_CSV::instance(); |
|
| 140 | - |
|
| 141 | - if (isset($_REQUEST['import'])) { |
|
| 142 | - if (isset($_POST['csv_submitted'])) { |
|
| 143 | - switch ($_FILES['file']['error'][0]) { |
|
| 144 | - case UPLOAD_ERR_OK: |
|
| 145 | - $error_msg = false; |
|
| 146 | - break; |
|
| 147 | - case UPLOAD_ERR_INI_SIZE: |
|
| 148 | - $error_msg = __( |
|
| 149 | - "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'", |
|
| 150 | - "event_espresso" |
|
| 151 | - ); |
|
| 152 | - break; |
|
| 153 | - case UPLOAD_ERR_FORM_SIZE: |
|
| 154 | - $error_msg = __( |
|
| 155 | - 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', |
|
| 156 | - "event_espresso" |
|
| 157 | - ); |
|
| 158 | - break; |
|
| 159 | - case UPLOAD_ERR_PARTIAL: |
|
| 160 | - $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso"); |
|
| 161 | - break; |
|
| 162 | - case UPLOAD_ERR_NO_FILE: |
|
| 163 | - $error_msg = __('No file was uploaded.', "event_espresso"); |
|
| 164 | - break; |
|
| 165 | - case UPLOAD_ERR_NO_TMP_DIR: |
|
| 166 | - $error_msg = __('Missing a temporary folder.', "event_espresso"); |
|
| 167 | - break; |
|
| 168 | - case UPLOAD_ERR_CANT_WRITE: |
|
| 169 | - $error_msg = __('Failed to write file to disk.', "event_espresso"); |
|
| 170 | - break; |
|
| 171 | - case UPLOAD_ERR_EXTENSION: |
|
| 172 | - $error_msg = __('File upload stopped by extension.', "event_espresso"); |
|
| 173 | - break; |
|
| 174 | - default: |
|
| 175 | - $error_msg = __( |
|
| 176 | - 'An unknown error occurred and the file could not be uploaded', |
|
| 177 | - "event_espresso" |
|
| 178 | - ); |
|
| 179 | - break; |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - if (! $error_msg) { |
|
| 183 | - $filename = $_FILES['file']['name'][0]; |
|
| 184 | - $file_ext = substr(strrchr($filename, '.'), 1); |
|
| 185 | - $file_type = $_FILES['file']['type'][0]; |
|
| 186 | - $temp_file = $_FILES['file']['tmp_name'][0]; |
|
| 187 | - $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB |
|
| 188 | - |
|
| 189 | - if ($file_ext == 'csv') { |
|
| 190 | - $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB |
|
| 191 | - if ($filesize < $max_upload || true) { |
|
| 192 | - $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir()); |
|
| 193 | - $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename; |
|
| 194 | - |
|
| 195 | - if (move_uploaded_file($temp_file, $path_to_file)) { |
|
| 196 | - // convert csv to array |
|
| 197 | - $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file); |
|
| 198 | - |
|
| 199 | - // was data successfully stored in an array? |
|
| 200 | - if (is_array($this->csv_array)) { |
|
| 201 | - $import_what = str_replace('csv_import_', '', $_REQUEST['action']); |
|
| 202 | - $import_what = str_replace('_', ' ', ucwords($import_what)); |
|
| 203 | - $processed_data = $this->csv_array; |
|
| 204 | - $this->columns_to_save = false; |
|
| 205 | - |
|
| 206 | - // if any imports require funcky processing, we'll catch them in the switch |
|
| 207 | - switch ($_REQUEST['action']) { |
|
| 208 | - case "import_events": |
|
| 209 | - case "event_list": |
|
| 210 | - $import_what = 'Event Details'; |
|
| 211 | - break; |
|
| 212 | - |
|
| 213 | - case 'groupon_import_csv': |
|
| 214 | - $import_what = 'Groupon Codes'; |
|
| 215 | - $processed_data = $this->process_groupon_codes(); |
|
| 216 | - break; |
|
| 217 | - } |
|
| 218 | - // save processed codes to db |
|
| 219 | - if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) { |
|
| 220 | - return true; |
|
| 221 | - } |
|
| 222 | - } else { |
|
| 223 | - // no array? must be an error |
|
| 224 | - EE_Error::add_error( |
|
| 225 | - sprintf(__("No file seems to have been uploaded", "event_espresso")), |
|
| 226 | - __FILE__, |
|
| 227 | - __FUNCTION__, |
|
| 228 | - __LINE__ |
|
| 229 | - ); |
|
| 230 | - return false; |
|
| 231 | - } |
|
| 232 | - } else { |
|
| 233 | - EE_Error::add_error( |
|
| 234 | - sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename), |
|
| 235 | - __FILE__, |
|
| 236 | - __FUNCTION__, |
|
| 237 | - __LINE__ |
|
| 238 | - ); |
|
| 239 | - return false; |
|
| 240 | - } |
|
| 241 | - } else { |
|
| 242 | - EE_Error::add_error( |
|
| 243 | - sprintf( |
|
| 244 | - __( |
|
| 245 | - "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.", |
|
| 246 | - "event_espresso" |
|
| 247 | - ), |
|
| 248 | - $filename, |
|
| 249 | - $max_upload |
|
| 250 | - ), |
|
| 251 | - __FILE__, |
|
| 252 | - __FUNCTION__, |
|
| 253 | - __LINE__ |
|
| 254 | - ); |
|
| 255 | - return false; |
|
| 256 | - } |
|
| 257 | - } else { |
|
| 258 | - EE_Error::add_error( |
|
| 259 | - sprintf(__("%s had an invalid file extension, not uploaded", "event_espresso"), $filename), |
|
| 260 | - __FILE__, |
|
| 261 | - __FUNCTION__, |
|
| 262 | - __LINE__ |
|
| 263 | - ); |
|
| 264 | - return false; |
|
| 265 | - } |
|
| 266 | - } else { |
|
| 267 | - EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 268 | - return false; |
|
| 269 | - } |
|
| 270 | - } |
|
| 271 | - } |
|
| 272 | - return; |
|
| 273 | - } |
|
| 274 | - |
|
| 275 | - |
|
| 276 | - /** |
|
| 277 | - * Given an array of data (usually from a CSV import) attempts to save that data to the db. |
|
| 278 | - * If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names, |
|
| 279 | - * next level being numeric indexes adn each value representing a model object, and the last layer down |
|
| 280 | - * being keys of model fields and their proposed values. |
|
| 281 | - * If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned. |
|
| 282 | - * If the CSV data says (in the metadata row) that it's from the SAME database, |
|
| 283 | - * we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those |
|
| 284 | - * IDs DON'T exist in the database, they're treated as temporary IDs, |
|
| 285 | - * which can used elsewhere to refer to the same object. Once an item |
|
| 286 | - * with a temporary ID gets inserted, we record its mapping from temporary |
|
| 287 | - * ID to real ID, and use the real ID in place of the temporary ID |
|
| 288 | - * when that temporary ID was used as a foreign key. |
|
| 289 | - * If the CSV data says (in the metadata again) that it's from a DIFFERENT database, |
|
| 290 | - * we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with |
|
| 291 | - * ID 1, and the database already has an event with ID 1, we assume that's just a coincidence, |
|
| 292 | - * and insert a new event, and map it's temporary ID of 1 over to its new real ID. |
|
| 293 | - * An important exception are non-auto-increment primary keys. If one entry in the |
|
| 294 | - * CSV file has the same ID as one in the DB, we assume they are meant to be |
|
| 295 | - * the same item, and instead update the item in the DB with that same ID. |
|
| 296 | - * Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th |
|
| 297 | - * time you import a CSV from a different site, we remember their mappings, and |
|
| 298 | - * will try to update the item in the DB instead of inserting another item (eg |
|
| 299 | - * if we previously imported an event with temporary ID 1, and then it got a |
|
| 300 | - * real ID of 123, we remember that. So the next time we import an event with |
|
| 301 | - * temporary ID, from the same site, we know that it's real ID is 123, and will |
|
| 302 | - * update that event, instead of adding a new event). |
|
| 303 | - * |
|
| 304 | - * @access public |
|
| 305 | - * @param array $csv_data_array - the array containing the csv data produced from |
|
| 306 | - * EE_CSV::import_csv_to_model_data_array() |
|
| 307 | - * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table |
|
| 308 | - * fields they will be saved to |
|
| 309 | - * @return TRUE on success, FALSE on fail |
|
| 310 | - * @throws \EE_Error |
|
| 311 | - */ |
|
| 312 | - public function save_csv_data_array_to_db($csv_data_array, $model_name = false) |
|
| 313 | - { |
|
| 314 | - $success = false; |
|
| 315 | - $error = false; |
|
| 316 | - // whther to treat this import as if it's data froma different database or not |
|
| 317 | - // ie, if it IS from a different database, ignore foreign keys whihf |
|
| 318 | - $export_from_site_a_to_b = true; |
|
| 319 | - // first level of array is not table information but a table name was passed to the function |
|
| 320 | - // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail |
|
| 321 | - if ($model_name) { |
|
| 322 | - $csv_data_array = array($csv_data_array); |
|
| 323 | - } |
|
| 324 | - // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name... |
|
| 325 | - $old_site_url = 'none-specified'; |
|
| 326 | - // hanlde metadata |
|
| 327 | - if (isset($csv_data_array[ EE_CSV::metadata_header ])) { |
|
| 328 | - $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 329 | - // ok so its metadata, dont try to save it to ehte db obviously... |
|
| 330 | - if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) { |
|
| 331 | - EE_Error::add_attention( |
|
| 332 | - sprintf( |
|
| 333 | - __( |
|
| 334 | - "CSV Data appears to be from the same database, so attempting to update data", |
|
| 335 | - "event_espresso" |
|
| 336 | - ) |
|
| 337 | - ) |
|
| 338 | - ); |
|
| 339 | - $export_from_site_a_to_b = false; |
|
| 340 | - } else { |
|
| 341 | - $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url; |
|
| 342 | - EE_Error::add_attention( |
|
| 343 | - sprintf( |
|
| 344 | - __( |
|
| 345 | - "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database", |
|
| 346 | - "event_espresso" |
|
| 347 | - ), |
|
| 348 | - $old_site_url, |
|
| 349 | - site_url() |
|
| 350 | - ) |
|
| 351 | - ); |
|
| 352 | - }; |
|
| 353 | - unset($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 354 | - } |
|
| 355 | - /** |
|
| 356 | - * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and |
|
| 357 | - * the value will be the newly-inserted ID. |
|
| 358 | - * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option |
|
| 359 | - */ |
|
| 360 | - $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array()); |
|
| 361 | - if ($old_db_to_new_db_mapping) { |
|
| 362 | - EE_Error::add_attention( |
|
| 363 | - sprintf( |
|
| 364 | - __( |
|
| 365 | - "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s", |
|
| 366 | - "event_espresso" |
|
| 367 | - ), |
|
| 368 | - $old_site_url, |
|
| 369 | - site_url() |
|
| 370 | - ) |
|
| 371 | - ); |
|
| 372 | - } |
|
| 373 | - $old_db_to_new_db_mapping = $this->save_data_rows_to_db( |
|
| 374 | - $csv_data_array, |
|
| 375 | - $export_from_site_a_to_b, |
|
| 376 | - $old_db_to_new_db_mapping |
|
| 377 | - ); |
|
| 378 | - |
|
| 379 | - // save the mapping from old db to new db in case they try re-importing the same data from the same website again |
|
| 380 | - update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping); |
|
| 381 | - |
|
| 382 | - if ($this->_total_updates > 0) { |
|
| 383 | - EE_Error::add_success( |
|
| 384 | - sprintf( |
|
| 385 | - __("%s existing records in the database were updated.", "event_espresso"), |
|
| 386 | - $this->_total_updates |
|
| 387 | - ) |
|
| 388 | - ); |
|
| 389 | - $success = true; |
|
| 390 | - } |
|
| 391 | - if ($this->_total_inserts > 0) { |
|
| 392 | - EE_Error::add_success( |
|
| 393 | - sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts) |
|
| 394 | - ); |
|
| 395 | - $success = true; |
|
| 396 | - } |
|
| 397 | - |
|
| 398 | - if ($this->_total_update_errors > 0) { |
|
| 399 | - EE_Error::add_error( |
|
| 400 | - sprintf( |
|
| 401 | - __( |
|
| 402 | - "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'", |
|
| 403 | - "event_espresso" |
|
| 404 | - ), |
|
| 405 | - $this->_total_update_errors |
|
| 406 | - ), |
|
| 407 | - __FILE__, |
|
| 408 | - __FUNCTION__, |
|
| 409 | - __LINE__ |
|
| 410 | - ); |
|
| 411 | - $error = true; |
|
| 412 | - } |
|
| 413 | - if ($this->_total_insert_errors > 0) { |
|
| 414 | - EE_Error::add_error( |
|
| 415 | - sprintf( |
|
| 416 | - __( |
|
| 417 | - "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'", |
|
| 418 | - "event_espresso" |
|
| 419 | - ), |
|
| 420 | - $this->_total_insert_errors |
|
| 421 | - ), |
|
| 422 | - __FILE__, |
|
| 423 | - __FUNCTION__, |
|
| 424 | - __LINE__ |
|
| 425 | - ); |
|
| 426 | - $error = true; |
|
| 427 | - } |
|
| 428 | - |
|
| 429 | - // lastly, we need to update the datetime and ticket sold amounts |
|
| 430 | - // as those may have been affected by this |
|
| 431 | - EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all()); |
|
| 432 | - |
|
| 433 | - // if there was at least one success and absolutely no errors |
|
| 434 | - if ($success && ! $error) { |
|
| 435 | - return true; |
|
| 436 | - } else { |
|
| 437 | - return false; |
|
| 438 | - } |
|
| 439 | - } |
|
| 440 | - |
|
| 441 | - |
|
| 442 | - /** |
|
| 443 | - * Processes the array of data, given the knowledge that it's from the same database or a different one, |
|
| 444 | - * and the mapping from temporary IDs to real IDs. |
|
| 445 | - * If the data is from a different database, we treat the primary keys and their corresponding |
|
| 446 | - * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys |
|
| 447 | - * in the real target database. As items are inserted, their temporary primary keys |
|
| 448 | - * are mapped to the real IDs in the target database. Also, before doing any update or |
|
| 449 | - * insert, we replace all the temp ID which are foreign keys with their mapped real IDs. |
|
| 450 | - * An exception: string primary keys are treated as real IDs, or else we'd need to |
|
| 451 | - * dynamically generate new string primary keys which would be very awkard for the country table etc. |
|
| 452 | - * Also, models with no primary key are strange too. We combine use their primar key INDEX (a |
|
| 453 | - * combination of fields) to create a unique string identifying the row and store |
|
| 454 | - * those in the mapping. |
|
| 455 | - * |
|
| 456 | - * If the data is from the same database, we usually treat primary keys as real IDs. |
|
| 457 | - * An exception is if there is nothing in the database for that ID. If that's the case, |
|
| 458 | - * we need to insert a new row for that ID, and then map from the non-existent ID |
|
| 459 | - * to the newly-inserted real ID. |
|
| 460 | - * |
|
| 461 | - * @param type $csv_data_array |
|
| 462 | - * @param type $export_from_site_a_to_b |
|
| 463 | - * @param type $old_db_to_new_db_mapping |
|
| 464 | - * @return array updated $old_db_to_new_db_mapping |
|
| 465 | - */ |
|
| 466 | - public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping) |
|
| 467 | - { |
|
| 468 | - foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) { |
|
| 469 | - // now check that assumption was correct. If |
|
| 470 | - if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) { |
|
| 471 | - $model_name = $model_name_in_csv_data; |
|
| 472 | - } else { |
|
| 473 | - // no table info in the array and no table name passed to the function?? FAIL |
|
| 474 | - EE_Error::add_error( |
|
| 475 | - __( |
|
| 476 | - 'No table information was specified and/or found, therefore the import could not be completed', |
|
| 477 | - 'event_espresso' |
|
| 478 | - ), |
|
| 479 | - __FILE__, |
|
| 480 | - __FUNCTION__, |
|
| 481 | - __LINE__ |
|
| 482 | - ); |
|
| 483 | - return false; |
|
| 484 | - } |
|
| 485 | - /* @var $model EEM_Base */ |
|
| 486 | - $model = EE_Registry::instance()->load_model($model_name); |
|
| 487 | - |
|
| 488 | - // so without further ado, scanning all the data provided for primary keys and their inital values |
|
| 489 | - foreach ($model_data_from_import as $model_object_data) { |
|
| 490 | - // before we do ANYTHING, make sure the csv row wasn't just completely blank |
|
| 491 | - $row_is_completely_empty = true; |
|
| 492 | - foreach ($model_object_data as $field) { |
|
| 493 | - if ($field) { |
|
| 494 | - $row_is_completely_empty = false; |
|
| 495 | - } |
|
| 496 | - } |
|
| 497 | - if ($row_is_completely_empty) { |
|
| 498 | - continue; |
|
| 499 | - } |
|
| 500 | - // find the PK in the row of data (or a combined key if |
|
| 501 | - // there is no primary key) |
|
| 502 | - if ($model->has_primary_key_field()) { |
|
| 503 | - $id_in_csv = $model_object_data[ $model->primary_key_name() ]; |
|
| 504 | - } else { |
|
| 505 | - $id_in_csv = $model->get_index_primary_key_string($model_object_data); |
|
| 506 | - } |
|
| 507 | - |
|
| 508 | - |
|
| 509 | - $model_object_data = $this->_replace_temp_ids_with_mappings( |
|
| 510 | - $model_object_data, |
|
| 511 | - $model, |
|
| 512 | - $old_db_to_new_db_mapping, |
|
| 513 | - $export_from_site_a_to_b |
|
| 514 | - ); |
|
| 515 | - // now we need to decide if we're going to add a new model object given the $model_object_data, |
|
| 516 | - // or just update. |
|
| 517 | - if ($export_from_site_a_to_b) { |
|
| 518 | - $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db( |
|
| 519 | - $id_in_csv, |
|
| 520 | - $model_object_data, |
|
| 521 | - $model, |
|
| 522 | - $old_db_to_new_db_mapping |
|
| 523 | - ); |
|
| 524 | - } else {// this is just a re-import |
|
| 525 | - $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db( |
|
| 526 | - $id_in_csv, |
|
| 527 | - $model_object_data, |
|
| 528 | - $model, |
|
| 529 | - $old_db_to_new_db_mapping |
|
| 530 | - ); |
|
| 531 | - } |
|
| 532 | - if ($what_to_do == self::do_nothing) { |
|
| 533 | - continue; |
|
| 534 | - } |
|
| 535 | - |
|
| 536 | - // double-check we actually want to insert, if that's what we're planning |
|
| 537 | - // based on whether this item would be unique in the DB or not |
|
| 538 | - if ($what_to_do == self::do_insert) { |
|
| 539 | - // we're supposed to be inserting. But wait, will this thing |
|
| 540 | - // be acceptable if inserted? |
|
| 541 | - $conflicting = $model->get_one_conflicting($model_object_data, false); |
|
| 542 | - if ($conflicting) { |
|
| 543 | - // ok, this item would conflict if inserted. Just update the item that it conflicts with. |
|
| 544 | - $what_to_do = self::do_update; |
|
| 545 | - // and if this model has a primary key, remember its mapping |
|
| 546 | - if ($model->has_primary_key_field()) { |
|
| 547 | - $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID(); |
|
| 548 | - $model_object_data[ $model->primary_key_name() ] = $conflicting->ID(); |
|
| 549 | - } else { |
|
| 550 | - // we want to update this conflicting item, instead of inserting a conflicting item |
|
| 551 | - // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields |
|
| 552 | - // for the WHERE conditions in the update). At the time of this comment, there were no models like this |
|
| 553 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
| 554 | - $model_object_data[ $key_field->get_name() ] = $conflicting->get( |
|
| 555 | - $key_field->get_name() |
|
| 556 | - ); |
|
| 557 | - } |
|
| 558 | - } |
|
| 559 | - } |
|
| 560 | - } |
|
| 561 | - if ($what_to_do == self::do_insert) { |
|
| 562 | - $old_db_to_new_db_mapping = $this->_insert_from_data_array( |
|
| 563 | - $id_in_csv, |
|
| 564 | - $model_object_data, |
|
| 565 | - $model, |
|
| 566 | - $old_db_to_new_db_mapping |
|
| 567 | - ); |
|
| 568 | - } elseif ($what_to_do == self::do_update) { |
|
| 569 | - $old_db_to_new_db_mapping = $this->_update_from_data_array( |
|
| 570 | - $id_in_csv, |
|
| 571 | - $model_object_data, |
|
| 572 | - $model, |
|
| 573 | - $old_db_to_new_db_mapping |
|
| 574 | - ); |
|
| 575 | - } else { |
|
| 576 | - throw new EE_Error( |
|
| 577 | - sprintf( |
|
| 578 | - __( |
|
| 579 | - 'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid', |
|
| 580 | - 'event_espresso' |
|
| 581 | - ), |
|
| 582 | - $what_to_do |
|
| 583 | - ) |
|
| 584 | - ); |
|
| 585 | - } |
|
| 586 | - } |
|
| 587 | - } |
|
| 588 | - return $old_db_to_new_db_mapping; |
|
| 589 | - } |
|
| 590 | - |
|
| 591 | - |
|
| 592 | - /** |
|
| 593 | - * Decides whether or not to insert, given that this data is from another database. |
|
| 594 | - * So, if the primary key of this $model_object_data already exists in the database, |
|
| 595 | - * it's just a coincidence and we should still insert. The only time we should |
|
| 596 | - * update is when we know what it maps to, or there's something that would |
|
| 597 | - * conflict (and we should instead just update that conflicting thing) |
|
| 598 | - * |
|
| 599 | - * @param string $id_in_csv |
|
| 600 | - * @param array $model_object_data by reference so it can be modified |
|
| 601 | - * @param EEM_Base $model |
|
| 602 | - * @param array $old_db_to_new_db_mapping by reference so it can be modified |
|
| 603 | - * @return string one of the consts on this class that starts with do_* |
|
| 604 | - */ |
|
| 605 | - protected function _decide_whether_to_insert_or_update_given_data_from_other_db( |
|
| 606 | - $id_in_csv, |
|
| 607 | - $model_object_data, |
|
| 608 | - $model, |
|
| 609 | - $old_db_to_new_db_mapping |
|
| 610 | - ) { |
|
| 611 | - $model_name = $model->get_this_model_name(); |
|
| 612 | - // if it's a site-to-site export-and-import, see if this modelobject's id |
|
| 613 | - // in the old data that we know of |
|
| 614 | - if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) { |
|
| 615 | - return self::do_update; |
|
| 616 | - } else { |
|
| 617 | - return self::do_insert; |
|
| 618 | - } |
|
| 619 | - } |
|
| 620 | - |
|
| 621 | - /** |
|
| 622 | - * If this thing basically already exists in the database, we want to update it; |
|
| 623 | - * otherwise insert it (ie, someone tweaked the CSV file, or the item was |
|
| 624 | - * deleted in the database so it should be re-inserted) |
|
| 625 | - * |
|
| 626 | - * @param type $id_in_csv |
|
| 627 | - * @param type $model_object_data |
|
| 628 | - * @param EEM_Base $model |
|
| 629 | - * @param type $old_db_to_new_db_mapping |
|
| 630 | - * @return |
|
| 631 | - */ |
|
| 632 | - protected function _decide_whether_to_insert_or_update_given_data_from_same_db( |
|
| 633 | - $id_in_csv, |
|
| 634 | - $model_object_data, |
|
| 635 | - $model |
|
| 636 | - ) { |
|
| 637 | - // in this case, check if this thing ACTUALLY exists in the database |
|
| 638 | - if ($model->get_one_conflicting($model_object_data)) { |
|
| 639 | - return self::do_update; |
|
| 640 | - } else { |
|
| 641 | - return self::do_insert; |
|
| 642 | - } |
|
| 643 | - } |
|
| 644 | - |
|
| 645 | - /** |
|
| 646 | - * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs |
|
| 647 | - * with their mapped real IDs. Eg, if importing from site A to B, the mapping |
|
| 648 | - * file may indicate that the ID "my_event_id" maps to an actual event ID of 123. |
|
| 649 | - * So this function searches for any event temp Ids called "my_event_id" and |
|
| 650 | - * replaces them with 123. |
|
| 651 | - * Also, if there is no temp ID for the INT foreign keys from another database, |
|
| 652 | - * replaces them with 0 or the field's default. |
|
| 653 | - * |
|
| 654 | - * @param type $model_object_data |
|
| 655 | - * @param EEM_Base $model |
|
| 656 | - * @param type $old_db_to_new_db_mapping |
|
| 657 | - * @param boolean $export_from_site_a_to_b |
|
| 658 | - * @return array updated model object data with temp IDs removed |
|
| 659 | - */ |
|
| 660 | - protected function _replace_temp_ids_with_mappings( |
|
| 661 | - $model_object_data, |
|
| 662 | - $model, |
|
| 663 | - $old_db_to_new_db_mapping, |
|
| 664 | - $export_from_site_a_to_b |
|
| 665 | - ) { |
|
| 666 | - // if this model object's primary key is in the mapping, replace it |
|
| 667 | - if ($model->has_primary_key_field() && |
|
| 668 | - $model->get_primary_key_field()->is_auto_increment() && |
|
| 669 | - isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) && |
|
| 670 | - isset( |
|
| 671 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ] |
|
| 672 | - )) { |
|
| 673 | - $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name( |
|
| 674 | - ) ][ $model_object_data[ $model->primary_key_name() ] ]; |
|
| 675 | - } |
|
| 676 | - |
|
| 677 | - try { |
|
| 678 | - $model_name_field = $model->get_field_containing_related_model_name(); |
|
| 679 | - $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to(); |
|
| 680 | - } catch (EE_Error $e) { |
|
| 681 | - $model_name_field = null; |
|
| 682 | - $models_pointed_to_by_model_name_field = array(); |
|
| 683 | - } |
|
| 684 | - foreach ($model->field_settings(true) as $field_obj) { |
|
| 685 | - if ($field_obj instanceof EE_Foreign_Key_Int_Field) { |
|
| 686 | - $models_pointed_to = $field_obj->get_model_names_pointed_to(); |
|
| 687 | - $found_a_mapping = false; |
|
| 688 | - foreach ($models_pointed_to as $model_pointed_to_by_fk) { |
|
| 689 | - if ($model_name_field) { |
|
| 690 | - $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ]; |
|
| 691 | - if ($value_of_model_name_field == $model_pointed_to_by_fk) { |
|
| 692 | - $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 693 | - $model_object_data[ $field_obj->get_name() ], |
|
| 694 | - $model_pointed_to_by_fk, |
|
| 695 | - $old_db_to_new_db_mapping, |
|
| 696 | - $export_from_site_a_to_b |
|
| 697 | - ); |
|
| 698 | - $found_a_mapping = true; |
|
| 699 | - break; |
|
| 700 | - } |
|
| 701 | - } else { |
|
| 702 | - $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 703 | - $model_object_data[ $field_obj->get_name() ], |
|
| 704 | - $model_pointed_to_by_fk, |
|
| 705 | - $old_db_to_new_db_mapping, |
|
| 706 | - $export_from_site_a_to_b |
|
| 707 | - ); |
|
| 708 | - $found_a_mapping = true; |
|
| 709 | - } |
|
| 710 | - // once we've found a mapping for this field no need to continue |
|
| 711 | - if ($found_a_mapping) { |
|
| 712 | - break; |
|
| 713 | - } |
|
| 714 | - } |
|
| 715 | - } else { |
|
| 716 | - // it's a string foreign key (which we leave alone, because those are things |
|
| 717 | - // like country names, which we'd really rather not make 2 USAs etc (we'd actually |
|
| 718 | - // prefer to just update one) |
|
| 719 | - // or it's just a regular value that ought to be replaced |
|
| 720 | - } |
|
| 721 | - } |
|
| 722 | - // |
|
| 723 | - if ($model instanceof EEM_Term_Taxonomy) { |
|
| 724 | - $model_object_data = $this->_handle_split_term_ids($model_object_data); |
|
| 725 | - } |
|
| 726 | - return $model_object_data; |
|
| 727 | - } |
|
| 728 | - |
|
| 729 | - /** |
|
| 730 | - * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id |
|
| 731 | - * this term-taxonomy refers to may be out-of-date so we need to update it. |
|
| 732 | - * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/ |
|
| 733 | - * |
|
| 734 | - * @param type $model_object_data |
|
| 735 | - * @return array new model object data |
|
| 736 | - */ |
|
| 737 | - protected function _handle_split_term_ids($model_object_data) |
|
| 738 | - { |
|
| 739 | - if (isset($model_object_data['term_id']) |
|
| 740 | - && isset($model_object_data['taxonomy']) |
|
| 741 | - && apply_filters( |
|
| 742 | - 'FHEE__EE_Import__handle_split_term_ids__function_exists', |
|
| 743 | - function_exists('wp_get_split_term'), |
|
| 744 | - $model_object_data |
|
| 745 | - )) { |
|
| 746 | - $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']); |
|
| 747 | - if ($new_term_id) { |
|
| 748 | - $model_object_data['term_id'] = $new_term_id; |
|
| 749 | - } |
|
| 750 | - } |
|
| 751 | - return $model_object_data; |
|
| 752 | - } |
|
| 753 | - |
|
| 754 | - /** |
|
| 755 | - * Given the object's ID and its model's name, find it int he mapping data, |
|
| 756 | - * bearing in mind where it came from |
|
| 757 | - * |
|
| 758 | - * @param type $object_id |
|
| 759 | - * @param string $model_name |
|
| 760 | - * @param array $old_db_to_new_db_mapping |
|
| 761 | - * @param type $export_from_site_a_to_b |
|
| 762 | - * @return int |
|
| 763 | - */ |
|
| 764 | - protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b) |
|
| 765 | - { |
|
| 766 | - if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) { |
|
| 767 | - return $old_db_to_new_db_mapping[ $model_name ][ $object_id ]; |
|
| 768 | - } elseif ($object_id == '0' || $object_id == '') { |
|
| 769 | - // leave as-is |
|
| 770 | - return $object_id; |
|
| 771 | - } elseif ($export_from_site_a_to_b) { |
|
| 772 | - // we couldn't find a mapping for this, and it's from a different site, |
|
| 773 | - // so blank it out |
|
| 774 | - return null; |
|
| 775 | - } elseif (! $export_from_site_a_to_b) { |
|
| 776 | - // we coudln't find a mapping for this, but it's from thsi DB anyway |
|
| 777 | - // so let's just leave it as-is |
|
| 778 | - return $object_id; |
|
| 779 | - } |
|
| 780 | - } |
|
| 781 | - |
|
| 782 | - /** |
|
| 783 | - * |
|
| 784 | - * @param type $id_in_csv |
|
| 785 | - * @param type $model_object_data |
|
| 786 | - * @param EEM_Base $model |
|
| 787 | - * @param type $old_db_to_new_db_mapping |
|
| 788 | - * @return array updated $old_db_to_new_db_mapping |
|
| 789 | - */ |
|
| 790 | - protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping) |
|
| 791 | - { |
|
| 792 | - // remove the primary key, if there is one (we don't want it for inserts OR updates) |
|
| 793 | - // we'll put it back in if we need it |
|
| 794 | - if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) { |
|
| 795 | - $effective_id = $model_object_data[ $model->primary_key_name() ]; |
|
| 796 | - unset($model_object_data[ $model->primary_key_name() ]); |
|
| 797 | - } else { |
|
| 798 | - $effective_id = $model->get_index_primary_key_string($model_object_data); |
|
| 799 | - } |
|
| 800 | - // the model takes care of validating the CSV's input |
|
| 801 | - try { |
|
| 802 | - $new_id = $model->insert($model_object_data); |
|
| 803 | - if ($new_id) { |
|
| 804 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id; |
|
| 805 | - $this->_total_inserts++; |
|
| 806 | - EE_Error::add_success( |
|
| 807 | - sprintf( |
|
| 808 | - __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"), |
|
| 809 | - $model->get_this_model_name(), |
|
| 810 | - $new_id, |
|
| 811 | - implode(",", $model_object_data) |
|
| 812 | - ) |
|
| 813 | - ); |
|
| 814 | - } else { |
|
| 815 | - $this->_total_insert_errors++; |
|
| 816 | - // put the ID used back in there for the error message |
|
| 817 | - if ($model->has_primary_key_field()) { |
|
| 818 | - $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 819 | - } |
|
| 820 | - EE_Error::add_error( |
|
| 821 | - sprintf( |
|
| 822 | - __("Could not insert new %s with the csv data: %s", "event_espresso"), |
|
| 823 | - $model->get_this_model_name(), |
|
| 824 | - http_build_query($model_object_data) |
|
| 825 | - ), |
|
| 826 | - __FILE__, |
|
| 827 | - __FUNCTION__, |
|
| 828 | - __LINE__ |
|
| 829 | - ); |
|
| 830 | - } |
|
| 831 | - } catch (EE_Error $e) { |
|
| 832 | - $this->_total_insert_errors++; |
|
| 833 | - if ($model->has_primary_key_field()) { |
|
| 834 | - $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 835 | - } |
|
| 836 | - EE_Error::add_error( |
|
| 837 | - sprintf( |
|
| 838 | - __("Could not insert new %s with the csv data: %s because %s", "event_espresso"), |
|
| 839 | - $model->get_this_model_name(), |
|
| 840 | - implode(",", $model_object_data), |
|
| 841 | - $e->getMessage() |
|
| 842 | - ), |
|
| 843 | - __FILE__, |
|
| 844 | - __FUNCTION__, |
|
| 845 | - __LINE__ |
|
| 846 | - ); |
|
| 847 | - } |
|
| 848 | - return $old_db_to_new_db_mapping; |
|
| 849 | - } |
|
| 850 | - |
|
| 851 | - /** |
|
| 852 | - * Given the model object data, finds the row to update and updates it |
|
| 853 | - * |
|
| 854 | - * @param string|int $id_in_csv |
|
| 855 | - * @param array $model_object_data |
|
| 856 | - * @param EEM_Base $model |
|
| 857 | - * @param array $old_db_to_new_db_mapping |
|
| 858 | - * @return array updated $old_db_to_new_db_mapping |
|
| 859 | - */ |
|
| 860 | - protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping) |
|
| 861 | - { |
|
| 862 | - try { |
|
| 863 | - // let's keep two copies of the model object data: |
|
| 864 | - // one for performing an update, one for everthing else |
|
| 865 | - $model_object_data_for_update = $model_object_data; |
|
| 866 | - if ($model->has_primary_key_field()) { |
|
| 867 | - $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]); |
|
| 868 | - // remove the primary key because we shouldn't use it for updating |
|
| 869 | - unset($model_object_data_for_update[ $model->primary_key_name() ]); |
|
| 870 | - } elseif ($model->get_combined_primary_key_fields() > 1) { |
|
| 871 | - $conditions = array(); |
|
| 872 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
| 873 | - $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ]; |
|
| 874 | - } |
|
| 875 | - } else { |
|
| 876 | - $model->primary_key_name( |
|
| 877 | - );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey) |
|
| 878 | - } |
|
| 879 | - |
|
| 880 | - $success = $model->update($model_object_data_for_update, array($conditions)); |
|
| 881 | - if ($success) { |
|
| 882 | - $this->_total_updates++; |
|
| 883 | - EE_Error::add_success( |
|
| 884 | - sprintf( |
|
| 885 | - __("Successfully updated %s with csv data %s", "event_espresso"), |
|
| 886 | - $model->get_this_model_name(), |
|
| 887 | - implode(",", $model_object_data_for_update) |
|
| 888 | - ) |
|
| 889 | - ); |
|
| 890 | - // we should still record the mapping even though it was an update |
|
| 891 | - // because if we were going to insert somethign but it was going to conflict |
|
| 892 | - // we would have last-minute decided to update. So we'd like to know what we updated |
|
| 893 | - // and so we record what record ended up being updated using the mapping |
|
| 894 | - if ($model->has_primary_key_field()) { |
|
| 895 | - $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ]; |
|
| 896 | - } else { |
|
| 897 | - // no primary key just a combined key |
|
| 898 | - $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data); |
|
| 899 | - } |
|
| 900 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping; |
|
| 901 | - } else { |
|
| 902 | - $matched_items = $model->get_all(array($conditions)); |
|
| 903 | - if (! $matched_items) { |
|
| 904 | - // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck? |
|
| 905 | - $this->_total_update_errors++; |
|
| 906 | - EE_Error::add_error( |
|
| 907 | - sprintf( |
|
| 908 | - __( |
|
| 909 | - "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)", |
|
| 910 | - "event_espresso" |
|
| 911 | - ), |
|
| 912 | - $model->get_this_model_name(), |
|
| 913 | - http_build_query($model_object_data), |
|
| 914 | - http_build_query($conditions) |
|
| 915 | - ), |
|
| 916 | - __FILE__, |
|
| 917 | - __FUNCTION__, |
|
| 918 | - __LINE__ |
|
| 919 | - ); |
|
| 920 | - } else { |
|
| 921 | - $this->_total_updates++; |
|
| 922 | - EE_Error::add_success( |
|
| 923 | - sprintf( |
|
| 924 | - __( |
|
| 925 | - "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.", |
|
| 926 | - "event_espresso" |
|
| 927 | - ), |
|
| 928 | - $model->get_this_model_name(), |
|
| 929 | - implode(",", $model_object_data) |
|
| 930 | - ) |
|
| 931 | - ); |
|
| 932 | - } |
|
| 933 | - } |
|
| 934 | - } catch (EE_Error $e) { |
|
| 935 | - $this->_total_update_errors++; |
|
| 936 | - $basic_message = sprintf( |
|
| 937 | - __("Could not update %s with the csv data: %s because %s", "event_espresso"), |
|
| 938 | - $model->get_this_model_name(), |
|
| 939 | - implode(",", $model_object_data), |
|
| 940 | - $e->getMessage() |
|
| 941 | - ); |
|
| 942 | - $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString(); |
|
| 943 | - EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__); |
|
| 944 | - } |
|
| 945 | - return $old_db_to_new_db_mapping; |
|
| 946 | - } |
|
| 947 | - |
|
| 948 | - /** |
|
| 949 | - * Gets the number of inserts performed since importer was instantiated or reset |
|
| 950 | - * |
|
| 951 | - * @return int |
|
| 952 | - */ |
|
| 953 | - public function get_total_inserts() |
|
| 954 | - { |
|
| 955 | - return $this->_total_inserts; |
|
| 956 | - } |
|
| 957 | - |
|
| 958 | - /** |
|
| 959 | - * Gets the number of insert errors since importer was instantiated or reset |
|
| 960 | - * |
|
| 961 | - * @return int |
|
| 962 | - */ |
|
| 963 | - public function get_total_insert_errors() |
|
| 964 | - { |
|
| 965 | - return $this->_total_insert_errors; |
|
| 966 | - } |
|
| 967 | - |
|
| 968 | - /** |
|
| 969 | - * Gets the number of updates performed since importer was instantiated or reset |
|
| 970 | - * |
|
| 971 | - * @return int |
|
| 972 | - */ |
|
| 973 | - public function get_total_updates() |
|
| 974 | - { |
|
| 975 | - return $this->_total_updates; |
|
| 976 | - } |
|
| 977 | - |
|
| 978 | - /** |
|
| 979 | - * Gets the number of update errors since importer was instantiated or reset |
|
| 980 | - * |
|
| 981 | - * @return int |
|
| 982 | - */ |
|
| 983 | - public function get_total_update_errors() |
|
| 984 | - { |
|
| 985 | - return $this->_total_update_errors; |
|
| 986 | - } |
|
| 125 | + $uploader = ob_get_clean(); |
|
| 126 | + return $uploader; |
|
| 127 | + } |
|
| 128 | + |
|
| 129 | + |
|
| 130 | + /** |
|
| 131 | + * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php |
|
| 132 | + * @access public |
|
| 133 | + * @return boolean success |
|
| 134 | + */ |
|
| 135 | + public function import() |
|
| 136 | + { |
|
| 137 | + |
|
| 138 | + require_once(EE_CLASSES . 'EE_CSV.class.php'); |
|
| 139 | + $this->EE_CSV = EE_CSV::instance(); |
|
| 140 | + |
|
| 141 | + if (isset($_REQUEST['import'])) { |
|
| 142 | + if (isset($_POST['csv_submitted'])) { |
|
| 143 | + switch ($_FILES['file']['error'][0]) { |
|
| 144 | + case UPLOAD_ERR_OK: |
|
| 145 | + $error_msg = false; |
|
| 146 | + break; |
|
| 147 | + case UPLOAD_ERR_INI_SIZE: |
|
| 148 | + $error_msg = __( |
|
| 149 | + "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'", |
|
| 150 | + "event_espresso" |
|
| 151 | + ); |
|
| 152 | + break; |
|
| 153 | + case UPLOAD_ERR_FORM_SIZE: |
|
| 154 | + $error_msg = __( |
|
| 155 | + 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', |
|
| 156 | + "event_espresso" |
|
| 157 | + ); |
|
| 158 | + break; |
|
| 159 | + case UPLOAD_ERR_PARTIAL: |
|
| 160 | + $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso"); |
|
| 161 | + break; |
|
| 162 | + case UPLOAD_ERR_NO_FILE: |
|
| 163 | + $error_msg = __('No file was uploaded.', "event_espresso"); |
|
| 164 | + break; |
|
| 165 | + case UPLOAD_ERR_NO_TMP_DIR: |
|
| 166 | + $error_msg = __('Missing a temporary folder.', "event_espresso"); |
|
| 167 | + break; |
|
| 168 | + case UPLOAD_ERR_CANT_WRITE: |
|
| 169 | + $error_msg = __('Failed to write file to disk.', "event_espresso"); |
|
| 170 | + break; |
|
| 171 | + case UPLOAD_ERR_EXTENSION: |
|
| 172 | + $error_msg = __('File upload stopped by extension.', "event_espresso"); |
|
| 173 | + break; |
|
| 174 | + default: |
|
| 175 | + $error_msg = __( |
|
| 176 | + 'An unknown error occurred and the file could not be uploaded', |
|
| 177 | + "event_espresso" |
|
| 178 | + ); |
|
| 179 | + break; |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + if (! $error_msg) { |
|
| 183 | + $filename = $_FILES['file']['name'][0]; |
|
| 184 | + $file_ext = substr(strrchr($filename, '.'), 1); |
|
| 185 | + $file_type = $_FILES['file']['type'][0]; |
|
| 186 | + $temp_file = $_FILES['file']['tmp_name'][0]; |
|
| 187 | + $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB |
|
| 188 | + |
|
| 189 | + if ($file_ext == 'csv') { |
|
| 190 | + $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB |
|
| 191 | + if ($filesize < $max_upload || true) { |
|
| 192 | + $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir()); |
|
| 193 | + $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename; |
|
| 194 | + |
|
| 195 | + if (move_uploaded_file($temp_file, $path_to_file)) { |
|
| 196 | + // convert csv to array |
|
| 197 | + $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file); |
|
| 198 | + |
|
| 199 | + // was data successfully stored in an array? |
|
| 200 | + if (is_array($this->csv_array)) { |
|
| 201 | + $import_what = str_replace('csv_import_', '', $_REQUEST['action']); |
|
| 202 | + $import_what = str_replace('_', ' ', ucwords($import_what)); |
|
| 203 | + $processed_data = $this->csv_array; |
|
| 204 | + $this->columns_to_save = false; |
|
| 205 | + |
|
| 206 | + // if any imports require funcky processing, we'll catch them in the switch |
|
| 207 | + switch ($_REQUEST['action']) { |
|
| 208 | + case "import_events": |
|
| 209 | + case "event_list": |
|
| 210 | + $import_what = 'Event Details'; |
|
| 211 | + break; |
|
| 212 | + |
|
| 213 | + case 'groupon_import_csv': |
|
| 214 | + $import_what = 'Groupon Codes'; |
|
| 215 | + $processed_data = $this->process_groupon_codes(); |
|
| 216 | + break; |
|
| 217 | + } |
|
| 218 | + // save processed codes to db |
|
| 219 | + if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) { |
|
| 220 | + return true; |
|
| 221 | + } |
|
| 222 | + } else { |
|
| 223 | + // no array? must be an error |
|
| 224 | + EE_Error::add_error( |
|
| 225 | + sprintf(__("No file seems to have been uploaded", "event_espresso")), |
|
| 226 | + __FILE__, |
|
| 227 | + __FUNCTION__, |
|
| 228 | + __LINE__ |
|
| 229 | + ); |
|
| 230 | + return false; |
|
| 231 | + } |
|
| 232 | + } else { |
|
| 233 | + EE_Error::add_error( |
|
| 234 | + sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename), |
|
| 235 | + __FILE__, |
|
| 236 | + __FUNCTION__, |
|
| 237 | + __LINE__ |
|
| 238 | + ); |
|
| 239 | + return false; |
|
| 240 | + } |
|
| 241 | + } else { |
|
| 242 | + EE_Error::add_error( |
|
| 243 | + sprintf( |
|
| 244 | + __( |
|
| 245 | + "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.", |
|
| 246 | + "event_espresso" |
|
| 247 | + ), |
|
| 248 | + $filename, |
|
| 249 | + $max_upload |
|
| 250 | + ), |
|
| 251 | + __FILE__, |
|
| 252 | + __FUNCTION__, |
|
| 253 | + __LINE__ |
|
| 254 | + ); |
|
| 255 | + return false; |
|
| 256 | + } |
|
| 257 | + } else { |
|
| 258 | + EE_Error::add_error( |
|
| 259 | + sprintf(__("%s had an invalid file extension, not uploaded", "event_espresso"), $filename), |
|
| 260 | + __FILE__, |
|
| 261 | + __FUNCTION__, |
|
| 262 | + __LINE__ |
|
| 263 | + ); |
|
| 264 | + return false; |
|
| 265 | + } |
|
| 266 | + } else { |
|
| 267 | + EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 268 | + return false; |
|
| 269 | + } |
|
| 270 | + } |
|
| 271 | + } |
|
| 272 | + return; |
|
| 273 | + } |
|
| 274 | + |
|
| 275 | + |
|
| 276 | + /** |
|
| 277 | + * Given an array of data (usually from a CSV import) attempts to save that data to the db. |
|
| 278 | + * If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names, |
|
| 279 | + * next level being numeric indexes adn each value representing a model object, and the last layer down |
|
| 280 | + * being keys of model fields and their proposed values. |
|
| 281 | + * If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned. |
|
| 282 | + * If the CSV data says (in the metadata row) that it's from the SAME database, |
|
| 283 | + * we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those |
|
| 284 | + * IDs DON'T exist in the database, they're treated as temporary IDs, |
|
| 285 | + * which can used elsewhere to refer to the same object. Once an item |
|
| 286 | + * with a temporary ID gets inserted, we record its mapping from temporary |
|
| 287 | + * ID to real ID, and use the real ID in place of the temporary ID |
|
| 288 | + * when that temporary ID was used as a foreign key. |
|
| 289 | + * If the CSV data says (in the metadata again) that it's from a DIFFERENT database, |
|
| 290 | + * we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with |
|
| 291 | + * ID 1, and the database already has an event with ID 1, we assume that's just a coincidence, |
|
| 292 | + * and insert a new event, and map it's temporary ID of 1 over to its new real ID. |
|
| 293 | + * An important exception are non-auto-increment primary keys. If one entry in the |
|
| 294 | + * CSV file has the same ID as one in the DB, we assume they are meant to be |
|
| 295 | + * the same item, and instead update the item in the DB with that same ID. |
|
| 296 | + * Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th |
|
| 297 | + * time you import a CSV from a different site, we remember their mappings, and |
|
| 298 | + * will try to update the item in the DB instead of inserting another item (eg |
|
| 299 | + * if we previously imported an event with temporary ID 1, and then it got a |
|
| 300 | + * real ID of 123, we remember that. So the next time we import an event with |
|
| 301 | + * temporary ID, from the same site, we know that it's real ID is 123, and will |
|
| 302 | + * update that event, instead of adding a new event). |
|
| 303 | + * |
|
| 304 | + * @access public |
|
| 305 | + * @param array $csv_data_array - the array containing the csv data produced from |
|
| 306 | + * EE_CSV::import_csv_to_model_data_array() |
|
| 307 | + * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table |
|
| 308 | + * fields they will be saved to |
|
| 309 | + * @return TRUE on success, FALSE on fail |
|
| 310 | + * @throws \EE_Error |
|
| 311 | + */ |
|
| 312 | + public function save_csv_data_array_to_db($csv_data_array, $model_name = false) |
|
| 313 | + { |
|
| 314 | + $success = false; |
|
| 315 | + $error = false; |
|
| 316 | + // whther to treat this import as if it's data froma different database or not |
|
| 317 | + // ie, if it IS from a different database, ignore foreign keys whihf |
|
| 318 | + $export_from_site_a_to_b = true; |
|
| 319 | + // first level of array is not table information but a table name was passed to the function |
|
| 320 | + // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail |
|
| 321 | + if ($model_name) { |
|
| 322 | + $csv_data_array = array($csv_data_array); |
|
| 323 | + } |
|
| 324 | + // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name... |
|
| 325 | + $old_site_url = 'none-specified'; |
|
| 326 | + // hanlde metadata |
|
| 327 | + if (isset($csv_data_array[ EE_CSV::metadata_header ])) { |
|
| 328 | + $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 329 | + // ok so its metadata, dont try to save it to ehte db obviously... |
|
| 330 | + if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) { |
|
| 331 | + EE_Error::add_attention( |
|
| 332 | + sprintf( |
|
| 333 | + __( |
|
| 334 | + "CSV Data appears to be from the same database, so attempting to update data", |
|
| 335 | + "event_espresso" |
|
| 336 | + ) |
|
| 337 | + ) |
|
| 338 | + ); |
|
| 339 | + $export_from_site_a_to_b = false; |
|
| 340 | + } else { |
|
| 341 | + $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url; |
|
| 342 | + EE_Error::add_attention( |
|
| 343 | + sprintf( |
|
| 344 | + __( |
|
| 345 | + "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database", |
|
| 346 | + "event_espresso" |
|
| 347 | + ), |
|
| 348 | + $old_site_url, |
|
| 349 | + site_url() |
|
| 350 | + ) |
|
| 351 | + ); |
|
| 352 | + }; |
|
| 353 | + unset($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 354 | + } |
|
| 355 | + /** |
|
| 356 | + * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and |
|
| 357 | + * the value will be the newly-inserted ID. |
|
| 358 | + * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option |
|
| 359 | + */ |
|
| 360 | + $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array()); |
|
| 361 | + if ($old_db_to_new_db_mapping) { |
|
| 362 | + EE_Error::add_attention( |
|
| 363 | + sprintf( |
|
| 364 | + __( |
|
| 365 | + "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s", |
|
| 366 | + "event_espresso" |
|
| 367 | + ), |
|
| 368 | + $old_site_url, |
|
| 369 | + site_url() |
|
| 370 | + ) |
|
| 371 | + ); |
|
| 372 | + } |
|
| 373 | + $old_db_to_new_db_mapping = $this->save_data_rows_to_db( |
|
| 374 | + $csv_data_array, |
|
| 375 | + $export_from_site_a_to_b, |
|
| 376 | + $old_db_to_new_db_mapping |
|
| 377 | + ); |
|
| 378 | + |
|
| 379 | + // save the mapping from old db to new db in case they try re-importing the same data from the same website again |
|
| 380 | + update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping); |
|
| 381 | + |
|
| 382 | + if ($this->_total_updates > 0) { |
|
| 383 | + EE_Error::add_success( |
|
| 384 | + sprintf( |
|
| 385 | + __("%s existing records in the database were updated.", "event_espresso"), |
|
| 386 | + $this->_total_updates |
|
| 387 | + ) |
|
| 388 | + ); |
|
| 389 | + $success = true; |
|
| 390 | + } |
|
| 391 | + if ($this->_total_inserts > 0) { |
|
| 392 | + EE_Error::add_success( |
|
| 393 | + sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts) |
|
| 394 | + ); |
|
| 395 | + $success = true; |
|
| 396 | + } |
|
| 397 | + |
|
| 398 | + if ($this->_total_update_errors > 0) { |
|
| 399 | + EE_Error::add_error( |
|
| 400 | + sprintf( |
|
| 401 | + __( |
|
| 402 | + "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'", |
|
| 403 | + "event_espresso" |
|
| 404 | + ), |
|
| 405 | + $this->_total_update_errors |
|
| 406 | + ), |
|
| 407 | + __FILE__, |
|
| 408 | + __FUNCTION__, |
|
| 409 | + __LINE__ |
|
| 410 | + ); |
|
| 411 | + $error = true; |
|
| 412 | + } |
|
| 413 | + if ($this->_total_insert_errors > 0) { |
|
| 414 | + EE_Error::add_error( |
|
| 415 | + sprintf( |
|
| 416 | + __( |
|
| 417 | + "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'", |
|
| 418 | + "event_espresso" |
|
| 419 | + ), |
|
| 420 | + $this->_total_insert_errors |
|
| 421 | + ), |
|
| 422 | + __FILE__, |
|
| 423 | + __FUNCTION__, |
|
| 424 | + __LINE__ |
|
| 425 | + ); |
|
| 426 | + $error = true; |
|
| 427 | + } |
|
| 428 | + |
|
| 429 | + // lastly, we need to update the datetime and ticket sold amounts |
|
| 430 | + // as those may have been affected by this |
|
| 431 | + EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all()); |
|
| 432 | + |
|
| 433 | + // if there was at least one success and absolutely no errors |
|
| 434 | + if ($success && ! $error) { |
|
| 435 | + return true; |
|
| 436 | + } else { |
|
| 437 | + return false; |
|
| 438 | + } |
|
| 439 | + } |
|
| 440 | + |
|
| 441 | + |
|
| 442 | + /** |
|
| 443 | + * Processes the array of data, given the knowledge that it's from the same database or a different one, |
|
| 444 | + * and the mapping from temporary IDs to real IDs. |
|
| 445 | + * If the data is from a different database, we treat the primary keys and their corresponding |
|
| 446 | + * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys |
|
| 447 | + * in the real target database. As items are inserted, their temporary primary keys |
|
| 448 | + * are mapped to the real IDs in the target database. Also, before doing any update or |
|
| 449 | + * insert, we replace all the temp ID which are foreign keys with their mapped real IDs. |
|
| 450 | + * An exception: string primary keys are treated as real IDs, or else we'd need to |
|
| 451 | + * dynamically generate new string primary keys which would be very awkard for the country table etc. |
|
| 452 | + * Also, models with no primary key are strange too. We combine use their primar key INDEX (a |
|
| 453 | + * combination of fields) to create a unique string identifying the row and store |
|
| 454 | + * those in the mapping. |
|
| 455 | + * |
|
| 456 | + * If the data is from the same database, we usually treat primary keys as real IDs. |
|
| 457 | + * An exception is if there is nothing in the database for that ID. If that's the case, |
|
| 458 | + * we need to insert a new row for that ID, and then map from the non-existent ID |
|
| 459 | + * to the newly-inserted real ID. |
|
| 460 | + * |
|
| 461 | + * @param type $csv_data_array |
|
| 462 | + * @param type $export_from_site_a_to_b |
|
| 463 | + * @param type $old_db_to_new_db_mapping |
|
| 464 | + * @return array updated $old_db_to_new_db_mapping |
|
| 465 | + */ |
|
| 466 | + public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping) |
|
| 467 | + { |
|
| 468 | + foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) { |
|
| 469 | + // now check that assumption was correct. If |
|
| 470 | + if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) { |
|
| 471 | + $model_name = $model_name_in_csv_data; |
|
| 472 | + } else { |
|
| 473 | + // no table info in the array and no table name passed to the function?? FAIL |
|
| 474 | + EE_Error::add_error( |
|
| 475 | + __( |
|
| 476 | + 'No table information was specified and/or found, therefore the import could not be completed', |
|
| 477 | + 'event_espresso' |
|
| 478 | + ), |
|
| 479 | + __FILE__, |
|
| 480 | + __FUNCTION__, |
|
| 481 | + __LINE__ |
|
| 482 | + ); |
|
| 483 | + return false; |
|
| 484 | + } |
|
| 485 | + /* @var $model EEM_Base */ |
|
| 486 | + $model = EE_Registry::instance()->load_model($model_name); |
|
| 487 | + |
|
| 488 | + // so without further ado, scanning all the data provided for primary keys and their inital values |
|
| 489 | + foreach ($model_data_from_import as $model_object_data) { |
|
| 490 | + // before we do ANYTHING, make sure the csv row wasn't just completely blank |
|
| 491 | + $row_is_completely_empty = true; |
|
| 492 | + foreach ($model_object_data as $field) { |
|
| 493 | + if ($field) { |
|
| 494 | + $row_is_completely_empty = false; |
|
| 495 | + } |
|
| 496 | + } |
|
| 497 | + if ($row_is_completely_empty) { |
|
| 498 | + continue; |
|
| 499 | + } |
|
| 500 | + // find the PK in the row of data (or a combined key if |
|
| 501 | + // there is no primary key) |
|
| 502 | + if ($model->has_primary_key_field()) { |
|
| 503 | + $id_in_csv = $model_object_data[ $model->primary_key_name() ]; |
|
| 504 | + } else { |
|
| 505 | + $id_in_csv = $model->get_index_primary_key_string($model_object_data); |
|
| 506 | + } |
|
| 507 | + |
|
| 508 | + |
|
| 509 | + $model_object_data = $this->_replace_temp_ids_with_mappings( |
|
| 510 | + $model_object_data, |
|
| 511 | + $model, |
|
| 512 | + $old_db_to_new_db_mapping, |
|
| 513 | + $export_from_site_a_to_b |
|
| 514 | + ); |
|
| 515 | + // now we need to decide if we're going to add a new model object given the $model_object_data, |
|
| 516 | + // or just update. |
|
| 517 | + if ($export_from_site_a_to_b) { |
|
| 518 | + $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db( |
|
| 519 | + $id_in_csv, |
|
| 520 | + $model_object_data, |
|
| 521 | + $model, |
|
| 522 | + $old_db_to_new_db_mapping |
|
| 523 | + ); |
|
| 524 | + } else {// this is just a re-import |
|
| 525 | + $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db( |
|
| 526 | + $id_in_csv, |
|
| 527 | + $model_object_data, |
|
| 528 | + $model, |
|
| 529 | + $old_db_to_new_db_mapping |
|
| 530 | + ); |
|
| 531 | + } |
|
| 532 | + if ($what_to_do == self::do_nothing) { |
|
| 533 | + continue; |
|
| 534 | + } |
|
| 535 | + |
|
| 536 | + // double-check we actually want to insert, if that's what we're planning |
|
| 537 | + // based on whether this item would be unique in the DB or not |
|
| 538 | + if ($what_to_do == self::do_insert) { |
|
| 539 | + // we're supposed to be inserting. But wait, will this thing |
|
| 540 | + // be acceptable if inserted? |
|
| 541 | + $conflicting = $model->get_one_conflicting($model_object_data, false); |
|
| 542 | + if ($conflicting) { |
|
| 543 | + // ok, this item would conflict if inserted. Just update the item that it conflicts with. |
|
| 544 | + $what_to_do = self::do_update; |
|
| 545 | + // and if this model has a primary key, remember its mapping |
|
| 546 | + if ($model->has_primary_key_field()) { |
|
| 547 | + $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID(); |
|
| 548 | + $model_object_data[ $model->primary_key_name() ] = $conflicting->ID(); |
|
| 549 | + } else { |
|
| 550 | + // we want to update this conflicting item, instead of inserting a conflicting item |
|
| 551 | + // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields |
|
| 552 | + // for the WHERE conditions in the update). At the time of this comment, there were no models like this |
|
| 553 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
| 554 | + $model_object_data[ $key_field->get_name() ] = $conflicting->get( |
|
| 555 | + $key_field->get_name() |
|
| 556 | + ); |
|
| 557 | + } |
|
| 558 | + } |
|
| 559 | + } |
|
| 560 | + } |
|
| 561 | + if ($what_to_do == self::do_insert) { |
|
| 562 | + $old_db_to_new_db_mapping = $this->_insert_from_data_array( |
|
| 563 | + $id_in_csv, |
|
| 564 | + $model_object_data, |
|
| 565 | + $model, |
|
| 566 | + $old_db_to_new_db_mapping |
|
| 567 | + ); |
|
| 568 | + } elseif ($what_to_do == self::do_update) { |
|
| 569 | + $old_db_to_new_db_mapping = $this->_update_from_data_array( |
|
| 570 | + $id_in_csv, |
|
| 571 | + $model_object_data, |
|
| 572 | + $model, |
|
| 573 | + $old_db_to_new_db_mapping |
|
| 574 | + ); |
|
| 575 | + } else { |
|
| 576 | + throw new EE_Error( |
|
| 577 | + sprintf( |
|
| 578 | + __( |
|
| 579 | + 'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid', |
|
| 580 | + 'event_espresso' |
|
| 581 | + ), |
|
| 582 | + $what_to_do |
|
| 583 | + ) |
|
| 584 | + ); |
|
| 585 | + } |
|
| 586 | + } |
|
| 587 | + } |
|
| 588 | + return $old_db_to_new_db_mapping; |
|
| 589 | + } |
|
| 590 | + |
|
| 591 | + |
|
| 592 | + /** |
|
| 593 | + * Decides whether or not to insert, given that this data is from another database. |
|
| 594 | + * So, if the primary key of this $model_object_data already exists in the database, |
|
| 595 | + * it's just a coincidence and we should still insert. The only time we should |
|
| 596 | + * update is when we know what it maps to, or there's something that would |
|
| 597 | + * conflict (and we should instead just update that conflicting thing) |
|
| 598 | + * |
|
| 599 | + * @param string $id_in_csv |
|
| 600 | + * @param array $model_object_data by reference so it can be modified |
|
| 601 | + * @param EEM_Base $model |
|
| 602 | + * @param array $old_db_to_new_db_mapping by reference so it can be modified |
|
| 603 | + * @return string one of the consts on this class that starts with do_* |
|
| 604 | + */ |
|
| 605 | + protected function _decide_whether_to_insert_or_update_given_data_from_other_db( |
|
| 606 | + $id_in_csv, |
|
| 607 | + $model_object_data, |
|
| 608 | + $model, |
|
| 609 | + $old_db_to_new_db_mapping |
|
| 610 | + ) { |
|
| 611 | + $model_name = $model->get_this_model_name(); |
|
| 612 | + // if it's a site-to-site export-and-import, see if this modelobject's id |
|
| 613 | + // in the old data that we know of |
|
| 614 | + if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) { |
|
| 615 | + return self::do_update; |
|
| 616 | + } else { |
|
| 617 | + return self::do_insert; |
|
| 618 | + } |
|
| 619 | + } |
|
| 620 | + |
|
| 621 | + /** |
|
| 622 | + * If this thing basically already exists in the database, we want to update it; |
|
| 623 | + * otherwise insert it (ie, someone tweaked the CSV file, or the item was |
|
| 624 | + * deleted in the database so it should be re-inserted) |
|
| 625 | + * |
|
| 626 | + * @param type $id_in_csv |
|
| 627 | + * @param type $model_object_data |
|
| 628 | + * @param EEM_Base $model |
|
| 629 | + * @param type $old_db_to_new_db_mapping |
|
| 630 | + * @return |
|
| 631 | + */ |
|
| 632 | + protected function _decide_whether_to_insert_or_update_given_data_from_same_db( |
|
| 633 | + $id_in_csv, |
|
| 634 | + $model_object_data, |
|
| 635 | + $model |
|
| 636 | + ) { |
|
| 637 | + // in this case, check if this thing ACTUALLY exists in the database |
|
| 638 | + if ($model->get_one_conflicting($model_object_data)) { |
|
| 639 | + return self::do_update; |
|
| 640 | + } else { |
|
| 641 | + return self::do_insert; |
|
| 642 | + } |
|
| 643 | + } |
|
| 644 | + |
|
| 645 | + /** |
|
| 646 | + * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs |
|
| 647 | + * with their mapped real IDs. Eg, if importing from site A to B, the mapping |
|
| 648 | + * file may indicate that the ID "my_event_id" maps to an actual event ID of 123. |
|
| 649 | + * So this function searches for any event temp Ids called "my_event_id" and |
|
| 650 | + * replaces them with 123. |
|
| 651 | + * Also, if there is no temp ID for the INT foreign keys from another database, |
|
| 652 | + * replaces them with 0 or the field's default. |
|
| 653 | + * |
|
| 654 | + * @param type $model_object_data |
|
| 655 | + * @param EEM_Base $model |
|
| 656 | + * @param type $old_db_to_new_db_mapping |
|
| 657 | + * @param boolean $export_from_site_a_to_b |
|
| 658 | + * @return array updated model object data with temp IDs removed |
|
| 659 | + */ |
|
| 660 | + protected function _replace_temp_ids_with_mappings( |
|
| 661 | + $model_object_data, |
|
| 662 | + $model, |
|
| 663 | + $old_db_to_new_db_mapping, |
|
| 664 | + $export_from_site_a_to_b |
|
| 665 | + ) { |
|
| 666 | + // if this model object's primary key is in the mapping, replace it |
|
| 667 | + if ($model->has_primary_key_field() && |
|
| 668 | + $model->get_primary_key_field()->is_auto_increment() && |
|
| 669 | + isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) && |
|
| 670 | + isset( |
|
| 671 | + $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ] |
|
| 672 | + )) { |
|
| 673 | + $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name( |
|
| 674 | + ) ][ $model_object_data[ $model->primary_key_name() ] ]; |
|
| 675 | + } |
|
| 676 | + |
|
| 677 | + try { |
|
| 678 | + $model_name_field = $model->get_field_containing_related_model_name(); |
|
| 679 | + $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to(); |
|
| 680 | + } catch (EE_Error $e) { |
|
| 681 | + $model_name_field = null; |
|
| 682 | + $models_pointed_to_by_model_name_field = array(); |
|
| 683 | + } |
|
| 684 | + foreach ($model->field_settings(true) as $field_obj) { |
|
| 685 | + if ($field_obj instanceof EE_Foreign_Key_Int_Field) { |
|
| 686 | + $models_pointed_to = $field_obj->get_model_names_pointed_to(); |
|
| 687 | + $found_a_mapping = false; |
|
| 688 | + foreach ($models_pointed_to as $model_pointed_to_by_fk) { |
|
| 689 | + if ($model_name_field) { |
|
| 690 | + $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ]; |
|
| 691 | + if ($value_of_model_name_field == $model_pointed_to_by_fk) { |
|
| 692 | + $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 693 | + $model_object_data[ $field_obj->get_name() ], |
|
| 694 | + $model_pointed_to_by_fk, |
|
| 695 | + $old_db_to_new_db_mapping, |
|
| 696 | + $export_from_site_a_to_b |
|
| 697 | + ); |
|
| 698 | + $found_a_mapping = true; |
|
| 699 | + break; |
|
| 700 | + } |
|
| 701 | + } else { |
|
| 702 | + $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 703 | + $model_object_data[ $field_obj->get_name() ], |
|
| 704 | + $model_pointed_to_by_fk, |
|
| 705 | + $old_db_to_new_db_mapping, |
|
| 706 | + $export_from_site_a_to_b |
|
| 707 | + ); |
|
| 708 | + $found_a_mapping = true; |
|
| 709 | + } |
|
| 710 | + // once we've found a mapping for this field no need to continue |
|
| 711 | + if ($found_a_mapping) { |
|
| 712 | + break; |
|
| 713 | + } |
|
| 714 | + } |
|
| 715 | + } else { |
|
| 716 | + // it's a string foreign key (which we leave alone, because those are things |
|
| 717 | + // like country names, which we'd really rather not make 2 USAs etc (we'd actually |
|
| 718 | + // prefer to just update one) |
|
| 719 | + // or it's just a regular value that ought to be replaced |
|
| 720 | + } |
|
| 721 | + } |
|
| 722 | + // |
|
| 723 | + if ($model instanceof EEM_Term_Taxonomy) { |
|
| 724 | + $model_object_data = $this->_handle_split_term_ids($model_object_data); |
|
| 725 | + } |
|
| 726 | + return $model_object_data; |
|
| 727 | + } |
|
| 728 | + |
|
| 729 | + /** |
|
| 730 | + * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id |
|
| 731 | + * this term-taxonomy refers to may be out-of-date so we need to update it. |
|
| 732 | + * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/ |
|
| 733 | + * |
|
| 734 | + * @param type $model_object_data |
|
| 735 | + * @return array new model object data |
|
| 736 | + */ |
|
| 737 | + protected function _handle_split_term_ids($model_object_data) |
|
| 738 | + { |
|
| 739 | + if (isset($model_object_data['term_id']) |
|
| 740 | + && isset($model_object_data['taxonomy']) |
|
| 741 | + && apply_filters( |
|
| 742 | + 'FHEE__EE_Import__handle_split_term_ids__function_exists', |
|
| 743 | + function_exists('wp_get_split_term'), |
|
| 744 | + $model_object_data |
|
| 745 | + )) { |
|
| 746 | + $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']); |
|
| 747 | + if ($new_term_id) { |
|
| 748 | + $model_object_data['term_id'] = $new_term_id; |
|
| 749 | + } |
|
| 750 | + } |
|
| 751 | + return $model_object_data; |
|
| 752 | + } |
|
| 753 | + |
|
| 754 | + /** |
|
| 755 | + * Given the object's ID and its model's name, find it int he mapping data, |
|
| 756 | + * bearing in mind where it came from |
|
| 757 | + * |
|
| 758 | + * @param type $object_id |
|
| 759 | + * @param string $model_name |
|
| 760 | + * @param array $old_db_to_new_db_mapping |
|
| 761 | + * @param type $export_from_site_a_to_b |
|
| 762 | + * @return int |
|
| 763 | + */ |
|
| 764 | + protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b) |
|
| 765 | + { |
|
| 766 | + if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) { |
|
| 767 | + return $old_db_to_new_db_mapping[ $model_name ][ $object_id ]; |
|
| 768 | + } elseif ($object_id == '0' || $object_id == '') { |
|
| 769 | + // leave as-is |
|
| 770 | + return $object_id; |
|
| 771 | + } elseif ($export_from_site_a_to_b) { |
|
| 772 | + // we couldn't find a mapping for this, and it's from a different site, |
|
| 773 | + // so blank it out |
|
| 774 | + return null; |
|
| 775 | + } elseif (! $export_from_site_a_to_b) { |
|
| 776 | + // we coudln't find a mapping for this, but it's from thsi DB anyway |
|
| 777 | + // so let's just leave it as-is |
|
| 778 | + return $object_id; |
|
| 779 | + } |
|
| 780 | + } |
|
| 781 | + |
|
| 782 | + /** |
|
| 783 | + * |
|
| 784 | + * @param type $id_in_csv |
|
| 785 | + * @param type $model_object_data |
|
| 786 | + * @param EEM_Base $model |
|
| 787 | + * @param type $old_db_to_new_db_mapping |
|
| 788 | + * @return array updated $old_db_to_new_db_mapping |
|
| 789 | + */ |
|
| 790 | + protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping) |
|
| 791 | + { |
|
| 792 | + // remove the primary key, if there is one (we don't want it for inserts OR updates) |
|
| 793 | + // we'll put it back in if we need it |
|
| 794 | + if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) { |
|
| 795 | + $effective_id = $model_object_data[ $model->primary_key_name() ]; |
|
| 796 | + unset($model_object_data[ $model->primary_key_name() ]); |
|
| 797 | + } else { |
|
| 798 | + $effective_id = $model->get_index_primary_key_string($model_object_data); |
|
| 799 | + } |
|
| 800 | + // the model takes care of validating the CSV's input |
|
| 801 | + try { |
|
| 802 | + $new_id = $model->insert($model_object_data); |
|
| 803 | + if ($new_id) { |
|
| 804 | + $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id; |
|
| 805 | + $this->_total_inserts++; |
|
| 806 | + EE_Error::add_success( |
|
| 807 | + sprintf( |
|
| 808 | + __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"), |
|
| 809 | + $model->get_this_model_name(), |
|
| 810 | + $new_id, |
|
| 811 | + implode(",", $model_object_data) |
|
| 812 | + ) |
|
| 813 | + ); |
|
| 814 | + } else { |
|
| 815 | + $this->_total_insert_errors++; |
|
| 816 | + // put the ID used back in there for the error message |
|
| 817 | + if ($model->has_primary_key_field()) { |
|
| 818 | + $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 819 | + } |
|
| 820 | + EE_Error::add_error( |
|
| 821 | + sprintf( |
|
| 822 | + __("Could not insert new %s with the csv data: %s", "event_espresso"), |
|
| 823 | + $model->get_this_model_name(), |
|
| 824 | + http_build_query($model_object_data) |
|
| 825 | + ), |
|
| 826 | + __FILE__, |
|
| 827 | + __FUNCTION__, |
|
| 828 | + __LINE__ |
|
| 829 | + ); |
|
| 830 | + } |
|
| 831 | + } catch (EE_Error $e) { |
|
| 832 | + $this->_total_insert_errors++; |
|
| 833 | + if ($model->has_primary_key_field()) { |
|
| 834 | + $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 835 | + } |
|
| 836 | + EE_Error::add_error( |
|
| 837 | + sprintf( |
|
| 838 | + __("Could not insert new %s with the csv data: %s because %s", "event_espresso"), |
|
| 839 | + $model->get_this_model_name(), |
|
| 840 | + implode(",", $model_object_data), |
|
| 841 | + $e->getMessage() |
|
| 842 | + ), |
|
| 843 | + __FILE__, |
|
| 844 | + __FUNCTION__, |
|
| 845 | + __LINE__ |
|
| 846 | + ); |
|
| 847 | + } |
|
| 848 | + return $old_db_to_new_db_mapping; |
|
| 849 | + } |
|
| 850 | + |
|
| 851 | + /** |
|
| 852 | + * Given the model object data, finds the row to update and updates it |
|
| 853 | + * |
|
| 854 | + * @param string|int $id_in_csv |
|
| 855 | + * @param array $model_object_data |
|
| 856 | + * @param EEM_Base $model |
|
| 857 | + * @param array $old_db_to_new_db_mapping |
|
| 858 | + * @return array updated $old_db_to_new_db_mapping |
|
| 859 | + */ |
|
| 860 | + protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping) |
|
| 861 | + { |
|
| 862 | + try { |
|
| 863 | + // let's keep two copies of the model object data: |
|
| 864 | + // one for performing an update, one for everthing else |
|
| 865 | + $model_object_data_for_update = $model_object_data; |
|
| 866 | + if ($model->has_primary_key_field()) { |
|
| 867 | + $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]); |
|
| 868 | + // remove the primary key because we shouldn't use it for updating |
|
| 869 | + unset($model_object_data_for_update[ $model->primary_key_name() ]); |
|
| 870 | + } elseif ($model->get_combined_primary_key_fields() > 1) { |
|
| 871 | + $conditions = array(); |
|
| 872 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
| 873 | + $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ]; |
|
| 874 | + } |
|
| 875 | + } else { |
|
| 876 | + $model->primary_key_name( |
|
| 877 | + );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey) |
|
| 878 | + } |
|
| 879 | + |
|
| 880 | + $success = $model->update($model_object_data_for_update, array($conditions)); |
|
| 881 | + if ($success) { |
|
| 882 | + $this->_total_updates++; |
|
| 883 | + EE_Error::add_success( |
|
| 884 | + sprintf( |
|
| 885 | + __("Successfully updated %s with csv data %s", "event_espresso"), |
|
| 886 | + $model->get_this_model_name(), |
|
| 887 | + implode(",", $model_object_data_for_update) |
|
| 888 | + ) |
|
| 889 | + ); |
|
| 890 | + // we should still record the mapping even though it was an update |
|
| 891 | + // because if we were going to insert somethign but it was going to conflict |
|
| 892 | + // we would have last-minute decided to update. So we'd like to know what we updated |
|
| 893 | + // and so we record what record ended up being updated using the mapping |
|
| 894 | + if ($model->has_primary_key_field()) { |
|
| 895 | + $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ]; |
|
| 896 | + } else { |
|
| 897 | + // no primary key just a combined key |
|
| 898 | + $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data); |
|
| 899 | + } |
|
| 900 | + $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping; |
|
| 901 | + } else { |
|
| 902 | + $matched_items = $model->get_all(array($conditions)); |
|
| 903 | + if (! $matched_items) { |
|
| 904 | + // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck? |
|
| 905 | + $this->_total_update_errors++; |
|
| 906 | + EE_Error::add_error( |
|
| 907 | + sprintf( |
|
| 908 | + __( |
|
| 909 | + "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)", |
|
| 910 | + "event_espresso" |
|
| 911 | + ), |
|
| 912 | + $model->get_this_model_name(), |
|
| 913 | + http_build_query($model_object_data), |
|
| 914 | + http_build_query($conditions) |
|
| 915 | + ), |
|
| 916 | + __FILE__, |
|
| 917 | + __FUNCTION__, |
|
| 918 | + __LINE__ |
|
| 919 | + ); |
|
| 920 | + } else { |
|
| 921 | + $this->_total_updates++; |
|
| 922 | + EE_Error::add_success( |
|
| 923 | + sprintf( |
|
| 924 | + __( |
|
| 925 | + "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.", |
|
| 926 | + "event_espresso" |
|
| 927 | + ), |
|
| 928 | + $model->get_this_model_name(), |
|
| 929 | + implode(",", $model_object_data) |
|
| 930 | + ) |
|
| 931 | + ); |
|
| 932 | + } |
|
| 933 | + } |
|
| 934 | + } catch (EE_Error $e) { |
|
| 935 | + $this->_total_update_errors++; |
|
| 936 | + $basic_message = sprintf( |
|
| 937 | + __("Could not update %s with the csv data: %s because %s", "event_espresso"), |
|
| 938 | + $model->get_this_model_name(), |
|
| 939 | + implode(",", $model_object_data), |
|
| 940 | + $e->getMessage() |
|
| 941 | + ); |
|
| 942 | + $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString(); |
|
| 943 | + EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__); |
|
| 944 | + } |
|
| 945 | + return $old_db_to_new_db_mapping; |
|
| 946 | + } |
|
| 947 | + |
|
| 948 | + /** |
|
| 949 | + * Gets the number of inserts performed since importer was instantiated or reset |
|
| 950 | + * |
|
| 951 | + * @return int |
|
| 952 | + */ |
|
| 953 | + public function get_total_inserts() |
|
| 954 | + { |
|
| 955 | + return $this->_total_inserts; |
|
| 956 | + } |
|
| 957 | + |
|
| 958 | + /** |
|
| 959 | + * Gets the number of insert errors since importer was instantiated or reset |
|
| 960 | + * |
|
| 961 | + * @return int |
|
| 962 | + */ |
|
| 963 | + public function get_total_insert_errors() |
|
| 964 | + { |
|
| 965 | + return $this->_total_insert_errors; |
|
| 966 | + } |
|
| 967 | + |
|
| 968 | + /** |
|
| 969 | + * Gets the number of updates performed since importer was instantiated or reset |
|
| 970 | + * |
|
| 971 | + * @return int |
|
| 972 | + */ |
|
| 973 | + public function get_total_updates() |
|
| 974 | + { |
|
| 975 | + return $this->_total_updates; |
|
| 976 | + } |
|
| 977 | + |
|
| 978 | + /** |
|
| 979 | + * Gets the number of update errors since importer was instantiated or reset |
|
| 980 | + * |
|
| 981 | + * @return int |
|
| 982 | + */ |
|
| 983 | + public function get_total_update_errors() |
|
| 984 | + { |
|
| 985 | + return $this->_total_update_errors; |
|
| 986 | + } |
|
| 987 | 987 | } |
@@ -135,7 +135,7 @@ discard block |
||
| 135 | 135 | public function import() |
| 136 | 136 | { |
| 137 | 137 | |
| 138 | - require_once(EE_CLASSES . 'EE_CSV.class.php'); |
|
| 138 | + require_once(EE_CLASSES.'EE_CSV.class.php'); |
|
| 139 | 139 | $this->EE_CSV = EE_CSV::instance(); |
| 140 | 140 | |
| 141 | 141 | if (isset($_REQUEST['import'])) { |
@@ -179,18 +179,18 @@ discard block |
||
| 179 | 179 | break; |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | - if (! $error_msg) { |
|
| 182 | + if ( ! $error_msg) { |
|
| 183 | 183 | $filename = $_FILES['file']['name'][0]; |
| 184 | 184 | $file_ext = substr(strrchr($filename, '.'), 1); |
| 185 | 185 | $file_type = $_FILES['file']['type'][0]; |
| 186 | 186 | $temp_file = $_FILES['file']['tmp_name'][0]; |
| 187 | - $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB |
|
| 187 | + $filesize = $_FILES['file']['size'][0] / 1024; // convert from bytes to KB |
|
| 188 | 188 | |
| 189 | 189 | if ($file_ext == 'csv') { |
| 190 | - $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB |
|
| 190 | + $max_upload = $this->EE_CSV->get_max_upload_size(); // max upload size in KB |
|
| 191 | 191 | if ($filesize < $max_upload || true) { |
| 192 | 192 | $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir()); |
| 193 | - $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename; |
|
| 193 | + $path_to_file = $wp_upload_dir['basedir'].'/espresso/'.$filename; |
|
| 194 | 194 | |
| 195 | 195 | if (move_uploaded_file($temp_file, $path_to_file)) { |
| 196 | 196 | // convert csv to array |
@@ -324,8 +324,8 @@ discard block |
||
| 324 | 324 | // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name... |
| 325 | 325 | $old_site_url = 'none-specified'; |
| 326 | 326 | // hanlde metadata |
| 327 | - if (isset($csv_data_array[ EE_CSV::metadata_header ])) { |
|
| 328 | - $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 327 | + if (isset($csv_data_array[EE_CSV::metadata_header])) { |
|
| 328 | + $csv_metadata = array_shift($csv_data_array[EE_CSV::metadata_header]); |
|
| 329 | 329 | // ok so its metadata, dont try to save it to ehte db obviously... |
| 330 | 330 | if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) { |
| 331 | 331 | EE_Error::add_attention( |
@@ -350,14 +350,14 @@ discard block |
||
| 350 | 350 | ) |
| 351 | 351 | ); |
| 352 | 352 | }; |
| 353 | - unset($csv_data_array[ EE_CSV::metadata_header ]); |
|
| 353 | + unset($csv_data_array[EE_CSV::metadata_header]); |
|
| 354 | 354 | } |
| 355 | 355 | /** |
| 356 | 356 | * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and |
| 357 | 357 | * the value will be the newly-inserted ID. |
| 358 | 358 | * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option |
| 359 | 359 | */ |
| 360 | - $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array()); |
|
| 360 | + $old_db_to_new_db_mapping = get_option('ee_id_mapping_from'.sanitize_title($old_site_url), array()); |
|
| 361 | 361 | if ($old_db_to_new_db_mapping) { |
| 362 | 362 | EE_Error::add_attention( |
| 363 | 363 | sprintf( |
@@ -377,7 +377,7 @@ discard block |
||
| 377 | 377 | ); |
| 378 | 378 | |
| 379 | 379 | // save the mapping from old db to new db in case they try re-importing the same data from the same website again |
| 380 | - update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping); |
|
| 380 | + update_option('ee_id_mapping_from'.sanitize_title($old_site_url), $old_db_to_new_db_mapping); |
|
| 381 | 381 | |
| 382 | 382 | if ($this->_total_updates > 0) { |
| 383 | 383 | EE_Error::add_success( |
@@ -500,7 +500,7 @@ discard block |
||
| 500 | 500 | // find the PK in the row of data (or a combined key if |
| 501 | 501 | // there is no primary key) |
| 502 | 502 | if ($model->has_primary_key_field()) { |
| 503 | - $id_in_csv = $model_object_data[ $model->primary_key_name() ]; |
|
| 503 | + $id_in_csv = $model_object_data[$model->primary_key_name()]; |
|
| 504 | 504 | } else { |
| 505 | 505 | $id_in_csv = $model->get_index_primary_key_string($model_object_data); |
| 506 | 506 | } |
@@ -544,14 +544,14 @@ discard block |
||
| 544 | 544 | $what_to_do = self::do_update; |
| 545 | 545 | // and if this model has a primary key, remember its mapping |
| 546 | 546 | if ($model->has_primary_key_field()) { |
| 547 | - $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID(); |
|
| 548 | - $model_object_data[ $model->primary_key_name() ] = $conflicting->ID(); |
|
| 547 | + $old_db_to_new_db_mapping[$model_name][$id_in_csv] = $conflicting->ID(); |
|
| 548 | + $model_object_data[$model->primary_key_name()] = $conflicting->ID(); |
|
| 549 | 549 | } else { |
| 550 | 550 | // we want to update this conflicting item, instead of inserting a conflicting item |
| 551 | 551 | // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields |
| 552 | 552 | // for the WHERE conditions in the update). At the time of this comment, there were no models like this |
| 553 | 553 | foreach ($model->get_combined_primary_key_fields() as $key_field) { |
| 554 | - $model_object_data[ $key_field->get_name() ] = $conflicting->get( |
|
| 554 | + $model_object_data[$key_field->get_name()] = $conflicting->get( |
|
| 555 | 555 | $key_field->get_name() |
| 556 | 556 | ); |
| 557 | 557 | } |
@@ -611,7 +611,7 @@ discard block |
||
| 611 | 611 | $model_name = $model->get_this_model_name(); |
| 612 | 612 | // if it's a site-to-site export-and-import, see if this modelobject's id |
| 613 | 613 | // in the old data that we know of |
| 614 | - if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) { |
|
| 614 | + if (isset($old_db_to_new_db_mapping[$model_name][$id_in_csv])) { |
|
| 615 | 615 | return self::do_update; |
| 616 | 616 | } else { |
| 617 | 617 | return self::do_insert; |
@@ -666,12 +666,12 @@ discard block |
||
| 666 | 666 | // if this model object's primary key is in the mapping, replace it |
| 667 | 667 | if ($model->has_primary_key_field() && |
| 668 | 668 | $model->get_primary_key_field()->is_auto_increment() && |
| 669 | - isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) && |
|
| 669 | + isset($old_db_to_new_db_mapping[$model->get_this_model_name()]) && |
|
| 670 | 670 | isset( |
| 671 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ] |
|
| 671 | + $old_db_to_new_db_mapping[$model->get_this_model_name()][$model_object_data[$model->primary_key_name()]] |
|
| 672 | 672 | )) { |
| 673 | - $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name( |
|
| 674 | - ) ][ $model_object_data[ $model->primary_key_name() ] ]; |
|
| 673 | + $model_object_data[$model->primary_key_name()] = $old_db_to_new_db_mapping[$model->get_this_model_name( |
|
| 674 | + )][$model_object_data[$model->primary_key_name()]]; |
|
| 675 | 675 | } |
| 676 | 676 | |
| 677 | 677 | try { |
@@ -687,10 +687,10 @@ discard block |
||
| 687 | 687 | $found_a_mapping = false; |
| 688 | 688 | foreach ($models_pointed_to as $model_pointed_to_by_fk) { |
| 689 | 689 | if ($model_name_field) { |
| 690 | - $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ]; |
|
| 690 | + $value_of_model_name_field = $model_object_data[$model_name_field->get_name()]; |
|
| 691 | 691 | if ($value_of_model_name_field == $model_pointed_to_by_fk) { |
| 692 | - $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 693 | - $model_object_data[ $field_obj->get_name() ], |
|
| 692 | + $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in( |
|
| 693 | + $model_object_data[$field_obj->get_name()], |
|
| 694 | 694 | $model_pointed_to_by_fk, |
| 695 | 695 | $old_db_to_new_db_mapping, |
| 696 | 696 | $export_from_site_a_to_b |
@@ -699,8 +699,8 @@ discard block |
||
| 699 | 699 | break; |
| 700 | 700 | } |
| 701 | 701 | } else { |
| 702 | - $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in( |
|
| 703 | - $model_object_data[ $field_obj->get_name() ], |
|
| 702 | + $model_object_data[$field_obj->get_name()] = $this->_find_mapping_in( |
|
| 703 | + $model_object_data[$field_obj->get_name()], |
|
| 704 | 704 | $model_pointed_to_by_fk, |
| 705 | 705 | $old_db_to_new_db_mapping, |
| 706 | 706 | $export_from_site_a_to_b |
@@ -763,8 +763,8 @@ discard block |
||
| 763 | 763 | */ |
| 764 | 764 | protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b) |
| 765 | 765 | { |
| 766 | - if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) { |
|
| 767 | - return $old_db_to_new_db_mapping[ $model_name ][ $object_id ]; |
|
| 766 | + if (isset($old_db_to_new_db_mapping[$model_name][$object_id])) { |
|
| 767 | + return $old_db_to_new_db_mapping[$model_name][$object_id]; |
|
| 768 | 768 | } elseif ($object_id == '0' || $object_id == '') { |
| 769 | 769 | // leave as-is |
| 770 | 770 | return $object_id; |
@@ -772,7 +772,7 @@ discard block |
||
| 772 | 772 | // we couldn't find a mapping for this, and it's from a different site, |
| 773 | 773 | // so blank it out |
| 774 | 774 | return null; |
| 775 | - } elseif (! $export_from_site_a_to_b) { |
|
| 775 | + } elseif ( ! $export_from_site_a_to_b) { |
|
| 776 | 776 | // we coudln't find a mapping for this, but it's from thsi DB anyway |
| 777 | 777 | // so let's just leave it as-is |
| 778 | 778 | return $object_id; |
@@ -792,8 +792,8 @@ discard block |
||
| 792 | 792 | // remove the primary key, if there is one (we don't want it for inserts OR updates) |
| 793 | 793 | // we'll put it back in if we need it |
| 794 | 794 | if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) { |
| 795 | - $effective_id = $model_object_data[ $model->primary_key_name() ]; |
|
| 796 | - unset($model_object_data[ $model->primary_key_name() ]); |
|
| 795 | + $effective_id = $model_object_data[$model->primary_key_name()]; |
|
| 796 | + unset($model_object_data[$model->primary_key_name()]); |
|
| 797 | 797 | } else { |
| 798 | 798 | $effective_id = $model->get_index_primary_key_string($model_object_data); |
| 799 | 799 | } |
@@ -801,7 +801,7 @@ discard block |
||
| 801 | 801 | try { |
| 802 | 802 | $new_id = $model->insert($model_object_data); |
| 803 | 803 | if ($new_id) { |
| 804 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id; |
|
| 804 | + $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_id; |
|
| 805 | 805 | $this->_total_inserts++; |
| 806 | 806 | EE_Error::add_success( |
| 807 | 807 | sprintf( |
@@ -815,7 +815,7 @@ discard block |
||
| 815 | 815 | $this->_total_insert_errors++; |
| 816 | 816 | // put the ID used back in there for the error message |
| 817 | 817 | if ($model->has_primary_key_field()) { |
| 818 | - $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 818 | + $model_object_data[$model->primary_key_name()] = $effective_id; |
|
| 819 | 819 | } |
| 820 | 820 | EE_Error::add_error( |
| 821 | 821 | sprintf( |
@@ -831,7 +831,7 @@ discard block |
||
| 831 | 831 | } catch (EE_Error $e) { |
| 832 | 832 | $this->_total_insert_errors++; |
| 833 | 833 | if ($model->has_primary_key_field()) { |
| 834 | - $model_object_data[ $model->primary_key_name() ] = $effective_id; |
|
| 834 | + $model_object_data[$model->primary_key_name()] = $effective_id; |
|
| 835 | 835 | } |
| 836 | 836 | EE_Error::add_error( |
| 837 | 837 | sprintf( |
@@ -864,17 +864,17 @@ discard block |
||
| 864 | 864 | // one for performing an update, one for everthing else |
| 865 | 865 | $model_object_data_for_update = $model_object_data; |
| 866 | 866 | if ($model->has_primary_key_field()) { |
| 867 | - $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]); |
|
| 867 | + $conditions = array($model->primary_key_name() => $model_object_data[$model->primary_key_name()]); |
|
| 868 | 868 | // remove the primary key because we shouldn't use it for updating |
| 869 | - unset($model_object_data_for_update[ $model->primary_key_name() ]); |
|
| 869 | + unset($model_object_data_for_update[$model->primary_key_name()]); |
|
| 870 | 870 | } elseif ($model->get_combined_primary_key_fields() > 1) { |
| 871 | 871 | $conditions = array(); |
| 872 | 872 | foreach ($model->get_combined_primary_key_fields() as $key_field) { |
| 873 | - $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ]; |
|
| 873 | + $conditions[$key_field->get_name()] = $model_object_data[$key_field->get_name()]; |
|
| 874 | 874 | } |
| 875 | 875 | } else { |
| 876 | 876 | $model->primary_key_name( |
| 877 | - );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey) |
|
| 877 | + ); // this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey) |
|
| 878 | 878 | } |
| 879 | 879 | |
| 880 | 880 | $success = $model->update($model_object_data_for_update, array($conditions)); |
@@ -892,15 +892,15 @@ discard block |
||
| 892 | 892 | // we would have last-minute decided to update. So we'd like to know what we updated |
| 893 | 893 | // and so we record what record ended up being updated using the mapping |
| 894 | 894 | if ($model->has_primary_key_field()) { |
| 895 | - $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ]; |
|
| 895 | + $new_key_for_mapping = $model_object_data[$model->primary_key_name()]; |
|
| 896 | 896 | } else { |
| 897 | 897 | // no primary key just a combined key |
| 898 | 898 | $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data); |
| 899 | 899 | } |
| 900 | - $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping; |
|
| 900 | + $old_db_to_new_db_mapping[$model->get_this_model_name()][$id_in_csv] = $new_key_for_mapping; |
|
| 901 | 901 | } else { |
| 902 | 902 | $matched_items = $model->get_all(array($conditions)); |
| 903 | - if (! $matched_items) { |
|
| 903 | + if ( ! $matched_items) { |
|
| 904 | 904 | // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck? |
| 905 | 905 | $this->_total_update_errors++; |
| 906 | 906 | EE_Error::add_error( |
@@ -939,7 +939,7 @@ discard block |
||
| 939 | 939 | implode(",", $model_object_data), |
| 940 | 940 | $e->getMessage() |
| 941 | 941 | ); |
| 942 | - $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString(); |
|
| 942 | + $debug_message = $basic_message.' Stack trace: '.$e->getTraceAsString(); |
|
| 943 | 943 | EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__); |
| 944 | 944 | } |
| 945 | 945 | return $old_db_to_new_db_mapping; |
@@ -22,1225 +22,1225 @@ |
||
| 22 | 22 | class EE_Register_Addon implements EEI_Plugin_API |
| 23 | 23 | { |
| 24 | 24 | |
| 25 | - /** |
|
| 26 | - * possibly truncated version of the EE core version string |
|
| 27 | - * |
|
| 28 | - * @var string |
|
| 29 | - */ |
|
| 30 | - protected static $_core_version = ''; |
|
| 25 | + /** |
|
| 26 | + * possibly truncated version of the EE core version string |
|
| 27 | + * |
|
| 28 | + * @var string |
|
| 29 | + */ |
|
| 30 | + protected static $_core_version = ''; |
|
| 31 | 31 | |
| 32 | - /** |
|
| 33 | - * Holds values for registered addons |
|
| 34 | - * |
|
| 35 | - * @var array |
|
| 36 | - */ |
|
| 37 | - protected static $_settings = array(); |
|
| 32 | + /** |
|
| 33 | + * Holds values for registered addons |
|
| 34 | + * |
|
| 35 | + * @var array |
|
| 36 | + */ |
|
| 37 | + protected static $_settings = array(); |
|
| 38 | 38 | |
| 39 | - /** |
|
| 40 | - * @var array $_incompatible_addons keys are addon SLUGS |
|
| 41 | - * (first argument passed to EE_Register_Addon::register()), keys are |
|
| 42 | - * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004). |
|
| 43 | - * Generally this should be used sparingly, as we don't want to muddle up |
|
| 44 | - * EE core with knowledge of ALL the addons out there. |
|
| 45 | - * If you want NO versions of an addon to run with a certain version of core, |
|
| 46 | - * it's usually best to define the addon's "min_core_version" as part of its call |
|
| 47 | - * to EE_Register_Addon::register(), rather than using this array with a super high value for its |
|
| 48 | - * minimum plugin version. |
|
| 49 | - * @access protected |
|
| 50 | - */ |
|
| 51 | - protected static $_incompatible_addons = array( |
|
| 52 | - 'Multi_Event_Registration' => '2.0.11.rc.002', |
|
| 53 | - 'Promotions' => '1.0.0.rc.084', |
|
| 54 | - ); |
|
| 39 | + /** |
|
| 40 | + * @var array $_incompatible_addons keys are addon SLUGS |
|
| 41 | + * (first argument passed to EE_Register_Addon::register()), keys are |
|
| 42 | + * their MINIMUM VERSION (with all 5 parts. Eg 1.2.3.rc.004). |
|
| 43 | + * Generally this should be used sparingly, as we don't want to muddle up |
|
| 44 | + * EE core with knowledge of ALL the addons out there. |
|
| 45 | + * If you want NO versions of an addon to run with a certain version of core, |
|
| 46 | + * it's usually best to define the addon's "min_core_version" as part of its call |
|
| 47 | + * to EE_Register_Addon::register(), rather than using this array with a super high value for its |
|
| 48 | + * minimum plugin version. |
|
| 49 | + * @access protected |
|
| 50 | + */ |
|
| 51 | + protected static $_incompatible_addons = array( |
|
| 52 | + 'Multi_Event_Registration' => '2.0.11.rc.002', |
|
| 53 | + 'Promotions' => '1.0.0.rc.084', |
|
| 54 | + ); |
|
| 55 | 55 | |
| 56 | 56 | |
| 57 | - /** |
|
| 58 | - * We should always be comparing core to a version like '4.3.0.rc.000', |
|
| 59 | - * not just '4.3.0'. |
|
| 60 | - * So if the addon developer doesn't provide that full version string, |
|
| 61 | - * fill in the blanks for them |
|
| 62 | - * |
|
| 63 | - * @param string $min_core_version |
|
| 64 | - * @return string always like '4.3.0.rc.000' |
|
| 65 | - */ |
|
| 66 | - protected static function _effective_version($min_core_version) |
|
| 67 | - { |
|
| 68 | - // versions: 4 . 3 . 1 . p . 123 |
|
| 69 | - // offsets: 0 . 1 . 2 . 3 . 4 |
|
| 70 | - $version_parts = explode('.', $min_core_version); |
|
| 71 | - // check they specified the micro version (after 2nd period) |
|
| 72 | - if (! isset($version_parts[2])) { |
|
| 73 | - $version_parts[2] = '0'; |
|
| 74 | - } |
|
| 75 | - // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible |
|
| 76 | - // soon we can assume that's 'rc', but this current version is 'alpha' |
|
| 77 | - if (! isset($version_parts[3])) { |
|
| 78 | - $version_parts[3] = 'dev'; |
|
| 79 | - } |
|
| 80 | - if (! isset($version_parts[4])) { |
|
| 81 | - $version_parts[4] = '000'; |
|
| 82 | - } |
|
| 83 | - return implode('.', $version_parts); |
|
| 84 | - } |
|
| 57 | + /** |
|
| 58 | + * We should always be comparing core to a version like '4.3.0.rc.000', |
|
| 59 | + * not just '4.3.0'. |
|
| 60 | + * So if the addon developer doesn't provide that full version string, |
|
| 61 | + * fill in the blanks for them |
|
| 62 | + * |
|
| 63 | + * @param string $min_core_version |
|
| 64 | + * @return string always like '4.3.0.rc.000' |
|
| 65 | + */ |
|
| 66 | + protected static function _effective_version($min_core_version) |
|
| 67 | + { |
|
| 68 | + // versions: 4 . 3 . 1 . p . 123 |
|
| 69 | + // offsets: 0 . 1 . 2 . 3 . 4 |
|
| 70 | + $version_parts = explode('.', $min_core_version); |
|
| 71 | + // check they specified the micro version (after 2nd period) |
|
| 72 | + if (! isset($version_parts[2])) { |
|
| 73 | + $version_parts[2] = '0'; |
|
| 74 | + } |
|
| 75 | + // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible |
|
| 76 | + // soon we can assume that's 'rc', but this current version is 'alpha' |
|
| 77 | + if (! isset($version_parts[3])) { |
|
| 78 | + $version_parts[3] = 'dev'; |
|
| 79 | + } |
|
| 80 | + if (! isset($version_parts[4])) { |
|
| 81 | + $version_parts[4] = '000'; |
|
| 82 | + } |
|
| 83 | + return implode('.', $version_parts); |
|
| 84 | + } |
|
| 85 | 85 | |
| 86 | 86 | |
| 87 | - /** |
|
| 88 | - * Returns whether or not the min core version requirement of the addon is met |
|
| 89 | - * |
|
| 90 | - * @param string $min_core_version the minimum core version required by the addon |
|
| 91 | - * @param string $actual_core_version the actual core version, optional |
|
| 92 | - * @return boolean |
|
| 93 | - */ |
|
| 94 | - public static function _meets_min_core_version_requirement( |
|
| 95 | - $min_core_version, |
|
| 96 | - $actual_core_version = EVENT_ESPRESSO_VERSION |
|
| 97 | - ) { |
|
| 98 | - return version_compare( |
|
| 99 | - self::_effective_version($actual_core_version), |
|
| 100 | - self::_effective_version($min_core_version), |
|
| 101 | - '>=' |
|
| 102 | - ); |
|
| 103 | - } |
|
| 87 | + /** |
|
| 88 | + * Returns whether or not the min core version requirement of the addon is met |
|
| 89 | + * |
|
| 90 | + * @param string $min_core_version the minimum core version required by the addon |
|
| 91 | + * @param string $actual_core_version the actual core version, optional |
|
| 92 | + * @return boolean |
|
| 93 | + */ |
|
| 94 | + public static function _meets_min_core_version_requirement( |
|
| 95 | + $min_core_version, |
|
| 96 | + $actual_core_version = EVENT_ESPRESSO_VERSION |
|
| 97 | + ) { |
|
| 98 | + return version_compare( |
|
| 99 | + self::_effective_version($actual_core_version), |
|
| 100 | + self::_effective_version($min_core_version), |
|
| 101 | + '>=' |
|
| 102 | + ); |
|
| 103 | + } |
|
| 104 | 104 | |
| 105 | 105 | |
| 106 | - /** |
|
| 107 | - * Method for registering new EE_Addons. |
|
| 108 | - * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE |
|
| 109 | - * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it |
|
| 110 | - * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon |
|
| 111 | - * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after |
|
| 112 | - * 'activate_plugin', it registers the addon still, but its components are not registered |
|
| 113 | - * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do |
|
| 114 | - * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns |
|
| 115 | - * (so that we can detect that the addon has activated on the subsequent request) |
|
| 116 | - * |
|
| 117 | - * @since 4.3.0 |
|
| 118 | - * @param string $addon_name [Required] the EE_Addon's name. |
|
| 119 | - * @param array $setup_args { |
|
| 120 | - * An array of arguments provided for registering |
|
| 121 | - * the message type. |
|
| 122 | - * @type string $class_name the addon's main file name. |
|
| 123 | - * If left blank, generated from the addon name, |
|
| 124 | - * changes something like "calendar" to |
|
| 125 | - * "EE_Calendar" |
|
| 126 | - * @type string $min_core_version the minimum version of EE Core that the |
|
| 127 | - * addon will work with. eg "4.8.1.rc.084" |
|
| 128 | - * @type string $version the "software" version for the addon. eg |
|
| 129 | - * "1.0.0.p" for a first stable release, or |
|
| 130 | - * "1.0.0.rc.043" for a version in progress |
|
| 131 | - * @type string $main_file_path the full server path to the main file |
|
| 132 | - * loaded directly by WP |
|
| 133 | - * @type DomainInterface $domain child class of |
|
| 134 | - * EventEspresso\core\domain\DomainBase |
|
| 135 | - * @type string $domain_fqcn Fully Qualified Class Name |
|
| 136 | - * for the addon's Domain class |
|
| 137 | - * (see EventEspresso\core\domain\Domain) |
|
| 138 | - * @type string $admin_path full server path to the folder where the |
|
| 139 | - * addon\'s admin files reside |
|
| 140 | - * @type string $admin_callback a method to be called when the EE Admin is |
|
| 141 | - * first invoked, can be used for hooking into |
|
| 142 | - * any admin page |
|
| 143 | - * @type string $config_section the section name for this addon's |
|
| 144 | - * configuration settings section |
|
| 145 | - * (defaults to "addons") |
|
| 146 | - * @type string $config_class the class name for this addon's |
|
| 147 | - * configuration settings object |
|
| 148 | - * @type string $config_name the class name for this addon's |
|
| 149 | - * configuration settings object |
|
| 150 | - * @type string $autoloader_paths [Required] an array of class names and the full |
|
| 151 | - * server paths to those files. |
|
| 152 | - * @type string $autoloader_folders an array of "full server paths" for any |
|
| 153 | - * folders containing classes that might be |
|
| 154 | - * invoked by the addon |
|
| 155 | - * @type string $dms_paths [Required] an array of full server paths to |
|
| 156 | - * folders that contain data migration scripts. |
|
| 157 | - * The key should be the EE_Addon class name that |
|
| 158 | - * this set of data migration scripts belongs to. |
|
| 159 | - * If the EE_Addon class is namespaced, then this |
|
| 160 | - * needs to be the Fully Qualified Class Name |
|
| 161 | - * @type string $module_paths an array of full server paths to any |
|
| 162 | - * EED_Modules used by the addon |
|
| 163 | - * @type string $shortcode_paths an array of full server paths to folders |
|
| 164 | - * that contain EES_Shortcodes |
|
| 165 | - * @type string $widget_paths an array of full server paths to folders |
|
| 166 | - * that contain WP_Widgets |
|
| 167 | - * @type string $pue_options |
|
| 168 | - * @type array $capabilities an array indexed by role name |
|
| 169 | - * (i.e administrator,author ) and the values |
|
| 170 | - * are an array of caps to add to the role. |
|
| 171 | - * 'administrator' => array( |
|
| 172 | - * 'read_addon', |
|
| 173 | - * 'edit_addon', |
|
| 174 | - * etc. |
|
| 175 | - * ). |
|
| 176 | - * @type EE_Meta_Capability_Map[] $capability_maps an array of EE_Meta_Capability_Map object |
|
| 177 | - * for any addons that need to register any |
|
| 178 | - * special meta mapped capabilities. Should |
|
| 179 | - * be indexed where the key is the |
|
| 180 | - * EE_Meta_Capability_Map class name and the |
|
| 181 | - * values are the arguments sent to the class. |
|
| 182 | - * @type array $model_paths array of folders containing DB models |
|
| 183 | - * @see EE_Register_Model |
|
| 184 | - * @type array $class_paths array of folders containing DB classes |
|
| 185 | - * @see EE_Register_Model |
|
| 186 | - * @type array $model_extension_paths array of folders containing DB model |
|
| 187 | - * extensions |
|
| 188 | - * @see EE_Register_Model_Extension |
|
| 189 | - * @type array $class_extension_paths array of folders containing DB class |
|
| 190 | - * extensions |
|
| 191 | - * @see EE_Register_Model_Extension |
|
| 192 | - * @type array message_types { |
|
| 193 | - * An array of message types with the key as |
|
| 194 | - * the message type name and the values as |
|
| 195 | - * below: |
|
| 196 | - * @type string $mtfilename [Required] The filename of the message type |
|
| 197 | - * being registered. This will be the main |
|
| 198 | - * EE_{Message Type Name}_message_type class. |
|
| 199 | - * for example: |
|
| 200 | - * EE_Declined_Registration_message_type.class.php |
|
| 201 | - * @type array $autoloadpaths [Required] An array of paths to add to the |
|
| 202 | - * messages autoloader for the new message type. |
|
| 203 | - * @type array $messengers_to_activate_with An array of messengers that this message |
|
| 204 | - * type should activate with. Each value in |
|
| 205 | - * the |
|
| 206 | - * array |
|
| 207 | - * should match the name property of a |
|
| 208 | - * EE_messenger. Optional. |
|
| 209 | - * @type array $messengers_to_validate_with An array of messengers that this message |
|
| 210 | - * type should validate with. Each value in |
|
| 211 | - * the |
|
| 212 | - * array |
|
| 213 | - * should match the name property of an |
|
| 214 | - * EE_messenger. |
|
| 215 | - * Optional. |
|
| 216 | - * } |
|
| 217 | - * @type array $custom_post_types |
|
| 218 | - * @type array $custom_taxonomies |
|
| 219 | - * @type array $payment_method_paths each element is the folder containing the |
|
| 220 | - * EE_PMT_Base child class |
|
| 221 | - * (eg, |
|
| 222 | - * '/wp-content/plugins/my_plugin/Payomatic/' |
|
| 223 | - * which contains the files |
|
| 224 | - * EE_PMT_Payomatic.pm.php) |
|
| 225 | - * @type array $default_terms |
|
| 226 | - * @type array $namespace { |
|
| 227 | - * An array with two items for registering the |
|
| 228 | - * addon's namespace. (If, for some reason, you |
|
| 229 | - * require additional namespaces, |
|
| 230 | - * use |
|
| 231 | - * EventEspresso\core\Psr4Autoloader::addNamespace() |
|
| 232 | - * directly) |
|
| 233 | - * @see EventEspresso\core\Psr4Autoloader::addNamespace() |
|
| 234 | - * @type string $FQNS the namespace prefix |
|
| 235 | - * @type string $DIR a base directory for class files in the |
|
| 236 | - * namespace. |
|
| 237 | - * } |
|
| 238 | - * } |
|
| 239 | - * @type string $privacy_policies FQNSs (namespaces, each of which contains only |
|
| 240 | - * privacy policy classes) or FQCNs (specific |
|
| 241 | - * classnames of privacy policy classes) |
|
| 242 | - * @type string $personal_data_exporters FQNSs (namespaces, each of which contains only |
|
| 243 | - * privacy policy classes) or FQCNs (specific |
|
| 244 | - * classnames of privacy policy classes) |
|
| 245 | - * @type string $personal_data_erasers FQNSs (namespaces, each of which contains only |
|
| 246 | - * privacy policy classes) or FQCNs (specific |
|
| 247 | - * classnames of privacy policy classes) |
|
| 248 | - * @return void |
|
| 249 | - * @throws DomainException |
|
| 250 | - * @throws EE_Error |
|
| 251 | - * @throws InvalidArgumentException |
|
| 252 | - * @throws ReflectionException |
|
| 253 | - * @throws InvalidDataTypeException |
|
| 254 | - * @throws InvalidInterfaceException |
|
| 255 | - */ |
|
| 256 | - public static function register($addon_name = '', $setup_args = array()) |
|
| 257 | - { |
|
| 258 | - // required fields MUST be present, so let's make sure they are. |
|
| 259 | - EE_Register_Addon::_verify_parameters($addon_name, $setup_args); |
|
| 260 | - // get class name for addon |
|
| 261 | - $class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args); |
|
| 262 | - // setup $_settings array from incoming values. |
|
| 263 | - $addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args); |
|
| 264 | - // setup PUE |
|
| 265 | - EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args); |
|
| 266 | - // does this addon work with this version of core or WordPress ? |
|
| 267 | - if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) { |
|
| 268 | - return; |
|
| 269 | - } |
|
| 270 | - // register namespaces |
|
| 271 | - EE_Register_Addon::_setup_namespaces($addon_settings); |
|
| 272 | - // check if this is an activation request |
|
| 273 | - if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) { |
|
| 274 | - // dont bother setting up the rest of the addon atm |
|
| 275 | - return; |
|
| 276 | - } |
|
| 277 | - // we need cars |
|
| 278 | - EE_Register_Addon::_setup_autoloaders($addon_name); |
|
| 279 | - // register new models and extensions |
|
| 280 | - EE_Register_Addon::_register_models_and_extensions($addon_name); |
|
| 281 | - // setup DMS |
|
| 282 | - EE_Register_Addon::_register_data_migration_scripts($addon_name); |
|
| 283 | - // if config_class is present let's register config. |
|
| 284 | - EE_Register_Addon::_register_config($addon_name); |
|
| 285 | - // register admin pages |
|
| 286 | - EE_Register_Addon::_register_admin_pages($addon_name); |
|
| 287 | - // add to list of modules to be registered |
|
| 288 | - EE_Register_Addon::_register_modules($addon_name); |
|
| 289 | - // add to list of shortcodes to be registered |
|
| 290 | - EE_Register_Addon::_register_shortcodes($addon_name); |
|
| 291 | - // add to list of widgets to be registered |
|
| 292 | - EE_Register_Addon::_register_widgets($addon_name); |
|
| 293 | - // register capability related stuff. |
|
| 294 | - EE_Register_Addon::_register_capabilities($addon_name); |
|
| 295 | - // any message type to register? |
|
| 296 | - EE_Register_Addon::_register_message_types($addon_name); |
|
| 297 | - // any custom post type/ custom capabilities or default terms to register |
|
| 298 | - EE_Register_Addon::_register_custom_post_types($addon_name); |
|
| 299 | - // and any payment methods |
|
| 300 | - EE_Register_Addon::_register_payment_methods($addon_name); |
|
| 301 | - // and privacy policy generators |
|
| 302 | - EE_Register_Addon::registerPrivacyPolicies($addon_name); |
|
| 303 | - // and privacy policy generators |
|
| 304 | - EE_Register_Addon::registerPersonalDataExporters($addon_name); |
|
| 305 | - // and privacy policy generators |
|
| 306 | - EE_Register_Addon::registerPersonalDataErasers($addon_name); |
|
| 307 | - // load and instantiate main addon class |
|
| 308 | - $addon = EE_Register_Addon::_load_and_init_addon_class($addon_name); |
|
| 309 | - // delay calling after_registration hook on each addon until after all add-ons have been registered. |
|
| 310 | - add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999); |
|
| 311 | - } |
|
| 106 | + /** |
|
| 107 | + * Method for registering new EE_Addons. |
|
| 108 | + * Should be called AFTER AHEE__EE_System__load_espresso_addons but BEFORE |
|
| 109 | + * AHEE__EE_System___detect_if_activation_or_upgrade__begin in order to register all its components. However, it |
|
| 110 | + * may also be called after the 'activate_plugin' action (when an addon is activated), because an activating addon |
|
| 111 | + * won't be loaded by WP until after AHEE__EE_System__load_espresso_addons has fired. If its called after |
|
| 112 | + * 'activate_plugin', it registers the addon still, but its components are not registered |
|
| 113 | + * (they shouldn't be needed anyways, because it's just an activation request and they won't have a chance to do |
|
| 114 | + * anything anyways). Instead, it just sets the newly-activated addon's activation indicator wp option and returns |
|
| 115 | + * (so that we can detect that the addon has activated on the subsequent request) |
|
| 116 | + * |
|
| 117 | + * @since 4.3.0 |
|
| 118 | + * @param string $addon_name [Required] the EE_Addon's name. |
|
| 119 | + * @param array $setup_args { |
|
| 120 | + * An array of arguments provided for registering |
|
| 121 | + * the message type. |
|
| 122 | + * @type string $class_name the addon's main file name. |
|
| 123 | + * If left blank, generated from the addon name, |
|
| 124 | + * changes something like "calendar" to |
|
| 125 | + * "EE_Calendar" |
|
| 126 | + * @type string $min_core_version the minimum version of EE Core that the |
|
| 127 | + * addon will work with. eg "4.8.1.rc.084" |
|
| 128 | + * @type string $version the "software" version for the addon. eg |
|
| 129 | + * "1.0.0.p" for a first stable release, or |
|
| 130 | + * "1.0.0.rc.043" for a version in progress |
|
| 131 | + * @type string $main_file_path the full server path to the main file |
|
| 132 | + * loaded directly by WP |
|
| 133 | + * @type DomainInterface $domain child class of |
|
| 134 | + * EventEspresso\core\domain\DomainBase |
|
| 135 | + * @type string $domain_fqcn Fully Qualified Class Name |
|
| 136 | + * for the addon's Domain class |
|
| 137 | + * (see EventEspresso\core\domain\Domain) |
|
| 138 | + * @type string $admin_path full server path to the folder where the |
|
| 139 | + * addon\'s admin files reside |
|
| 140 | + * @type string $admin_callback a method to be called when the EE Admin is |
|
| 141 | + * first invoked, can be used for hooking into |
|
| 142 | + * any admin page |
|
| 143 | + * @type string $config_section the section name for this addon's |
|
| 144 | + * configuration settings section |
|
| 145 | + * (defaults to "addons") |
|
| 146 | + * @type string $config_class the class name for this addon's |
|
| 147 | + * configuration settings object |
|
| 148 | + * @type string $config_name the class name for this addon's |
|
| 149 | + * configuration settings object |
|
| 150 | + * @type string $autoloader_paths [Required] an array of class names and the full |
|
| 151 | + * server paths to those files. |
|
| 152 | + * @type string $autoloader_folders an array of "full server paths" for any |
|
| 153 | + * folders containing classes that might be |
|
| 154 | + * invoked by the addon |
|
| 155 | + * @type string $dms_paths [Required] an array of full server paths to |
|
| 156 | + * folders that contain data migration scripts. |
|
| 157 | + * The key should be the EE_Addon class name that |
|
| 158 | + * this set of data migration scripts belongs to. |
|
| 159 | + * If the EE_Addon class is namespaced, then this |
|
| 160 | + * needs to be the Fully Qualified Class Name |
|
| 161 | + * @type string $module_paths an array of full server paths to any |
|
| 162 | + * EED_Modules used by the addon |
|
| 163 | + * @type string $shortcode_paths an array of full server paths to folders |
|
| 164 | + * that contain EES_Shortcodes |
|
| 165 | + * @type string $widget_paths an array of full server paths to folders |
|
| 166 | + * that contain WP_Widgets |
|
| 167 | + * @type string $pue_options |
|
| 168 | + * @type array $capabilities an array indexed by role name |
|
| 169 | + * (i.e administrator,author ) and the values |
|
| 170 | + * are an array of caps to add to the role. |
|
| 171 | + * 'administrator' => array( |
|
| 172 | + * 'read_addon', |
|
| 173 | + * 'edit_addon', |
|
| 174 | + * etc. |
|
| 175 | + * ). |
|
| 176 | + * @type EE_Meta_Capability_Map[] $capability_maps an array of EE_Meta_Capability_Map object |
|
| 177 | + * for any addons that need to register any |
|
| 178 | + * special meta mapped capabilities. Should |
|
| 179 | + * be indexed where the key is the |
|
| 180 | + * EE_Meta_Capability_Map class name and the |
|
| 181 | + * values are the arguments sent to the class. |
|
| 182 | + * @type array $model_paths array of folders containing DB models |
|
| 183 | + * @see EE_Register_Model |
|
| 184 | + * @type array $class_paths array of folders containing DB classes |
|
| 185 | + * @see EE_Register_Model |
|
| 186 | + * @type array $model_extension_paths array of folders containing DB model |
|
| 187 | + * extensions |
|
| 188 | + * @see EE_Register_Model_Extension |
|
| 189 | + * @type array $class_extension_paths array of folders containing DB class |
|
| 190 | + * extensions |
|
| 191 | + * @see EE_Register_Model_Extension |
|
| 192 | + * @type array message_types { |
|
| 193 | + * An array of message types with the key as |
|
| 194 | + * the message type name and the values as |
|
| 195 | + * below: |
|
| 196 | + * @type string $mtfilename [Required] The filename of the message type |
|
| 197 | + * being registered. This will be the main |
|
| 198 | + * EE_{Message Type Name}_message_type class. |
|
| 199 | + * for example: |
|
| 200 | + * EE_Declined_Registration_message_type.class.php |
|
| 201 | + * @type array $autoloadpaths [Required] An array of paths to add to the |
|
| 202 | + * messages autoloader for the new message type. |
|
| 203 | + * @type array $messengers_to_activate_with An array of messengers that this message |
|
| 204 | + * type should activate with. Each value in |
|
| 205 | + * the |
|
| 206 | + * array |
|
| 207 | + * should match the name property of a |
|
| 208 | + * EE_messenger. Optional. |
|
| 209 | + * @type array $messengers_to_validate_with An array of messengers that this message |
|
| 210 | + * type should validate with. Each value in |
|
| 211 | + * the |
|
| 212 | + * array |
|
| 213 | + * should match the name property of an |
|
| 214 | + * EE_messenger. |
|
| 215 | + * Optional. |
|
| 216 | + * } |
|
| 217 | + * @type array $custom_post_types |
|
| 218 | + * @type array $custom_taxonomies |
|
| 219 | + * @type array $payment_method_paths each element is the folder containing the |
|
| 220 | + * EE_PMT_Base child class |
|
| 221 | + * (eg, |
|
| 222 | + * '/wp-content/plugins/my_plugin/Payomatic/' |
|
| 223 | + * which contains the files |
|
| 224 | + * EE_PMT_Payomatic.pm.php) |
|
| 225 | + * @type array $default_terms |
|
| 226 | + * @type array $namespace { |
|
| 227 | + * An array with two items for registering the |
|
| 228 | + * addon's namespace. (If, for some reason, you |
|
| 229 | + * require additional namespaces, |
|
| 230 | + * use |
|
| 231 | + * EventEspresso\core\Psr4Autoloader::addNamespace() |
|
| 232 | + * directly) |
|
| 233 | + * @see EventEspresso\core\Psr4Autoloader::addNamespace() |
|
| 234 | + * @type string $FQNS the namespace prefix |
|
| 235 | + * @type string $DIR a base directory for class files in the |
|
| 236 | + * namespace. |
|
| 237 | + * } |
|
| 238 | + * } |
|
| 239 | + * @type string $privacy_policies FQNSs (namespaces, each of which contains only |
|
| 240 | + * privacy policy classes) or FQCNs (specific |
|
| 241 | + * classnames of privacy policy classes) |
|
| 242 | + * @type string $personal_data_exporters FQNSs (namespaces, each of which contains only |
|
| 243 | + * privacy policy classes) or FQCNs (specific |
|
| 244 | + * classnames of privacy policy classes) |
|
| 245 | + * @type string $personal_data_erasers FQNSs (namespaces, each of which contains only |
|
| 246 | + * privacy policy classes) or FQCNs (specific |
|
| 247 | + * classnames of privacy policy classes) |
|
| 248 | + * @return void |
|
| 249 | + * @throws DomainException |
|
| 250 | + * @throws EE_Error |
|
| 251 | + * @throws InvalidArgumentException |
|
| 252 | + * @throws ReflectionException |
|
| 253 | + * @throws InvalidDataTypeException |
|
| 254 | + * @throws InvalidInterfaceException |
|
| 255 | + */ |
|
| 256 | + public static function register($addon_name = '', $setup_args = array()) |
|
| 257 | + { |
|
| 258 | + // required fields MUST be present, so let's make sure they are. |
|
| 259 | + EE_Register_Addon::_verify_parameters($addon_name, $setup_args); |
|
| 260 | + // get class name for addon |
|
| 261 | + $class_name = EE_Register_Addon::_parse_class_name($addon_name, $setup_args); |
|
| 262 | + // setup $_settings array from incoming values. |
|
| 263 | + $addon_settings = EE_Register_Addon::_get_addon_settings($class_name, $setup_args); |
|
| 264 | + // setup PUE |
|
| 265 | + EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args); |
|
| 266 | + // does this addon work with this version of core or WordPress ? |
|
| 267 | + if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) { |
|
| 268 | + return; |
|
| 269 | + } |
|
| 270 | + // register namespaces |
|
| 271 | + EE_Register_Addon::_setup_namespaces($addon_settings); |
|
| 272 | + // check if this is an activation request |
|
| 273 | + if (EE_Register_Addon::_addon_activation($addon_name, $addon_settings)) { |
|
| 274 | + // dont bother setting up the rest of the addon atm |
|
| 275 | + return; |
|
| 276 | + } |
|
| 277 | + // we need cars |
|
| 278 | + EE_Register_Addon::_setup_autoloaders($addon_name); |
|
| 279 | + // register new models and extensions |
|
| 280 | + EE_Register_Addon::_register_models_and_extensions($addon_name); |
|
| 281 | + // setup DMS |
|
| 282 | + EE_Register_Addon::_register_data_migration_scripts($addon_name); |
|
| 283 | + // if config_class is present let's register config. |
|
| 284 | + EE_Register_Addon::_register_config($addon_name); |
|
| 285 | + // register admin pages |
|
| 286 | + EE_Register_Addon::_register_admin_pages($addon_name); |
|
| 287 | + // add to list of modules to be registered |
|
| 288 | + EE_Register_Addon::_register_modules($addon_name); |
|
| 289 | + // add to list of shortcodes to be registered |
|
| 290 | + EE_Register_Addon::_register_shortcodes($addon_name); |
|
| 291 | + // add to list of widgets to be registered |
|
| 292 | + EE_Register_Addon::_register_widgets($addon_name); |
|
| 293 | + // register capability related stuff. |
|
| 294 | + EE_Register_Addon::_register_capabilities($addon_name); |
|
| 295 | + // any message type to register? |
|
| 296 | + EE_Register_Addon::_register_message_types($addon_name); |
|
| 297 | + // any custom post type/ custom capabilities or default terms to register |
|
| 298 | + EE_Register_Addon::_register_custom_post_types($addon_name); |
|
| 299 | + // and any payment methods |
|
| 300 | + EE_Register_Addon::_register_payment_methods($addon_name); |
|
| 301 | + // and privacy policy generators |
|
| 302 | + EE_Register_Addon::registerPrivacyPolicies($addon_name); |
|
| 303 | + // and privacy policy generators |
|
| 304 | + EE_Register_Addon::registerPersonalDataExporters($addon_name); |
|
| 305 | + // and privacy policy generators |
|
| 306 | + EE_Register_Addon::registerPersonalDataErasers($addon_name); |
|
| 307 | + // load and instantiate main addon class |
|
| 308 | + $addon = EE_Register_Addon::_load_and_init_addon_class($addon_name); |
|
| 309 | + // delay calling after_registration hook on each addon until after all add-ons have been registered. |
|
| 310 | + add_action('AHEE__EE_System__load_espresso_addons__complete', array($addon, 'after_registration'), 999); |
|
| 311 | + } |
|
| 312 | 312 | |
| 313 | 313 | |
| 314 | - /** |
|
| 315 | - * @param string $addon_name |
|
| 316 | - * @param array $setup_args |
|
| 317 | - * @return void |
|
| 318 | - * @throws EE_Error |
|
| 319 | - */ |
|
| 320 | - private static function _verify_parameters($addon_name, array $setup_args) |
|
| 321 | - { |
|
| 322 | - // required fields MUST be present, so let's make sure they are. |
|
| 323 | - if (empty($addon_name) || ! is_array($setup_args)) { |
|
| 324 | - throw new EE_Error( |
|
| 325 | - __( |
|
| 326 | - 'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.', |
|
| 327 | - 'event_espresso' |
|
| 328 | - ) |
|
| 329 | - ); |
|
| 330 | - } |
|
| 331 | - if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) { |
|
| 332 | - throw new EE_Error( |
|
| 333 | - sprintf( |
|
| 334 | - __( |
|
| 335 | - 'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s', |
|
| 336 | - 'event_espresso' |
|
| 337 | - ), |
|
| 338 | - implode(',', array_keys($setup_args)) |
|
| 339 | - ) |
|
| 340 | - ); |
|
| 341 | - } |
|
| 342 | - // check that addon has not already been registered with that name |
|
| 343 | - if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) { |
|
| 344 | - throw new EE_Error( |
|
| 345 | - sprintf( |
|
| 346 | - __( |
|
| 347 | - 'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.', |
|
| 348 | - 'event_espresso' |
|
| 349 | - ), |
|
| 350 | - $addon_name |
|
| 351 | - ) |
|
| 352 | - ); |
|
| 353 | - } |
|
| 354 | - } |
|
| 314 | + /** |
|
| 315 | + * @param string $addon_name |
|
| 316 | + * @param array $setup_args |
|
| 317 | + * @return void |
|
| 318 | + * @throws EE_Error |
|
| 319 | + */ |
|
| 320 | + private static function _verify_parameters($addon_name, array $setup_args) |
|
| 321 | + { |
|
| 322 | + // required fields MUST be present, so let's make sure they are. |
|
| 323 | + if (empty($addon_name) || ! is_array($setup_args)) { |
|
| 324 | + throw new EE_Error( |
|
| 325 | + __( |
|
| 326 | + 'In order to register an EE_Addon with EE_Register_Addon::register(), you must include the "addon_name" (the name of the addon), and an array of arguments.', |
|
| 327 | + 'event_espresso' |
|
| 328 | + ) |
|
| 329 | + ); |
|
| 330 | + } |
|
| 331 | + if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) { |
|
| 332 | + throw new EE_Error( |
|
| 333 | + sprintf( |
|
| 334 | + __( |
|
| 335 | + 'When registering an addon, you didn\'t provide the "main_file_path", which is the full path to the main file loaded directly by Wordpress. You only provided %s', |
|
| 336 | + 'event_espresso' |
|
| 337 | + ), |
|
| 338 | + implode(',', array_keys($setup_args)) |
|
| 339 | + ) |
|
| 340 | + ); |
|
| 341 | + } |
|
| 342 | + // check that addon has not already been registered with that name |
|
| 343 | + if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) { |
|
| 344 | + throw new EE_Error( |
|
| 345 | + sprintf( |
|
| 346 | + __( |
|
| 347 | + 'An EE_Addon with the name "%s" has already been registered and each EE_Addon requires a unique name.', |
|
| 348 | + 'event_espresso' |
|
| 349 | + ), |
|
| 350 | + $addon_name |
|
| 351 | + ) |
|
| 352 | + ); |
|
| 353 | + } |
|
| 354 | + } |
|
| 355 | 355 | |
| 356 | 356 | |
| 357 | - /** |
|
| 358 | - * @param string $addon_name |
|
| 359 | - * @param array $setup_args |
|
| 360 | - * @return string |
|
| 361 | - */ |
|
| 362 | - private static function _parse_class_name($addon_name, array $setup_args) |
|
| 363 | - { |
|
| 364 | - if (empty($setup_args['class_name'])) { |
|
| 365 | - // generate one by first separating name with spaces |
|
| 366 | - $class_name = str_replace(array('-', '_'), ' ', trim($addon_name)); |
|
| 367 | - // capitalize, then replace spaces with underscores |
|
| 368 | - $class_name = str_replace(' ', '_', ucwords($class_name)); |
|
| 369 | - } else { |
|
| 370 | - $class_name = $setup_args['class_name']; |
|
| 371 | - } |
|
| 372 | - // check if classname is fully qualified or is a legacy classname already prefixed with 'EE_' |
|
| 373 | - return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0 |
|
| 374 | - ? $class_name |
|
| 375 | - : 'EE_' . $class_name; |
|
| 376 | - } |
|
| 357 | + /** |
|
| 358 | + * @param string $addon_name |
|
| 359 | + * @param array $setup_args |
|
| 360 | + * @return string |
|
| 361 | + */ |
|
| 362 | + private static function _parse_class_name($addon_name, array $setup_args) |
|
| 363 | + { |
|
| 364 | + if (empty($setup_args['class_name'])) { |
|
| 365 | + // generate one by first separating name with spaces |
|
| 366 | + $class_name = str_replace(array('-', '_'), ' ', trim($addon_name)); |
|
| 367 | + // capitalize, then replace spaces with underscores |
|
| 368 | + $class_name = str_replace(' ', '_', ucwords($class_name)); |
|
| 369 | + } else { |
|
| 370 | + $class_name = $setup_args['class_name']; |
|
| 371 | + } |
|
| 372 | + // check if classname is fully qualified or is a legacy classname already prefixed with 'EE_' |
|
| 373 | + return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0 |
|
| 374 | + ? $class_name |
|
| 375 | + : 'EE_' . $class_name; |
|
| 376 | + } |
|
| 377 | 377 | |
| 378 | 378 | |
| 379 | - /** |
|
| 380 | - * @param string $class_name |
|
| 381 | - * @param array $setup_args |
|
| 382 | - * @return array |
|
| 383 | - */ |
|
| 384 | - private static function _get_addon_settings($class_name, array $setup_args) |
|
| 385 | - { |
|
| 386 | - // setup $_settings array from incoming values. |
|
| 387 | - $addon_settings = array( |
|
| 388 | - // generated from the addon name, changes something like "calendar" to "EE_Calendar" |
|
| 389 | - 'class_name' => $class_name, |
|
| 390 | - // the addon slug for use in URLs, etc |
|
| 391 | - 'plugin_slug' => isset($setup_args['plugin_slug']) |
|
| 392 | - ? (string) $setup_args['plugin_slug'] |
|
| 393 | - : '', |
|
| 394 | - // page slug to be used when generating the "Settings" link on the WP plugin page |
|
| 395 | - 'plugin_action_slug' => isset($setup_args['plugin_action_slug']) |
|
| 396 | - ? (string) $setup_args['plugin_action_slug'] |
|
| 397 | - : '', |
|
| 398 | - // the "software" version for the addon |
|
| 399 | - 'version' => isset($setup_args['version']) |
|
| 400 | - ? (string) $setup_args['version'] |
|
| 401 | - : '', |
|
| 402 | - // the minimum version of EE Core that the addon will work with |
|
| 403 | - 'min_core_version' => isset($setup_args['min_core_version']) |
|
| 404 | - ? (string) $setup_args['min_core_version'] |
|
| 405 | - : '', |
|
| 406 | - // the minimum version of WordPress that the addon will work with |
|
| 407 | - 'min_wp_version' => isset($setup_args['min_wp_version']) |
|
| 408 | - ? (string) $setup_args['min_wp_version'] |
|
| 409 | - : EE_MIN_WP_VER_REQUIRED, |
|
| 410 | - // full server path to main file (file loaded directly by WP) |
|
| 411 | - 'main_file_path' => isset($setup_args['main_file_path']) |
|
| 412 | - ? (string) $setup_args['main_file_path'] |
|
| 413 | - : '', |
|
| 414 | - // instance of \EventEspresso\core\domain\DomainInterface |
|
| 415 | - 'domain' => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface |
|
| 416 | - ? $setup_args['domain'] |
|
| 417 | - : null, |
|
| 418 | - // Fully Qualified Class Name for the addon's Domain class |
|
| 419 | - 'domain_fqcn' => isset($setup_args['domain_fqcn']) |
|
| 420 | - ? (string) $setup_args['domain_fqcn'] |
|
| 421 | - : '', |
|
| 422 | - // path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages |
|
| 423 | - 'admin_path' => isset($setup_args['admin_path']) |
|
| 424 | - ? (string) $setup_args['admin_path'] : '', |
|
| 425 | - // a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page |
|
| 426 | - 'admin_callback' => isset($setup_args['admin_callback']) |
|
| 427 | - ? (string) $setup_args['admin_callback'] |
|
| 428 | - : '', |
|
| 429 | - // the section name for this addon's configuration settings section (defaults to "addons") |
|
| 430 | - 'config_section' => isset($setup_args['config_section']) |
|
| 431 | - ? (string) $setup_args['config_section'] |
|
| 432 | - : 'addons', |
|
| 433 | - // the class name for this addon's configuration settings object |
|
| 434 | - 'config_class' => isset($setup_args['config_class']) |
|
| 435 | - ? (string) $setup_args['config_class'] : '', |
|
| 436 | - // the name given to the config for this addons' configuration settings object (optional) |
|
| 437 | - 'config_name' => isset($setup_args['config_name']) |
|
| 438 | - ? (string) $setup_args['config_name'] : '', |
|
| 439 | - // an array of "class names" => "full server paths" for any classes that might be invoked by the addon |
|
| 440 | - 'autoloader_paths' => isset($setup_args['autoloader_paths']) |
|
| 441 | - ? (array) $setup_args['autoloader_paths'] |
|
| 442 | - : array(), |
|
| 443 | - // an array of "full server paths" for any folders containing classes that might be invoked by the addon |
|
| 444 | - 'autoloader_folders' => isset($setup_args['autoloader_folders']) |
|
| 445 | - ? (array) $setup_args['autoloader_folders'] |
|
| 446 | - : array(), |
|
| 447 | - // array of full server paths to any EE_DMS data migration scripts used by the addon. |
|
| 448 | - // The key should be the EE_Addon class name that this set of data migration scripts belongs to. |
|
| 449 | - // If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name |
|
| 450 | - 'dms_paths' => isset($setup_args['dms_paths']) |
|
| 451 | - ? (array) $setup_args['dms_paths'] |
|
| 452 | - : array(), |
|
| 453 | - // array of full server paths to any EED_Modules used by the addon |
|
| 454 | - 'module_paths' => isset($setup_args['module_paths']) |
|
| 455 | - ? (array) $setup_args['module_paths'] |
|
| 456 | - : array(), |
|
| 457 | - // array of full server paths to any EES_Shortcodes used by the addon |
|
| 458 | - 'shortcode_paths' => isset($setup_args['shortcode_paths']) |
|
| 459 | - ? (array) $setup_args['shortcode_paths'] |
|
| 460 | - : array(), |
|
| 461 | - 'shortcode_fqcns' => isset($setup_args['shortcode_fqcns']) |
|
| 462 | - ? (array) $setup_args['shortcode_fqcns'] |
|
| 463 | - : array(), |
|
| 464 | - // array of full server paths to any WP_Widgets used by the addon |
|
| 465 | - 'widget_paths' => isset($setup_args['widget_paths']) |
|
| 466 | - ? (array) $setup_args['widget_paths'] |
|
| 467 | - : array(), |
|
| 468 | - // array of PUE options used by the addon |
|
| 469 | - 'pue_options' => isset($setup_args['pue_options']) |
|
| 470 | - ? (array) $setup_args['pue_options'] |
|
| 471 | - : array(), |
|
| 472 | - 'message_types' => isset($setup_args['message_types']) |
|
| 473 | - ? (array) $setup_args['message_types'] |
|
| 474 | - : array(), |
|
| 475 | - 'capabilities' => isset($setup_args['capabilities']) |
|
| 476 | - ? (array) $setup_args['capabilities'] |
|
| 477 | - : array(), |
|
| 478 | - 'capability_maps' => isset($setup_args['capability_maps']) |
|
| 479 | - ? (array) $setup_args['capability_maps'] |
|
| 480 | - : array(), |
|
| 481 | - 'model_paths' => isset($setup_args['model_paths']) |
|
| 482 | - ? (array) $setup_args['model_paths'] |
|
| 483 | - : array(), |
|
| 484 | - 'class_paths' => isset($setup_args['class_paths']) |
|
| 485 | - ? (array) $setup_args['class_paths'] |
|
| 486 | - : array(), |
|
| 487 | - 'model_extension_paths' => isset($setup_args['model_extension_paths']) |
|
| 488 | - ? (array) $setup_args['model_extension_paths'] |
|
| 489 | - : array(), |
|
| 490 | - 'class_extension_paths' => isset($setup_args['class_extension_paths']) |
|
| 491 | - ? (array) $setup_args['class_extension_paths'] |
|
| 492 | - : array(), |
|
| 493 | - 'custom_post_types' => isset($setup_args['custom_post_types']) |
|
| 494 | - ? (array) $setup_args['custom_post_types'] |
|
| 495 | - : array(), |
|
| 496 | - 'custom_taxonomies' => isset($setup_args['custom_taxonomies']) |
|
| 497 | - ? (array) $setup_args['custom_taxonomies'] |
|
| 498 | - : array(), |
|
| 499 | - 'payment_method_paths' => isset($setup_args['payment_method_paths']) |
|
| 500 | - ? (array) $setup_args['payment_method_paths'] |
|
| 501 | - : array(), |
|
| 502 | - 'default_terms' => isset($setup_args['default_terms']) |
|
| 503 | - ? (array) $setup_args['default_terms'] |
|
| 504 | - : array(), |
|
| 505 | - // if not empty, inserts a new table row after this plugin's row on the WP Plugins page |
|
| 506 | - // that can be used for adding upgrading/marketing info |
|
| 507 | - 'plugins_page_row' => isset($setup_args['plugins_page_row']) |
|
| 508 | - ? $setup_args['plugins_page_row'] |
|
| 509 | - : '', |
|
| 510 | - 'namespace' => isset( |
|
| 511 | - $setup_args['namespace']['FQNS'], |
|
| 512 | - $setup_args['namespace']['DIR'] |
|
| 513 | - ) |
|
| 514 | - ? (array) $setup_args['namespace'] |
|
| 515 | - : array(), |
|
| 516 | - 'privacy_policies' => isset($setup_args['privacy_policies']) |
|
| 517 | - ? (array) $setup_args['privacy_policies'] |
|
| 518 | - : '', |
|
| 519 | - ); |
|
| 520 | - // if plugin_action_slug is NOT set, but an admin page path IS set, |
|
| 521 | - // then let's just use the plugin_slug since that will be used for linking to the admin page |
|
| 522 | - $addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug']) |
|
| 523 | - && ! empty($addon_settings['admin_path']) |
|
| 524 | - ? $addon_settings['plugin_slug'] |
|
| 525 | - : $addon_settings['plugin_action_slug']; |
|
| 526 | - // full server path to main file (file loaded directly by WP) |
|
| 527 | - $addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']); |
|
| 528 | - return $addon_settings; |
|
| 529 | - } |
|
| 379 | + /** |
|
| 380 | + * @param string $class_name |
|
| 381 | + * @param array $setup_args |
|
| 382 | + * @return array |
|
| 383 | + */ |
|
| 384 | + private static function _get_addon_settings($class_name, array $setup_args) |
|
| 385 | + { |
|
| 386 | + // setup $_settings array from incoming values. |
|
| 387 | + $addon_settings = array( |
|
| 388 | + // generated from the addon name, changes something like "calendar" to "EE_Calendar" |
|
| 389 | + 'class_name' => $class_name, |
|
| 390 | + // the addon slug for use in URLs, etc |
|
| 391 | + 'plugin_slug' => isset($setup_args['plugin_slug']) |
|
| 392 | + ? (string) $setup_args['plugin_slug'] |
|
| 393 | + : '', |
|
| 394 | + // page slug to be used when generating the "Settings" link on the WP plugin page |
|
| 395 | + 'plugin_action_slug' => isset($setup_args['plugin_action_slug']) |
|
| 396 | + ? (string) $setup_args['plugin_action_slug'] |
|
| 397 | + : '', |
|
| 398 | + // the "software" version for the addon |
|
| 399 | + 'version' => isset($setup_args['version']) |
|
| 400 | + ? (string) $setup_args['version'] |
|
| 401 | + : '', |
|
| 402 | + // the minimum version of EE Core that the addon will work with |
|
| 403 | + 'min_core_version' => isset($setup_args['min_core_version']) |
|
| 404 | + ? (string) $setup_args['min_core_version'] |
|
| 405 | + : '', |
|
| 406 | + // the minimum version of WordPress that the addon will work with |
|
| 407 | + 'min_wp_version' => isset($setup_args['min_wp_version']) |
|
| 408 | + ? (string) $setup_args['min_wp_version'] |
|
| 409 | + : EE_MIN_WP_VER_REQUIRED, |
|
| 410 | + // full server path to main file (file loaded directly by WP) |
|
| 411 | + 'main_file_path' => isset($setup_args['main_file_path']) |
|
| 412 | + ? (string) $setup_args['main_file_path'] |
|
| 413 | + : '', |
|
| 414 | + // instance of \EventEspresso\core\domain\DomainInterface |
|
| 415 | + 'domain' => isset($setup_args['domain']) && $setup_args['domain'] instanceof DomainInterface |
|
| 416 | + ? $setup_args['domain'] |
|
| 417 | + : null, |
|
| 418 | + // Fully Qualified Class Name for the addon's Domain class |
|
| 419 | + 'domain_fqcn' => isset($setup_args['domain_fqcn']) |
|
| 420 | + ? (string) $setup_args['domain_fqcn'] |
|
| 421 | + : '', |
|
| 422 | + // path to folder containing files for integrating with the EE core admin and/or setting up EE admin pages |
|
| 423 | + 'admin_path' => isset($setup_args['admin_path']) |
|
| 424 | + ? (string) $setup_args['admin_path'] : '', |
|
| 425 | + // a method to be called when the EE Admin is first invoked, can be used for hooking into any admin page |
|
| 426 | + 'admin_callback' => isset($setup_args['admin_callback']) |
|
| 427 | + ? (string) $setup_args['admin_callback'] |
|
| 428 | + : '', |
|
| 429 | + // the section name for this addon's configuration settings section (defaults to "addons") |
|
| 430 | + 'config_section' => isset($setup_args['config_section']) |
|
| 431 | + ? (string) $setup_args['config_section'] |
|
| 432 | + : 'addons', |
|
| 433 | + // the class name for this addon's configuration settings object |
|
| 434 | + 'config_class' => isset($setup_args['config_class']) |
|
| 435 | + ? (string) $setup_args['config_class'] : '', |
|
| 436 | + // the name given to the config for this addons' configuration settings object (optional) |
|
| 437 | + 'config_name' => isset($setup_args['config_name']) |
|
| 438 | + ? (string) $setup_args['config_name'] : '', |
|
| 439 | + // an array of "class names" => "full server paths" for any classes that might be invoked by the addon |
|
| 440 | + 'autoloader_paths' => isset($setup_args['autoloader_paths']) |
|
| 441 | + ? (array) $setup_args['autoloader_paths'] |
|
| 442 | + : array(), |
|
| 443 | + // an array of "full server paths" for any folders containing classes that might be invoked by the addon |
|
| 444 | + 'autoloader_folders' => isset($setup_args['autoloader_folders']) |
|
| 445 | + ? (array) $setup_args['autoloader_folders'] |
|
| 446 | + : array(), |
|
| 447 | + // array of full server paths to any EE_DMS data migration scripts used by the addon. |
|
| 448 | + // The key should be the EE_Addon class name that this set of data migration scripts belongs to. |
|
| 449 | + // If the EE_Addon class is namespaced, then this needs to be the Fully Qualified Class Name |
|
| 450 | + 'dms_paths' => isset($setup_args['dms_paths']) |
|
| 451 | + ? (array) $setup_args['dms_paths'] |
|
| 452 | + : array(), |
|
| 453 | + // array of full server paths to any EED_Modules used by the addon |
|
| 454 | + 'module_paths' => isset($setup_args['module_paths']) |
|
| 455 | + ? (array) $setup_args['module_paths'] |
|
| 456 | + : array(), |
|
| 457 | + // array of full server paths to any EES_Shortcodes used by the addon |
|
| 458 | + 'shortcode_paths' => isset($setup_args['shortcode_paths']) |
|
| 459 | + ? (array) $setup_args['shortcode_paths'] |
|
| 460 | + : array(), |
|
| 461 | + 'shortcode_fqcns' => isset($setup_args['shortcode_fqcns']) |
|
| 462 | + ? (array) $setup_args['shortcode_fqcns'] |
|
| 463 | + : array(), |
|
| 464 | + // array of full server paths to any WP_Widgets used by the addon |
|
| 465 | + 'widget_paths' => isset($setup_args['widget_paths']) |
|
| 466 | + ? (array) $setup_args['widget_paths'] |
|
| 467 | + : array(), |
|
| 468 | + // array of PUE options used by the addon |
|
| 469 | + 'pue_options' => isset($setup_args['pue_options']) |
|
| 470 | + ? (array) $setup_args['pue_options'] |
|
| 471 | + : array(), |
|
| 472 | + 'message_types' => isset($setup_args['message_types']) |
|
| 473 | + ? (array) $setup_args['message_types'] |
|
| 474 | + : array(), |
|
| 475 | + 'capabilities' => isset($setup_args['capabilities']) |
|
| 476 | + ? (array) $setup_args['capabilities'] |
|
| 477 | + : array(), |
|
| 478 | + 'capability_maps' => isset($setup_args['capability_maps']) |
|
| 479 | + ? (array) $setup_args['capability_maps'] |
|
| 480 | + : array(), |
|
| 481 | + 'model_paths' => isset($setup_args['model_paths']) |
|
| 482 | + ? (array) $setup_args['model_paths'] |
|
| 483 | + : array(), |
|
| 484 | + 'class_paths' => isset($setup_args['class_paths']) |
|
| 485 | + ? (array) $setup_args['class_paths'] |
|
| 486 | + : array(), |
|
| 487 | + 'model_extension_paths' => isset($setup_args['model_extension_paths']) |
|
| 488 | + ? (array) $setup_args['model_extension_paths'] |
|
| 489 | + : array(), |
|
| 490 | + 'class_extension_paths' => isset($setup_args['class_extension_paths']) |
|
| 491 | + ? (array) $setup_args['class_extension_paths'] |
|
| 492 | + : array(), |
|
| 493 | + 'custom_post_types' => isset($setup_args['custom_post_types']) |
|
| 494 | + ? (array) $setup_args['custom_post_types'] |
|
| 495 | + : array(), |
|
| 496 | + 'custom_taxonomies' => isset($setup_args['custom_taxonomies']) |
|
| 497 | + ? (array) $setup_args['custom_taxonomies'] |
|
| 498 | + : array(), |
|
| 499 | + 'payment_method_paths' => isset($setup_args['payment_method_paths']) |
|
| 500 | + ? (array) $setup_args['payment_method_paths'] |
|
| 501 | + : array(), |
|
| 502 | + 'default_terms' => isset($setup_args['default_terms']) |
|
| 503 | + ? (array) $setup_args['default_terms'] |
|
| 504 | + : array(), |
|
| 505 | + // if not empty, inserts a new table row after this plugin's row on the WP Plugins page |
|
| 506 | + // that can be used for adding upgrading/marketing info |
|
| 507 | + 'plugins_page_row' => isset($setup_args['plugins_page_row']) |
|
| 508 | + ? $setup_args['plugins_page_row'] |
|
| 509 | + : '', |
|
| 510 | + 'namespace' => isset( |
|
| 511 | + $setup_args['namespace']['FQNS'], |
|
| 512 | + $setup_args['namespace']['DIR'] |
|
| 513 | + ) |
|
| 514 | + ? (array) $setup_args['namespace'] |
|
| 515 | + : array(), |
|
| 516 | + 'privacy_policies' => isset($setup_args['privacy_policies']) |
|
| 517 | + ? (array) $setup_args['privacy_policies'] |
|
| 518 | + : '', |
|
| 519 | + ); |
|
| 520 | + // if plugin_action_slug is NOT set, but an admin page path IS set, |
|
| 521 | + // then let's just use the plugin_slug since that will be used for linking to the admin page |
|
| 522 | + $addon_settings['plugin_action_slug'] = empty($addon_settings['plugin_action_slug']) |
|
| 523 | + && ! empty($addon_settings['admin_path']) |
|
| 524 | + ? $addon_settings['plugin_slug'] |
|
| 525 | + : $addon_settings['plugin_action_slug']; |
|
| 526 | + // full server path to main file (file loaded directly by WP) |
|
| 527 | + $addon_settings['plugin_basename'] = plugin_basename($addon_settings['main_file_path']); |
|
| 528 | + return $addon_settings; |
|
| 529 | + } |
|
| 530 | 530 | |
| 531 | 531 | |
| 532 | - /** |
|
| 533 | - * @param string $addon_name |
|
| 534 | - * @param array $addon_settings |
|
| 535 | - * @return boolean |
|
| 536 | - */ |
|
| 537 | - private static function _addon_is_compatible($addon_name, array $addon_settings) |
|
| 538 | - { |
|
| 539 | - global $wp_version; |
|
| 540 | - $incompatibility_message = ''; |
|
| 541 | - // check whether this addon version is compatible with EE core |
|
| 542 | - if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ]) |
|
| 543 | - && ! self::_meets_min_core_version_requirement( |
|
| 544 | - EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 545 | - $addon_settings['version'] |
|
| 546 | - ) |
|
| 547 | - ) { |
|
| 548 | - $incompatibility_message = sprintf( |
|
| 549 | - __( |
|
| 550 | - '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.', |
|
| 551 | - 'event_espresso' |
|
| 552 | - ), |
|
| 553 | - $addon_name, |
|
| 554 | - '<br />', |
|
| 555 | - EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 556 | - '<span style="font-weight: bold; color: #D54E21;">', |
|
| 557 | - '</span><br />' |
|
| 558 | - ); |
|
| 559 | - } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version()) |
|
| 560 | - ) { |
|
| 561 | - $incompatibility_message = sprintf( |
|
| 562 | - __( |
|
| 563 | - '%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".', |
|
| 564 | - 'event_espresso' |
|
| 565 | - ), |
|
| 566 | - $addon_name, |
|
| 567 | - self::_effective_version($addon_settings['min_core_version']), |
|
| 568 | - self::_effective_version(espresso_version()), |
|
| 569 | - '<br />', |
|
| 570 | - '<span style="font-weight: bold; color: #D54E21;">', |
|
| 571 | - '</span><br />' |
|
| 572 | - ); |
|
| 573 | - } elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) { |
|
| 574 | - $incompatibility_message = sprintf( |
|
| 575 | - __( |
|
| 576 | - '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.', |
|
| 577 | - 'event_espresso' |
|
| 578 | - ), |
|
| 579 | - $addon_name, |
|
| 580 | - $addon_settings['min_wp_version'], |
|
| 581 | - '<br />', |
|
| 582 | - '<span style="font-weight: bold; color: #D54E21;">', |
|
| 583 | - '</span><br />' |
|
| 584 | - ); |
|
| 585 | - } |
|
| 586 | - if (! empty($incompatibility_message)) { |
|
| 587 | - // remove 'activate' from the REQUEST |
|
| 588 | - // so WP doesn't erroneously tell the user the plugin activated fine when it didn't |
|
| 589 | - unset($_GET['activate'], $_REQUEST['activate']); |
|
| 590 | - if (current_user_can('activate_plugins')) { |
|
| 591 | - // show an error message indicating the plugin didn't activate properly |
|
| 592 | - EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__); |
|
| 593 | - } |
|
| 594 | - // BAIL FROM THE ADDON REGISTRATION PROCESS |
|
| 595 | - return false; |
|
| 596 | - } |
|
| 597 | - // addon IS compatible |
|
| 598 | - return true; |
|
| 599 | - } |
|
| 532 | + /** |
|
| 533 | + * @param string $addon_name |
|
| 534 | + * @param array $addon_settings |
|
| 535 | + * @return boolean |
|
| 536 | + */ |
|
| 537 | + private static function _addon_is_compatible($addon_name, array $addon_settings) |
|
| 538 | + { |
|
| 539 | + global $wp_version; |
|
| 540 | + $incompatibility_message = ''; |
|
| 541 | + // check whether this addon version is compatible with EE core |
|
| 542 | + if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ]) |
|
| 543 | + && ! self::_meets_min_core_version_requirement( |
|
| 544 | + EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 545 | + $addon_settings['version'] |
|
| 546 | + ) |
|
| 547 | + ) { |
|
| 548 | + $incompatibility_message = sprintf( |
|
| 549 | + __( |
|
| 550 | + '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon is not compatible with this version of Event Espresso.%2$sPlease upgrade your "%1$s" addon to version %3$s or newer to resolve this issue.', |
|
| 551 | + 'event_espresso' |
|
| 552 | + ), |
|
| 553 | + $addon_name, |
|
| 554 | + '<br />', |
|
| 555 | + EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 556 | + '<span style="font-weight: bold; color: #D54E21;">', |
|
| 557 | + '</span><br />' |
|
| 558 | + ); |
|
| 559 | + } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version()) |
|
| 560 | + ) { |
|
| 561 | + $incompatibility_message = sprintf( |
|
| 562 | + __( |
|
| 563 | + '%5$sIMPORTANT!%6$sThe Event Espresso "%1$s" addon requires Event Espresso Core version "%2$s" or higher in order to run.%4$sYour version of Event Espresso Core is currently at "%3$s". Please upgrade Event Espresso Core first and then re-activate "%1$s".', |
|
| 564 | + 'event_espresso' |
|
| 565 | + ), |
|
| 566 | + $addon_name, |
|
| 567 | + self::_effective_version($addon_settings['min_core_version']), |
|
| 568 | + self::_effective_version(espresso_version()), |
|
| 569 | + '<br />', |
|
| 570 | + '<span style="font-weight: bold; color: #D54E21;">', |
|
| 571 | + '</span><br />' |
|
| 572 | + ); |
|
| 573 | + } elseif (version_compare($wp_version, $addon_settings['min_wp_version'], '<')) { |
|
| 574 | + $incompatibility_message = sprintf( |
|
| 575 | + __( |
|
| 576 | + '%4$sIMPORTANT!%5$sThe Event Espresso "%1$s" addon requires WordPress version "%2$s" or greater.%3$sPlease update your version of WordPress to use the "%1$s" addon and to keep your site secure.', |
|
| 577 | + 'event_espresso' |
|
| 578 | + ), |
|
| 579 | + $addon_name, |
|
| 580 | + $addon_settings['min_wp_version'], |
|
| 581 | + '<br />', |
|
| 582 | + '<span style="font-weight: bold; color: #D54E21;">', |
|
| 583 | + '</span><br />' |
|
| 584 | + ); |
|
| 585 | + } |
|
| 586 | + if (! empty($incompatibility_message)) { |
|
| 587 | + // remove 'activate' from the REQUEST |
|
| 588 | + // so WP doesn't erroneously tell the user the plugin activated fine when it didn't |
|
| 589 | + unset($_GET['activate'], $_REQUEST['activate']); |
|
| 590 | + if (current_user_can('activate_plugins')) { |
|
| 591 | + // show an error message indicating the plugin didn't activate properly |
|
| 592 | + EE_Error::add_error($incompatibility_message, __FILE__, __FUNCTION__, __LINE__); |
|
| 593 | + } |
|
| 594 | + // BAIL FROM THE ADDON REGISTRATION PROCESS |
|
| 595 | + return false; |
|
| 596 | + } |
|
| 597 | + // addon IS compatible |
|
| 598 | + return true; |
|
| 599 | + } |
|
| 600 | 600 | |
| 601 | 601 | |
| 602 | - /** |
|
| 603 | - * if plugin update engine is being used for auto-updates, |
|
| 604 | - * then let's set that up now before going any further so that ALL addons can be updated |
|
| 605 | - * (not needed if PUE is not being used) |
|
| 606 | - * |
|
| 607 | - * @param string $addon_name |
|
| 608 | - * @param string $class_name |
|
| 609 | - * @param array $setup_args |
|
| 610 | - * @return void |
|
| 611 | - */ |
|
| 612 | - private static function _parse_pue_options($addon_name, $class_name, array $setup_args) |
|
| 613 | - { |
|
| 614 | - if (! empty($setup_args['pue_options'])) { |
|
| 615 | - self::$_settings[ $addon_name ]['pue_options'] = array( |
|
| 616 | - 'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug']) |
|
| 617 | - ? (string) $setup_args['pue_options']['pue_plugin_slug'] |
|
| 618 | - : 'espresso_' . strtolower($class_name), |
|
| 619 | - 'plugin_basename' => isset($setup_args['pue_options']['plugin_basename']) |
|
| 620 | - ? (string) $setup_args['pue_options']['plugin_basename'] |
|
| 621 | - : plugin_basename($setup_args['main_file_path']), |
|
| 622 | - 'checkPeriod' => isset($setup_args['pue_options']['checkPeriod']) |
|
| 623 | - ? (string) $setup_args['pue_options']['checkPeriod'] |
|
| 624 | - : '24', |
|
| 625 | - 'use_wp_update' => isset($setup_args['pue_options']['use_wp_update']) |
|
| 626 | - ? (string) $setup_args['pue_options']['use_wp_update'] |
|
| 627 | - : false, |
|
| 628 | - ); |
|
| 629 | - add_action( |
|
| 630 | - 'AHEE__EE_System__brew_espresso__after_pue_init', |
|
| 631 | - array('EE_Register_Addon', 'load_pue_update') |
|
| 632 | - ); |
|
| 633 | - } |
|
| 634 | - } |
|
| 602 | + /** |
|
| 603 | + * if plugin update engine is being used for auto-updates, |
|
| 604 | + * then let's set that up now before going any further so that ALL addons can be updated |
|
| 605 | + * (not needed if PUE is not being used) |
|
| 606 | + * |
|
| 607 | + * @param string $addon_name |
|
| 608 | + * @param string $class_name |
|
| 609 | + * @param array $setup_args |
|
| 610 | + * @return void |
|
| 611 | + */ |
|
| 612 | + private static function _parse_pue_options($addon_name, $class_name, array $setup_args) |
|
| 613 | + { |
|
| 614 | + if (! empty($setup_args['pue_options'])) { |
|
| 615 | + self::$_settings[ $addon_name ]['pue_options'] = array( |
|
| 616 | + 'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug']) |
|
| 617 | + ? (string) $setup_args['pue_options']['pue_plugin_slug'] |
|
| 618 | + : 'espresso_' . strtolower($class_name), |
|
| 619 | + 'plugin_basename' => isset($setup_args['pue_options']['plugin_basename']) |
|
| 620 | + ? (string) $setup_args['pue_options']['plugin_basename'] |
|
| 621 | + : plugin_basename($setup_args['main_file_path']), |
|
| 622 | + 'checkPeriod' => isset($setup_args['pue_options']['checkPeriod']) |
|
| 623 | + ? (string) $setup_args['pue_options']['checkPeriod'] |
|
| 624 | + : '24', |
|
| 625 | + 'use_wp_update' => isset($setup_args['pue_options']['use_wp_update']) |
|
| 626 | + ? (string) $setup_args['pue_options']['use_wp_update'] |
|
| 627 | + : false, |
|
| 628 | + ); |
|
| 629 | + add_action( |
|
| 630 | + 'AHEE__EE_System__brew_espresso__after_pue_init', |
|
| 631 | + array('EE_Register_Addon', 'load_pue_update') |
|
| 632 | + ); |
|
| 633 | + } |
|
| 634 | + } |
|
| 635 | 635 | |
| 636 | 636 | |
| 637 | - /** |
|
| 638 | - * register namespaces right away before any other files or classes get loaded, but AFTER the version checks |
|
| 639 | - * |
|
| 640 | - * @param array $addon_settings |
|
| 641 | - * @return void |
|
| 642 | - */ |
|
| 643 | - private static function _setup_namespaces(array $addon_settings) |
|
| 644 | - { |
|
| 645 | - // |
|
| 646 | - if (isset( |
|
| 647 | - $addon_settings['namespace']['FQNS'], |
|
| 648 | - $addon_settings['namespace']['DIR'] |
|
| 649 | - )) { |
|
| 650 | - EE_Psr4AutoloaderInit::psr4_loader()->addNamespace( |
|
| 651 | - $addon_settings['namespace']['FQNS'], |
|
| 652 | - $addon_settings['namespace']['DIR'] |
|
| 653 | - ); |
|
| 654 | - } |
|
| 655 | - } |
|
| 637 | + /** |
|
| 638 | + * register namespaces right away before any other files or classes get loaded, but AFTER the version checks |
|
| 639 | + * |
|
| 640 | + * @param array $addon_settings |
|
| 641 | + * @return void |
|
| 642 | + */ |
|
| 643 | + private static function _setup_namespaces(array $addon_settings) |
|
| 644 | + { |
|
| 645 | + // |
|
| 646 | + if (isset( |
|
| 647 | + $addon_settings['namespace']['FQNS'], |
|
| 648 | + $addon_settings['namespace']['DIR'] |
|
| 649 | + )) { |
|
| 650 | + EE_Psr4AutoloaderInit::psr4_loader()->addNamespace( |
|
| 651 | + $addon_settings['namespace']['FQNS'], |
|
| 652 | + $addon_settings['namespace']['DIR'] |
|
| 653 | + ); |
|
| 654 | + } |
|
| 655 | + } |
|
| 656 | 656 | |
| 657 | 657 | |
| 658 | - /** |
|
| 659 | - * @param string $addon_name |
|
| 660 | - * @param array $addon_settings |
|
| 661 | - * @return bool |
|
| 662 | - * @throws EE_Error |
|
| 663 | - * @throws InvalidArgumentException |
|
| 664 | - * @throws ReflectionException |
|
| 665 | - * @throws InvalidDataTypeException |
|
| 666 | - * @throws InvalidInterfaceException |
|
| 667 | - */ |
|
| 668 | - private static function _addon_activation($addon_name, array $addon_settings) |
|
| 669 | - { |
|
| 670 | - // this is an activation request |
|
| 671 | - if (did_action( |
|
| 672 | - 'activate_plugin' |
|
| 673 | - )) {// to find if THIS is the addon that was activated, just check if we have already registered it or not |
|
| 674 | - // (as the newly-activated addon wasn't around the first time addons were registered). |
|
| 675 | - // Note: the presence of pue_options in the addon registration options will initialize the $_settings |
|
| 676 | - // property for the add-on, but the add-on is only partially initialized. Hence, the additional check. |
|
| 677 | - if (! isset(self::$_settings[ $addon_name ]) |
|
| 678 | - || (isset(self::$_settings[ $addon_name ]) |
|
| 679 | - && ! isset(self::$_settings[ $addon_name ]['class_name']) |
|
| 680 | - ) |
|
| 681 | - ) { |
|
| 682 | - self::$_settings[ $addon_name ] = $addon_settings; |
|
| 683 | - $addon = self::_load_and_init_addon_class($addon_name); |
|
| 684 | - $addon->set_activation_indicator_option(); |
|
| 685 | - // dont bother setting up the rest of the addon. |
|
| 686 | - // we know it was just activated and the request will end soon |
|
| 687 | - } |
|
| 688 | - return true; |
|
| 689 | - } |
|
| 690 | - // make sure this was called in the right place! |
|
| 691 | - if (! did_action('AHEE__EE_System__load_espresso_addons') |
|
| 692 | - || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin') |
|
| 693 | - ) { |
|
| 694 | - EE_Error::doing_it_wrong( |
|
| 695 | - __METHOD__, |
|
| 696 | - sprintf( |
|
| 697 | - __( |
|
| 698 | - 'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time. Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.', |
|
| 699 | - 'event_espresso' |
|
| 700 | - ), |
|
| 701 | - $addon_name |
|
| 702 | - ), |
|
| 703 | - '4.3.0' |
|
| 704 | - ); |
|
| 705 | - } |
|
| 706 | - // make sure addon settings are set correctly without overwriting anything existing |
|
| 707 | - if (isset(self::$_settings[ $addon_name ])) { |
|
| 708 | - self::$_settings[ $addon_name ] += $addon_settings; |
|
| 709 | - } else { |
|
| 710 | - self::$_settings[ $addon_name ] = $addon_settings; |
|
| 711 | - } |
|
| 712 | - return false; |
|
| 713 | - } |
|
| 658 | + /** |
|
| 659 | + * @param string $addon_name |
|
| 660 | + * @param array $addon_settings |
|
| 661 | + * @return bool |
|
| 662 | + * @throws EE_Error |
|
| 663 | + * @throws InvalidArgumentException |
|
| 664 | + * @throws ReflectionException |
|
| 665 | + * @throws InvalidDataTypeException |
|
| 666 | + * @throws InvalidInterfaceException |
|
| 667 | + */ |
|
| 668 | + private static function _addon_activation($addon_name, array $addon_settings) |
|
| 669 | + { |
|
| 670 | + // this is an activation request |
|
| 671 | + if (did_action( |
|
| 672 | + 'activate_plugin' |
|
| 673 | + )) {// to find if THIS is the addon that was activated, just check if we have already registered it or not |
|
| 674 | + // (as the newly-activated addon wasn't around the first time addons were registered). |
|
| 675 | + // Note: the presence of pue_options in the addon registration options will initialize the $_settings |
|
| 676 | + // property for the add-on, but the add-on is only partially initialized. Hence, the additional check. |
|
| 677 | + if (! isset(self::$_settings[ $addon_name ]) |
|
| 678 | + || (isset(self::$_settings[ $addon_name ]) |
|
| 679 | + && ! isset(self::$_settings[ $addon_name ]['class_name']) |
|
| 680 | + ) |
|
| 681 | + ) { |
|
| 682 | + self::$_settings[ $addon_name ] = $addon_settings; |
|
| 683 | + $addon = self::_load_and_init_addon_class($addon_name); |
|
| 684 | + $addon->set_activation_indicator_option(); |
|
| 685 | + // dont bother setting up the rest of the addon. |
|
| 686 | + // we know it was just activated and the request will end soon |
|
| 687 | + } |
|
| 688 | + return true; |
|
| 689 | + } |
|
| 690 | + // make sure this was called in the right place! |
|
| 691 | + if (! did_action('AHEE__EE_System__load_espresso_addons') |
|
| 692 | + || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin') |
|
| 693 | + ) { |
|
| 694 | + EE_Error::doing_it_wrong( |
|
| 695 | + __METHOD__, |
|
| 696 | + sprintf( |
|
| 697 | + __( |
|
| 698 | + 'An attempt to register an EE_Addon named "%s" has failed because it was not registered at the correct time. Please use the "AHEE__EE_System__load_espresso_addons" hook to register addons.', |
|
| 699 | + 'event_espresso' |
|
| 700 | + ), |
|
| 701 | + $addon_name |
|
| 702 | + ), |
|
| 703 | + '4.3.0' |
|
| 704 | + ); |
|
| 705 | + } |
|
| 706 | + // make sure addon settings are set correctly without overwriting anything existing |
|
| 707 | + if (isset(self::$_settings[ $addon_name ])) { |
|
| 708 | + self::$_settings[ $addon_name ] += $addon_settings; |
|
| 709 | + } else { |
|
| 710 | + self::$_settings[ $addon_name ] = $addon_settings; |
|
| 711 | + } |
|
| 712 | + return false; |
|
| 713 | + } |
|
| 714 | 714 | |
| 715 | 715 | |
| 716 | - /** |
|
| 717 | - * @param string $addon_name |
|
| 718 | - * @return void |
|
| 719 | - * @throws EE_Error |
|
| 720 | - */ |
|
| 721 | - private static function _setup_autoloaders($addon_name) |
|
| 722 | - { |
|
| 723 | - if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) { |
|
| 724 | - // setup autoloader for single file |
|
| 725 | - EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']); |
|
| 726 | - } |
|
| 727 | - // setup autoloaders for folders |
|
| 728 | - if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) { |
|
| 729 | - foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) { |
|
| 730 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder); |
|
| 731 | - } |
|
| 732 | - } |
|
| 733 | - } |
|
| 716 | + /** |
|
| 717 | + * @param string $addon_name |
|
| 718 | + * @return void |
|
| 719 | + * @throws EE_Error |
|
| 720 | + */ |
|
| 721 | + private static function _setup_autoloaders($addon_name) |
|
| 722 | + { |
|
| 723 | + if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) { |
|
| 724 | + // setup autoloader for single file |
|
| 725 | + EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']); |
|
| 726 | + } |
|
| 727 | + // setup autoloaders for folders |
|
| 728 | + if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) { |
|
| 729 | + foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) { |
|
| 730 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder); |
|
| 731 | + } |
|
| 732 | + } |
|
| 733 | + } |
|
| 734 | 734 | |
| 735 | 735 | |
| 736 | - /** |
|
| 737 | - * register new models and extensions |
|
| 738 | - * |
|
| 739 | - * @param string $addon_name |
|
| 740 | - * @return void |
|
| 741 | - * @throws EE_Error |
|
| 742 | - */ |
|
| 743 | - private static function _register_models_and_extensions($addon_name) |
|
| 744 | - { |
|
| 745 | - // register new models |
|
| 746 | - if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 747 | - || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 748 | - ) { |
|
| 749 | - EE_Register_Model::register( |
|
| 750 | - $addon_name, |
|
| 751 | - array( |
|
| 752 | - 'model_paths' => self::$_settings[ $addon_name ]['model_paths'], |
|
| 753 | - 'class_paths' => self::$_settings[ $addon_name ]['class_paths'], |
|
| 754 | - ) |
|
| 755 | - ); |
|
| 756 | - } |
|
| 757 | - // register model extensions |
|
| 758 | - if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 759 | - || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 760 | - ) { |
|
| 761 | - EE_Register_Model_Extensions::register( |
|
| 762 | - $addon_name, |
|
| 763 | - array( |
|
| 764 | - 'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'], |
|
| 765 | - 'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'], |
|
| 766 | - ) |
|
| 767 | - ); |
|
| 768 | - } |
|
| 769 | - } |
|
| 736 | + /** |
|
| 737 | + * register new models and extensions |
|
| 738 | + * |
|
| 739 | + * @param string $addon_name |
|
| 740 | + * @return void |
|
| 741 | + * @throws EE_Error |
|
| 742 | + */ |
|
| 743 | + private static function _register_models_and_extensions($addon_name) |
|
| 744 | + { |
|
| 745 | + // register new models |
|
| 746 | + if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 747 | + || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 748 | + ) { |
|
| 749 | + EE_Register_Model::register( |
|
| 750 | + $addon_name, |
|
| 751 | + array( |
|
| 752 | + 'model_paths' => self::$_settings[ $addon_name ]['model_paths'], |
|
| 753 | + 'class_paths' => self::$_settings[ $addon_name ]['class_paths'], |
|
| 754 | + ) |
|
| 755 | + ); |
|
| 756 | + } |
|
| 757 | + // register model extensions |
|
| 758 | + if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 759 | + || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 760 | + ) { |
|
| 761 | + EE_Register_Model_Extensions::register( |
|
| 762 | + $addon_name, |
|
| 763 | + array( |
|
| 764 | + 'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'], |
|
| 765 | + 'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'], |
|
| 766 | + ) |
|
| 767 | + ); |
|
| 768 | + } |
|
| 769 | + } |
|
| 770 | 770 | |
| 771 | 771 | |
| 772 | - /** |
|
| 773 | - * @param string $addon_name |
|
| 774 | - * @return void |
|
| 775 | - * @throws EE_Error |
|
| 776 | - */ |
|
| 777 | - private static function _register_data_migration_scripts($addon_name) |
|
| 778 | - { |
|
| 779 | - // setup DMS |
|
| 780 | - if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 781 | - EE_Register_Data_Migration_Scripts::register( |
|
| 782 | - $addon_name, |
|
| 783 | - array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths']) |
|
| 784 | - ); |
|
| 785 | - } |
|
| 786 | - } |
|
| 772 | + /** |
|
| 773 | + * @param string $addon_name |
|
| 774 | + * @return void |
|
| 775 | + * @throws EE_Error |
|
| 776 | + */ |
|
| 777 | + private static function _register_data_migration_scripts($addon_name) |
|
| 778 | + { |
|
| 779 | + // setup DMS |
|
| 780 | + if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 781 | + EE_Register_Data_Migration_Scripts::register( |
|
| 782 | + $addon_name, |
|
| 783 | + array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths']) |
|
| 784 | + ); |
|
| 785 | + } |
|
| 786 | + } |
|
| 787 | 787 | |
| 788 | 788 | |
| 789 | - /** |
|
| 790 | - * @param string $addon_name |
|
| 791 | - * @return void |
|
| 792 | - * @throws EE_Error |
|
| 793 | - */ |
|
| 794 | - private static function _register_config($addon_name) |
|
| 795 | - { |
|
| 796 | - // if config_class is present let's register config. |
|
| 797 | - if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 798 | - EE_Register_Config::register( |
|
| 799 | - self::$_settings[ $addon_name ]['config_class'], |
|
| 800 | - array( |
|
| 801 | - 'config_section' => self::$_settings[ $addon_name ]['config_section'], |
|
| 802 | - 'config_name' => self::$_settings[ $addon_name ]['config_name'], |
|
| 803 | - ) |
|
| 804 | - ); |
|
| 805 | - } |
|
| 806 | - } |
|
| 789 | + /** |
|
| 790 | + * @param string $addon_name |
|
| 791 | + * @return void |
|
| 792 | + * @throws EE_Error |
|
| 793 | + */ |
|
| 794 | + private static function _register_config($addon_name) |
|
| 795 | + { |
|
| 796 | + // if config_class is present let's register config. |
|
| 797 | + if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 798 | + EE_Register_Config::register( |
|
| 799 | + self::$_settings[ $addon_name ]['config_class'], |
|
| 800 | + array( |
|
| 801 | + 'config_section' => self::$_settings[ $addon_name ]['config_section'], |
|
| 802 | + 'config_name' => self::$_settings[ $addon_name ]['config_name'], |
|
| 803 | + ) |
|
| 804 | + ); |
|
| 805 | + } |
|
| 806 | + } |
|
| 807 | 807 | |
| 808 | 808 | |
| 809 | - /** |
|
| 810 | - * @param string $addon_name |
|
| 811 | - * @return void |
|
| 812 | - * @throws EE_Error |
|
| 813 | - */ |
|
| 814 | - private static function _register_admin_pages($addon_name) |
|
| 815 | - { |
|
| 816 | - if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 817 | - EE_Register_Admin_Page::register( |
|
| 818 | - $addon_name, |
|
| 819 | - array('page_path' => self::$_settings[ $addon_name ]['admin_path']) |
|
| 820 | - ); |
|
| 821 | - } |
|
| 822 | - } |
|
| 809 | + /** |
|
| 810 | + * @param string $addon_name |
|
| 811 | + * @return void |
|
| 812 | + * @throws EE_Error |
|
| 813 | + */ |
|
| 814 | + private static function _register_admin_pages($addon_name) |
|
| 815 | + { |
|
| 816 | + if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 817 | + EE_Register_Admin_Page::register( |
|
| 818 | + $addon_name, |
|
| 819 | + array('page_path' => self::$_settings[ $addon_name ]['admin_path']) |
|
| 820 | + ); |
|
| 821 | + } |
|
| 822 | + } |
|
| 823 | 823 | |
| 824 | 824 | |
| 825 | - /** |
|
| 826 | - * @param string $addon_name |
|
| 827 | - * @return void |
|
| 828 | - * @throws EE_Error |
|
| 829 | - */ |
|
| 830 | - private static function _register_modules($addon_name) |
|
| 831 | - { |
|
| 832 | - if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 833 | - EE_Register_Module::register( |
|
| 834 | - $addon_name, |
|
| 835 | - array('module_paths' => self::$_settings[ $addon_name ]['module_paths']) |
|
| 836 | - ); |
|
| 837 | - } |
|
| 838 | - } |
|
| 825 | + /** |
|
| 826 | + * @param string $addon_name |
|
| 827 | + * @return void |
|
| 828 | + * @throws EE_Error |
|
| 829 | + */ |
|
| 830 | + private static function _register_modules($addon_name) |
|
| 831 | + { |
|
| 832 | + if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 833 | + EE_Register_Module::register( |
|
| 834 | + $addon_name, |
|
| 835 | + array('module_paths' => self::$_settings[ $addon_name ]['module_paths']) |
|
| 836 | + ); |
|
| 837 | + } |
|
| 838 | + } |
|
| 839 | 839 | |
| 840 | 840 | |
| 841 | - /** |
|
| 842 | - * @param string $addon_name |
|
| 843 | - * @return void |
|
| 844 | - * @throws EE_Error |
|
| 845 | - */ |
|
| 846 | - private static function _register_shortcodes($addon_name) |
|
| 847 | - { |
|
| 848 | - if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 849 | - || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 850 | - ) { |
|
| 851 | - EE_Register_Shortcode::register( |
|
| 852 | - $addon_name, |
|
| 853 | - array( |
|
| 854 | - 'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 855 | - ? self::$_settings[ $addon_name ]['shortcode_paths'] |
|
| 856 | - : array(), |
|
| 857 | - 'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 858 | - ? self::$_settings[ $addon_name ]['shortcode_fqcns'] |
|
| 859 | - : array(), |
|
| 860 | - ) |
|
| 861 | - ); |
|
| 862 | - } |
|
| 863 | - } |
|
| 841 | + /** |
|
| 842 | + * @param string $addon_name |
|
| 843 | + * @return void |
|
| 844 | + * @throws EE_Error |
|
| 845 | + */ |
|
| 846 | + private static function _register_shortcodes($addon_name) |
|
| 847 | + { |
|
| 848 | + if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 849 | + || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 850 | + ) { |
|
| 851 | + EE_Register_Shortcode::register( |
|
| 852 | + $addon_name, |
|
| 853 | + array( |
|
| 854 | + 'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 855 | + ? self::$_settings[ $addon_name ]['shortcode_paths'] |
|
| 856 | + : array(), |
|
| 857 | + 'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 858 | + ? self::$_settings[ $addon_name ]['shortcode_fqcns'] |
|
| 859 | + : array(), |
|
| 860 | + ) |
|
| 861 | + ); |
|
| 862 | + } |
|
| 863 | + } |
|
| 864 | 864 | |
| 865 | 865 | |
| 866 | - /** |
|
| 867 | - * @param string $addon_name |
|
| 868 | - * @return void |
|
| 869 | - * @throws EE_Error |
|
| 870 | - */ |
|
| 871 | - private static function _register_widgets($addon_name) |
|
| 872 | - { |
|
| 873 | - if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 874 | - EE_Register_Widget::register( |
|
| 875 | - $addon_name, |
|
| 876 | - array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths']) |
|
| 877 | - ); |
|
| 878 | - } |
|
| 879 | - } |
|
| 866 | + /** |
|
| 867 | + * @param string $addon_name |
|
| 868 | + * @return void |
|
| 869 | + * @throws EE_Error |
|
| 870 | + */ |
|
| 871 | + private static function _register_widgets($addon_name) |
|
| 872 | + { |
|
| 873 | + if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 874 | + EE_Register_Widget::register( |
|
| 875 | + $addon_name, |
|
| 876 | + array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths']) |
|
| 877 | + ); |
|
| 878 | + } |
|
| 879 | + } |
|
| 880 | 880 | |
| 881 | 881 | |
| 882 | - /** |
|
| 883 | - * @param string $addon_name |
|
| 884 | - * @return void |
|
| 885 | - * @throws EE_Error |
|
| 886 | - */ |
|
| 887 | - private static function _register_capabilities($addon_name) |
|
| 888 | - { |
|
| 889 | - if (! empty(self::$_settings[ $addon_name ]['capabilities'])) { |
|
| 890 | - EE_Register_Capabilities::register( |
|
| 891 | - $addon_name, |
|
| 892 | - array( |
|
| 893 | - 'capabilities' => self::$_settings[ $addon_name ]['capabilities'], |
|
| 894 | - 'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'], |
|
| 895 | - ) |
|
| 896 | - ); |
|
| 897 | - } |
|
| 898 | - } |
|
| 882 | + /** |
|
| 883 | + * @param string $addon_name |
|
| 884 | + * @return void |
|
| 885 | + * @throws EE_Error |
|
| 886 | + */ |
|
| 887 | + private static function _register_capabilities($addon_name) |
|
| 888 | + { |
|
| 889 | + if (! empty(self::$_settings[ $addon_name ]['capabilities'])) { |
|
| 890 | + EE_Register_Capabilities::register( |
|
| 891 | + $addon_name, |
|
| 892 | + array( |
|
| 893 | + 'capabilities' => self::$_settings[ $addon_name ]['capabilities'], |
|
| 894 | + 'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'], |
|
| 895 | + ) |
|
| 896 | + ); |
|
| 897 | + } |
|
| 898 | + } |
|
| 899 | 899 | |
| 900 | 900 | |
| 901 | - /** |
|
| 902 | - * @param string $addon_name |
|
| 903 | - * @return void |
|
| 904 | - * @throws EE_Error |
|
| 905 | - */ |
|
| 906 | - private static function _register_message_types($addon_name) |
|
| 907 | - { |
|
| 908 | - if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 909 | - add_action( |
|
| 910 | - 'EE_Brewing_Regular___messages_caf', |
|
| 911 | - array('EE_Register_Addon', 'register_message_types') |
|
| 912 | - ); |
|
| 913 | - } |
|
| 914 | - } |
|
| 901 | + /** |
|
| 902 | + * @param string $addon_name |
|
| 903 | + * @return void |
|
| 904 | + * @throws EE_Error |
|
| 905 | + */ |
|
| 906 | + private static function _register_message_types($addon_name) |
|
| 907 | + { |
|
| 908 | + if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 909 | + add_action( |
|
| 910 | + 'EE_Brewing_Regular___messages_caf', |
|
| 911 | + array('EE_Register_Addon', 'register_message_types') |
|
| 912 | + ); |
|
| 913 | + } |
|
| 914 | + } |
|
| 915 | 915 | |
| 916 | 916 | |
| 917 | - /** |
|
| 918 | - * @param string $addon_name |
|
| 919 | - * @return void |
|
| 920 | - * @throws EE_Error |
|
| 921 | - */ |
|
| 922 | - private static function _register_custom_post_types($addon_name) |
|
| 923 | - { |
|
| 924 | - if (! empty(self::$_settings[ $addon_name ]['custom_post_types']) |
|
| 925 | - || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies']) |
|
| 926 | - ) { |
|
| 927 | - EE_Register_CPT::register( |
|
| 928 | - $addon_name, |
|
| 929 | - array( |
|
| 930 | - 'cpts' => self::$_settings[ $addon_name ]['custom_post_types'], |
|
| 931 | - 'cts' => self::$_settings[ $addon_name ]['custom_taxonomies'], |
|
| 932 | - 'default_terms' => self::$_settings[ $addon_name ]['default_terms'], |
|
| 933 | - ) |
|
| 934 | - ); |
|
| 935 | - } |
|
| 936 | - } |
|
| 917 | + /** |
|
| 918 | + * @param string $addon_name |
|
| 919 | + * @return void |
|
| 920 | + * @throws EE_Error |
|
| 921 | + */ |
|
| 922 | + private static function _register_custom_post_types($addon_name) |
|
| 923 | + { |
|
| 924 | + if (! empty(self::$_settings[ $addon_name ]['custom_post_types']) |
|
| 925 | + || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies']) |
|
| 926 | + ) { |
|
| 927 | + EE_Register_CPT::register( |
|
| 928 | + $addon_name, |
|
| 929 | + array( |
|
| 930 | + 'cpts' => self::$_settings[ $addon_name ]['custom_post_types'], |
|
| 931 | + 'cts' => self::$_settings[ $addon_name ]['custom_taxonomies'], |
|
| 932 | + 'default_terms' => self::$_settings[ $addon_name ]['default_terms'], |
|
| 933 | + ) |
|
| 934 | + ); |
|
| 935 | + } |
|
| 936 | + } |
|
| 937 | 937 | |
| 938 | 938 | |
| 939 | - /** |
|
| 940 | - * @param string $addon_name |
|
| 941 | - * @return void |
|
| 942 | - * @throws InvalidArgumentException |
|
| 943 | - * @throws InvalidInterfaceException |
|
| 944 | - * @throws InvalidDataTypeException |
|
| 945 | - * @throws DomainException |
|
| 946 | - * @throws EE_Error |
|
| 947 | - */ |
|
| 948 | - private static function _register_payment_methods($addon_name) |
|
| 949 | - { |
|
| 950 | - if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 951 | - EE_Register_Payment_Method::register( |
|
| 952 | - $addon_name, |
|
| 953 | - array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths']) |
|
| 954 | - ); |
|
| 955 | - } |
|
| 956 | - } |
|
| 939 | + /** |
|
| 940 | + * @param string $addon_name |
|
| 941 | + * @return void |
|
| 942 | + * @throws InvalidArgumentException |
|
| 943 | + * @throws InvalidInterfaceException |
|
| 944 | + * @throws InvalidDataTypeException |
|
| 945 | + * @throws DomainException |
|
| 946 | + * @throws EE_Error |
|
| 947 | + */ |
|
| 948 | + private static function _register_payment_methods($addon_name) |
|
| 949 | + { |
|
| 950 | + if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 951 | + EE_Register_Payment_Method::register( |
|
| 952 | + $addon_name, |
|
| 953 | + array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths']) |
|
| 954 | + ); |
|
| 955 | + } |
|
| 956 | + } |
|
| 957 | 957 | |
| 958 | 958 | |
| 959 | - /** |
|
| 960 | - * @param string $addon_name |
|
| 961 | - * @return void |
|
| 962 | - * @throws InvalidArgumentException |
|
| 963 | - * @throws InvalidInterfaceException |
|
| 964 | - * @throws InvalidDataTypeException |
|
| 965 | - * @throws DomainException |
|
| 966 | - * @throws EE_Error |
|
| 967 | - */ |
|
| 968 | - private static function registerPrivacyPolicies($addon_name) |
|
| 969 | - { |
|
| 970 | - if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) { |
|
| 971 | - EE_Register_Privacy_Policy::register( |
|
| 972 | - $addon_name, |
|
| 973 | - self::$_settings[ $addon_name ]['privacy_policies'] |
|
| 974 | - ); |
|
| 975 | - } |
|
| 976 | - } |
|
| 959 | + /** |
|
| 960 | + * @param string $addon_name |
|
| 961 | + * @return void |
|
| 962 | + * @throws InvalidArgumentException |
|
| 963 | + * @throws InvalidInterfaceException |
|
| 964 | + * @throws InvalidDataTypeException |
|
| 965 | + * @throws DomainException |
|
| 966 | + * @throws EE_Error |
|
| 967 | + */ |
|
| 968 | + private static function registerPrivacyPolicies($addon_name) |
|
| 969 | + { |
|
| 970 | + if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) { |
|
| 971 | + EE_Register_Privacy_Policy::register( |
|
| 972 | + $addon_name, |
|
| 973 | + self::$_settings[ $addon_name ]['privacy_policies'] |
|
| 974 | + ); |
|
| 975 | + } |
|
| 976 | + } |
|
| 977 | 977 | |
| 978 | 978 | |
| 979 | - /** |
|
| 980 | - * @param string $addon_name |
|
| 981 | - * @return void |
|
| 982 | - */ |
|
| 983 | - private static function registerPersonalDataExporters($addon_name) |
|
| 984 | - { |
|
| 985 | - if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) { |
|
| 986 | - EE_Register_Personal_Data_Eraser::register( |
|
| 987 | - $addon_name, |
|
| 988 | - self::$_settings[ $addon_name ]['personal_data_exporters'] |
|
| 989 | - ); |
|
| 990 | - } |
|
| 991 | - } |
|
| 979 | + /** |
|
| 980 | + * @param string $addon_name |
|
| 981 | + * @return void |
|
| 982 | + */ |
|
| 983 | + private static function registerPersonalDataExporters($addon_name) |
|
| 984 | + { |
|
| 985 | + if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) { |
|
| 986 | + EE_Register_Personal_Data_Eraser::register( |
|
| 987 | + $addon_name, |
|
| 988 | + self::$_settings[ $addon_name ]['personal_data_exporters'] |
|
| 989 | + ); |
|
| 990 | + } |
|
| 991 | + } |
|
| 992 | 992 | |
| 993 | 993 | |
| 994 | - /** |
|
| 995 | - * @param string $addon_name |
|
| 996 | - * @return void |
|
| 997 | - */ |
|
| 998 | - private static function registerPersonalDataErasers($addon_name) |
|
| 999 | - { |
|
| 1000 | - if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) { |
|
| 1001 | - EE_Register_Personal_Data_Eraser::register( |
|
| 1002 | - $addon_name, |
|
| 1003 | - self::$_settings[ $addon_name ]['personal_data_erasers'] |
|
| 1004 | - ); |
|
| 1005 | - } |
|
| 1006 | - } |
|
| 994 | + /** |
|
| 995 | + * @param string $addon_name |
|
| 996 | + * @return void |
|
| 997 | + */ |
|
| 998 | + private static function registerPersonalDataErasers($addon_name) |
|
| 999 | + { |
|
| 1000 | + if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) { |
|
| 1001 | + EE_Register_Personal_Data_Eraser::register( |
|
| 1002 | + $addon_name, |
|
| 1003 | + self::$_settings[ $addon_name ]['personal_data_erasers'] |
|
| 1004 | + ); |
|
| 1005 | + } |
|
| 1006 | + } |
|
| 1007 | 1007 | |
| 1008 | 1008 | |
| 1009 | - /** |
|
| 1010 | - * Loads and instantiates the EE_Addon class and adds it onto the registry |
|
| 1011 | - * |
|
| 1012 | - * @param string $addon_name |
|
| 1013 | - * @return EE_Addon |
|
| 1014 | - * @throws InvalidArgumentException |
|
| 1015 | - * @throws InvalidInterfaceException |
|
| 1016 | - * @throws InvalidDataTypeException |
|
| 1017 | - * @throws ReflectionException |
|
| 1018 | - * @throws EE_Error |
|
| 1019 | - */ |
|
| 1020 | - private static function _load_and_init_addon_class($addon_name) |
|
| 1021 | - { |
|
| 1022 | - $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader(); |
|
| 1023 | - $addon = $loader->getShared( |
|
| 1024 | - self::$_settings[ $addon_name ]['class_name'], |
|
| 1025 | - array('EE_Registry::create(addon)' => true) |
|
| 1026 | - ); |
|
| 1027 | - // setter inject dep map if required |
|
| 1028 | - if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) { |
|
| 1029 | - $addon->setDependencyMap($loader->getShared('EE_Dependency_Map')); |
|
| 1030 | - } |
|
| 1031 | - // setter inject domain if required |
|
| 1032 | - if ($addon instanceof RequiresDomainInterface |
|
| 1033 | - && $addon->domain() === null |
|
| 1034 | - ) { |
|
| 1035 | - // using supplied Domain object |
|
| 1036 | - $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface |
|
| 1037 | - ? self::$_settings[ $addon_name ]['domain'] |
|
| 1038 | - : null; |
|
| 1039 | - // or construct one using Domain FQCN |
|
| 1040 | - if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') { |
|
| 1041 | - $domain = $loader->getShared( |
|
| 1042 | - self::$_settings[ $addon_name ]['domain_fqcn'], |
|
| 1043 | - array( |
|
| 1044 | - new EventEspresso\core\domain\values\FilePath( |
|
| 1045 | - self::$_settings[ $addon_name ]['main_file_path'] |
|
| 1046 | - ), |
|
| 1047 | - EventEspresso\core\domain\values\Version::fromString( |
|
| 1048 | - self::$_settings[ $addon_name ]['version'] |
|
| 1049 | - ), |
|
| 1050 | - ) |
|
| 1051 | - ); |
|
| 1052 | - } |
|
| 1053 | - if ($domain instanceof DomainInterface) { |
|
| 1054 | - $addon->setDomain($domain); |
|
| 1055 | - } |
|
| 1056 | - } |
|
| 1057 | - $addon->set_name($addon_name); |
|
| 1058 | - $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']); |
|
| 1059 | - $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']); |
|
| 1060 | - $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']); |
|
| 1061 | - $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']); |
|
| 1062 | - $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']); |
|
| 1063 | - $addon->set_version(self::$_settings[ $addon_name ]['version']); |
|
| 1064 | - $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version'])); |
|
| 1065 | - $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']); |
|
| 1066 | - $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']); |
|
| 1067 | - $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']); |
|
| 1068 | - // unfortunately this can't be hooked in upon construction, because we don't have |
|
| 1069 | - // the plugin mainfile's path upon construction. |
|
| 1070 | - register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation')); |
|
| 1071 | - // call any additional admin_callback functions during load_admin_controller hook |
|
| 1072 | - if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) { |
|
| 1073 | - add_action( |
|
| 1074 | - 'AHEE__EE_System__load_controllers__load_admin_controllers', |
|
| 1075 | - array($addon, self::$_settings[ $addon_name ]['admin_callback']) |
|
| 1076 | - ); |
|
| 1077 | - } |
|
| 1078 | - return $addon; |
|
| 1079 | - } |
|
| 1009 | + /** |
|
| 1010 | + * Loads and instantiates the EE_Addon class and adds it onto the registry |
|
| 1011 | + * |
|
| 1012 | + * @param string $addon_name |
|
| 1013 | + * @return EE_Addon |
|
| 1014 | + * @throws InvalidArgumentException |
|
| 1015 | + * @throws InvalidInterfaceException |
|
| 1016 | + * @throws InvalidDataTypeException |
|
| 1017 | + * @throws ReflectionException |
|
| 1018 | + * @throws EE_Error |
|
| 1019 | + */ |
|
| 1020 | + private static function _load_and_init_addon_class($addon_name) |
|
| 1021 | + { |
|
| 1022 | + $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader(); |
|
| 1023 | + $addon = $loader->getShared( |
|
| 1024 | + self::$_settings[ $addon_name ]['class_name'], |
|
| 1025 | + array('EE_Registry::create(addon)' => true) |
|
| 1026 | + ); |
|
| 1027 | + // setter inject dep map if required |
|
| 1028 | + if ($addon instanceof RequiresDependencyMapInterface && $addon->dependencyMap() === null) { |
|
| 1029 | + $addon->setDependencyMap($loader->getShared('EE_Dependency_Map')); |
|
| 1030 | + } |
|
| 1031 | + // setter inject domain if required |
|
| 1032 | + if ($addon instanceof RequiresDomainInterface |
|
| 1033 | + && $addon->domain() === null |
|
| 1034 | + ) { |
|
| 1035 | + // using supplied Domain object |
|
| 1036 | + $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface |
|
| 1037 | + ? self::$_settings[ $addon_name ]['domain'] |
|
| 1038 | + : null; |
|
| 1039 | + // or construct one using Domain FQCN |
|
| 1040 | + if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') { |
|
| 1041 | + $domain = $loader->getShared( |
|
| 1042 | + self::$_settings[ $addon_name ]['domain_fqcn'], |
|
| 1043 | + array( |
|
| 1044 | + new EventEspresso\core\domain\values\FilePath( |
|
| 1045 | + self::$_settings[ $addon_name ]['main_file_path'] |
|
| 1046 | + ), |
|
| 1047 | + EventEspresso\core\domain\values\Version::fromString( |
|
| 1048 | + self::$_settings[ $addon_name ]['version'] |
|
| 1049 | + ), |
|
| 1050 | + ) |
|
| 1051 | + ); |
|
| 1052 | + } |
|
| 1053 | + if ($domain instanceof DomainInterface) { |
|
| 1054 | + $addon->setDomain($domain); |
|
| 1055 | + } |
|
| 1056 | + } |
|
| 1057 | + $addon->set_name($addon_name); |
|
| 1058 | + $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']); |
|
| 1059 | + $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']); |
|
| 1060 | + $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']); |
|
| 1061 | + $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']); |
|
| 1062 | + $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']); |
|
| 1063 | + $addon->set_version(self::$_settings[ $addon_name ]['version']); |
|
| 1064 | + $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version'])); |
|
| 1065 | + $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']); |
|
| 1066 | + $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']); |
|
| 1067 | + $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']); |
|
| 1068 | + // unfortunately this can't be hooked in upon construction, because we don't have |
|
| 1069 | + // the plugin mainfile's path upon construction. |
|
| 1070 | + register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation')); |
|
| 1071 | + // call any additional admin_callback functions during load_admin_controller hook |
|
| 1072 | + if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) { |
|
| 1073 | + add_action( |
|
| 1074 | + 'AHEE__EE_System__load_controllers__load_admin_controllers', |
|
| 1075 | + array($addon, self::$_settings[ $addon_name ]['admin_callback']) |
|
| 1076 | + ); |
|
| 1077 | + } |
|
| 1078 | + return $addon; |
|
| 1079 | + } |
|
| 1080 | 1080 | |
| 1081 | 1081 | |
| 1082 | - /** |
|
| 1083 | - * load_pue_update - Update notifications |
|
| 1084 | - * |
|
| 1085 | - * @return void |
|
| 1086 | - * @throws InvalidArgumentException |
|
| 1087 | - * @throws InvalidDataTypeException |
|
| 1088 | - * @throws InvalidInterfaceException |
|
| 1089 | - */ |
|
| 1090 | - public static function load_pue_update() |
|
| 1091 | - { |
|
| 1092 | - // load PUE client |
|
| 1093 | - require_once EE_THIRD_PARTY . 'pue/pue-client.php'; |
|
| 1094 | - $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com'; |
|
| 1095 | - // cycle thru settings |
|
| 1096 | - foreach (self::$_settings as $settings) { |
|
| 1097 | - if (! empty($settings['pue_options'])) { |
|
| 1098 | - // initiate the class and start the plugin update engine! |
|
| 1099 | - new PluginUpdateEngineChecker( |
|
| 1100 | - // host file URL |
|
| 1101 | - $license_server, |
|
| 1102 | - // plugin slug(s) |
|
| 1103 | - array( |
|
| 1104 | - 'premium' => array('p' => $settings['pue_options']['pue_plugin_slug']), |
|
| 1105 | - 'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'), |
|
| 1106 | - ), |
|
| 1107 | - // options |
|
| 1108 | - array( |
|
| 1109 | - 'apikey' => EE_Registry::instance()->NET_CFG->core->site_license_key, |
|
| 1110 | - 'lang_domain' => 'event_espresso', |
|
| 1111 | - 'checkPeriod' => $settings['pue_options']['checkPeriod'], |
|
| 1112 | - 'option_key' => 'ee_site_license_key', |
|
| 1113 | - 'options_page_slug' => 'event_espresso', |
|
| 1114 | - 'plugin_basename' => $settings['pue_options']['plugin_basename'], |
|
| 1115 | - // if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP |
|
| 1116 | - 'use_wp_update' => $settings['pue_options']['use_wp_update'], |
|
| 1117 | - ) |
|
| 1118 | - ); |
|
| 1119 | - } |
|
| 1120 | - } |
|
| 1121 | - } |
|
| 1082 | + /** |
|
| 1083 | + * load_pue_update - Update notifications |
|
| 1084 | + * |
|
| 1085 | + * @return void |
|
| 1086 | + * @throws InvalidArgumentException |
|
| 1087 | + * @throws InvalidDataTypeException |
|
| 1088 | + * @throws InvalidInterfaceException |
|
| 1089 | + */ |
|
| 1090 | + public static function load_pue_update() |
|
| 1091 | + { |
|
| 1092 | + // load PUE client |
|
| 1093 | + require_once EE_THIRD_PARTY . 'pue/pue-client.php'; |
|
| 1094 | + $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com'; |
|
| 1095 | + // cycle thru settings |
|
| 1096 | + foreach (self::$_settings as $settings) { |
|
| 1097 | + if (! empty($settings['pue_options'])) { |
|
| 1098 | + // initiate the class and start the plugin update engine! |
|
| 1099 | + new PluginUpdateEngineChecker( |
|
| 1100 | + // host file URL |
|
| 1101 | + $license_server, |
|
| 1102 | + // plugin slug(s) |
|
| 1103 | + array( |
|
| 1104 | + 'premium' => array('p' => $settings['pue_options']['pue_plugin_slug']), |
|
| 1105 | + 'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'), |
|
| 1106 | + ), |
|
| 1107 | + // options |
|
| 1108 | + array( |
|
| 1109 | + 'apikey' => EE_Registry::instance()->NET_CFG->core->site_license_key, |
|
| 1110 | + 'lang_domain' => 'event_espresso', |
|
| 1111 | + 'checkPeriod' => $settings['pue_options']['checkPeriod'], |
|
| 1112 | + 'option_key' => 'ee_site_license_key', |
|
| 1113 | + 'options_page_slug' => 'event_espresso', |
|
| 1114 | + 'plugin_basename' => $settings['pue_options']['plugin_basename'], |
|
| 1115 | + // if use_wp_update is TRUE it means you want FREE versions of the plugin to be updated from WP |
|
| 1116 | + 'use_wp_update' => $settings['pue_options']['use_wp_update'], |
|
| 1117 | + ) |
|
| 1118 | + ); |
|
| 1119 | + } |
|
| 1120 | + } |
|
| 1121 | + } |
|
| 1122 | 1122 | |
| 1123 | 1123 | |
| 1124 | - /** |
|
| 1125 | - * Callback for EE_Brewing_Regular__messages_caf hook used to register message types. |
|
| 1126 | - * |
|
| 1127 | - * @since 4.4.0 |
|
| 1128 | - * @return void |
|
| 1129 | - * @throws EE_Error |
|
| 1130 | - */ |
|
| 1131 | - public static function register_message_types() |
|
| 1132 | - { |
|
| 1133 | - foreach (self::$_settings as $addon_name => $settings) { |
|
| 1134 | - if (! empty($settings['message_types'])) { |
|
| 1135 | - foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) { |
|
| 1136 | - EE_Register_Message_Type::register($message_type, $message_type_settings); |
|
| 1137 | - } |
|
| 1138 | - } |
|
| 1139 | - } |
|
| 1140 | - } |
|
| 1124 | + /** |
|
| 1125 | + * Callback for EE_Brewing_Regular__messages_caf hook used to register message types. |
|
| 1126 | + * |
|
| 1127 | + * @since 4.4.0 |
|
| 1128 | + * @return void |
|
| 1129 | + * @throws EE_Error |
|
| 1130 | + */ |
|
| 1131 | + public static function register_message_types() |
|
| 1132 | + { |
|
| 1133 | + foreach (self::$_settings as $addon_name => $settings) { |
|
| 1134 | + if (! empty($settings['message_types'])) { |
|
| 1135 | + foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) { |
|
| 1136 | + EE_Register_Message_Type::register($message_type, $message_type_settings); |
|
| 1137 | + } |
|
| 1138 | + } |
|
| 1139 | + } |
|
| 1140 | + } |
|
| 1141 | 1141 | |
| 1142 | 1142 | |
| 1143 | - /** |
|
| 1144 | - * This deregisters an addon that was previously registered with a specific addon_name. |
|
| 1145 | - * |
|
| 1146 | - * @since 4.3.0 |
|
| 1147 | - * @param string $addon_name the name for the addon that was previously registered |
|
| 1148 | - * @throws DomainException |
|
| 1149 | - * @throws EE_Error |
|
| 1150 | - * @throws InvalidArgumentException |
|
| 1151 | - * @throws InvalidDataTypeException |
|
| 1152 | - * @throws InvalidInterfaceException |
|
| 1153 | - */ |
|
| 1154 | - public static function deregister($addon_name = null) |
|
| 1155 | - { |
|
| 1156 | - if (isset(self::$_settings[ $addon_name ]['class_name'])) { |
|
| 1157 | - try { |
|
| 1158 | - do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name); |
|
| 1159 | - $class_name = self::$_settings[ $addon_name ]['class_name']; |
|
| 1160 | - if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 1161 | - // setup DMS |
|
| 1162 | - EE_Register_Data_Migration_Scripts::deregister($addon_name); |
|
| 1163 | - } |
|
| 1164 | - if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 1165 | - // register admin page |
|
| 1166 | - EE_Register_Admin_Page::deregister($addon_name); |
|
| 1167 | - } |
|
| 1168 | - if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 1169 | - // add to list of modules to be registered |
|
| 1170 | - EE_Register_Module::deregister($addon_name); |
|
| 1171 | - } |
|
| 1172 | - if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 1173 | - || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 1174 | - ) { |
|
| 1175 | - // add to list of shortcodes to be registered |
|
| 1176 | - EE_Register_Shortcode::deregister($addon_name); |
|
| 1177 | - } |
|
| 1178 | - if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 1179 | - // if config_class present let's register config. |
|
| 1180 | - EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']); |
|
| 1181 | - } |
|
| 1182 | - if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 1183 | - // add to list of widgets to be registered |
|
| 1184 | - EE_Register_Widget::deregister($addon_name); |
|
| 1185 | - } |
|
| 1186 | - if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 1187 | - || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 1188 | - ) { |
|
| 1189 | - // add to list of shortcodes to be registered |
|
| 1190 | - EE_Register_Model::deregister($addon_name); |
|
| 1191 | - } |
|
| 1192 | - if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 1193 | - || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 1194 | - ) { |
|
| 1195 | - // add to list of shortcodes to be registered |
|
| 1196 | - EE_Register_Model_Extensions::deregister($addon_name); |
|
| 1197 | - } |
|
| 1198 | - if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 1199 | - foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) { |
|
| 1200 | - EE_Register_Message_Type::deregister($message_type); |
|
| 1201 | - } |
|
| 1202 | - } |
|
| 1203 | - // deregister capabilities for addon |
|
| 1204 | - if (! empty(self::$_settings[ $addon_name ]['capabilities']) |
|
| 1205 | - || ! empty(self::$_settings[ $addon_name ]['capability_maps']) |
|
| 1206 | - ) { |
|
| 1207 | - EE_Register_Capabilities::deregister($addon_name); |
|
| 1208 | - } |
|
| 1209 | - // deregister custom_post_types for addon |
|
| 1210 | - if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) { |
|
| 1211 | - EE_Register_CPT::deregister($addon_name); |
|
| 1212 | - } |
|
| 1213 | - if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 1214 | - EE_Register_Payment_Method::deregister($addon_name); |
|
| 1215 | - } |
|
| 1216 | - $addon = EE_Registry::instance()->getAddon($class_name); |
|
| 1217 | - if ($addon instanceof EE_Addon) { |
|
| 1218 | - remove_action( |
|
| 1219 | - 'deactivate_' . $addon->get_main_plugin_file_basename(), |
|
| 1220 | - array($addon, 'deactivation') |
|
| 1221 | - ); |
|
| 1222 | - remove_action( |
|
| 1223 | - 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
| 1224 | - array($addon, 'initialize_db_if_no_migrations_required') |
|
| 1225 | - ); |
|
| 1226 | - // remove `after_registration` call |
|
| 1227 | - remove_action( |
|
| 1228 | - 'AHEE__EE_System__load_espresso_addons__complete', |
|
| 1229 | - array($addon, 'after_registration'), |
|
| 1230 | - 999 |
|
| 1231 | - ); |
|
| 1232 | - } |
|
| 1233 | - EE_Registry::instance()->removeAddon($class_name); |
|
| 1234 | - } catch (OutOfBoundsException $addon_not_yet_registered_exception) { |
|
| 1235 | - // the add-on was not yet registered in the registry, |
|
| 1236 | - // so RegistryContainer::__get() throws this exception. |
|
| 1237 | - // also no need to worry about this or log it, |
|
| 1238 | - // it's ok to deregister an add-on before its registered in the registry |
|
| 1239 | - } catch (Exception $e) { |
|
| 1240 | - new ExceptionLogger($e); |
|
| 1241 | - } |
|
| 1242 | - unset(self::$_settings[ $addon_name ]); |
|
| 1243 | - do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name); |
|
| 1244 | - } |
|
| 1245 | - } |
|
| 1143 | + /** |
|
| 1144 | + * This deregisters an addon that was previously registered with a specific addon_name. |
|
| 1145 | + * |
|
| 1146 | + * @since 4.3.0 |
|
| 1147 | + * @param string $addon_name the name for the addon that was previously registered |
|
| 1148 | + * @throws DomainException |
|
| 1149 | + * @throws EE_Error |
|
| 1150 | + * @throws InvalidArgumentException |
|
| 1151 | + * @throws InvalidDataTypeException |
|
| 1152 | + * @throws InvalidInterfaceException |
|
| 1153 | + */ |
|
| 1154 | + public static function deregister($addon_name = null) |
|
| 1155 | + { |
|
| 1156 | + if (isset(self::$_settings[ $addon_name ]['class_name'])) { |
|
| 1157 | + try { |
|
| 1158 | + do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name); |
|
| 1159 | + $class_name = self::$_settings[ $addon_name ]['class_name']; |
|
| 1160 | + if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 1161 | + // setup DMS |
|
| 1162 | + EE_Register_Data_Migration_Scripts::deregister($addon_name); |
|
| 1163 | + } |
|
| 1164 | + if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 1165 | + // register admin page |
|
| 1166 | + EE_Register_Admin_Page::deregister($addon_name); |
|
| 1167 | + } |
|
| 1168 | + if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 1169 | + // add to list of modules to be registered |
|
| 1170 | + EE_Register_Module::deregister($addon_name); |
|
| 1171 | + } |
|
| 1172 | + if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 1173 | + || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 1174 | + ) { |
|
| 1175 | + // add to list of shortcodes to be registered |
|
| 1176 | + EE_Register_Shortcode::deregister($addon_name); |
|
| 1177 | + } |
|
| 1178 | + if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 1179 | + // if config_class present let's register config. |
|
| 1180 | + EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']); |
|
| 1181 | + } |
|
| 1182 | + if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 1183 | + // add to list of widgets to be registered |
|
| 1184 | + EE_Register_Widget::deregister($addon_name); |
|
| 1185 | + } |
|
| 1186 | + if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 1187 | + || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 1188 | + ) { |
|
| 1189 | + // add to list of shortcodes to be registered |
|
| 1190 | + EE_Register_Model::deregister($addon_name); |
|
| 1191 | + } |
|
| 1192 | + if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 1193 | + || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 1194 | + ) { |
|
| 1195 | + // add to list of shortcodes to be registered |
|
| 1196 | + EE_Register_Model_Extensions::deregister($addon_name); |
|
| 1197 | + } |
|
| 1198 | + if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 1199 | + foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) { |
|
| 1200 | + EE_Register_Message_Type::deregister($message_type); |
|
| 1201 | + } |
|
| 1202 | + } |
|
| 1203 | + // deregister capabilities for addon |
|
| 1204 | + if (! empty(self::$_settings[ $addon_name ]['capabilities']) |
|
| 1205 | + || ! empty(self::$_settings[ $addon_name ]['capability_maps']) |
|
| 1206 | + ) { |
|
| 1207 | + EE_Register_Capabilities::deregister($addon_name); |
|
| 1208 | + } |
|
| 1209 | + // deregister custom_post_types for addon |
|
| 1210 | + if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) { |
|
| 1211 | + EE_Register_CPT::deregister($addon_name); |
|
| 1212 | + } |
|
| 1213 | + if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 1214 | + EE_Register_Payment_Method::deregister($addon_name); |
|
| 1215 | + } |
|
| 1216 | + $addon = EE_Registry::instance()->getAddon($class_name); |
|
| 1217 | + if ($addon instanceof EE_Addon) { |
|
| 1218 | + remove_action( |
|
| 1219 | + 'deactivate_' . $addon->get_main_plugin_file_basename(), |
|
| 1220 | + array($addon, 'deactivation') |
|
| 1221 | + ); |
|
| 1222 | + remove_action( |
|
| 1223 | + 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
| 1224 | + array($addon, 'initialize_db_if_no_migrations_required') |
|
| 1225 | + ); |
|
| 1226 | + // remove `after_registration` call |
|
| 1227 | + remove_action( |
|
| 1228 | + 'AHEE__EE_System__load_espresso_addons__complete', |
|
| 1229 | + array($addon, 'after_registration'), |
|
| 1230 | + 999 |
|
| 1231 | + ); |
|
| 1232 | + } |
|
| 1233 | + EE_Registry::instance()->removeAddon($class_name); |
|
| 1234 | + } catch (OutOfBoundsException $addon_not_yet_registered_exception) { |
|
| 1235 | + // the add-on was not yet registered in the registry, |
|
| 1236 | + // so RegistryContainer::__get() throws this exception. |
|
| 1237 | + // also no need to worry about this or log it, |
|
| 1238 | + // it's ok to deregister an add-on before its registered in the registry |
|
| 1239 | + } catch (Exception $e) { |
|
| 1240 | + new ExceptionLogger($e); |
|
| 1241 | + } |
|
| 1242 | + unset(self::$_settings[ $addon_name ]); |
|
| 1243 | + do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name); |
|
| 1244 | + } |
|
| 1245 | + } |
|
| 1246 | 1246 | } |
@@ -69,15 +69,15 @@ discard block |
||
| 69 | 69 | // offsets: 0 . 1 . 2 . 3 . 4 |
| 70 | 70 | $version_parts = explode('.', $min_core_version); |
| 71 | 71 | // check they specified the micro version (after 2nd period) |
| 72 | - if (! isset($version_parts[2])) { |
|
| 72 | + if ( ! isset($version_parts[2])) { |
|
| 73 | 73 | $version_parts[2] = '0'; |
| 74 | 74 | } |
| 75 | 75 | // if they didn't specify the 'p', or 'rc' part. Just assume the lowest possible |
| 76 | 76 | // soon we can assume that's 'rc', but this current version is 'alpha' |
| 77 | - if (! isset($version_parts[3])) { |
|
| 77 | + if ( ! isset($version_parts[3])) { |
|
| 78 | 78 | $version_parts[3] = 'dev'; |
| 79 | 79 | } |
| 80 | - if (! isset($version_parts[4])) { |
|
| 80 | + if ( ! isset($version_parts[4])) { |
|
| 81 | 81 | $version_parts[4] = '000'; |
| 82 | 82 | } |
| 83 | 83 | return implode('.', $version_parts); |
@@ -264,7 +264,7 @@ discard block |
||
| 264 | 264 | // setup PUE |
| 265 | 265 | EE_Register_Addon::_parse_pue_options($addon_name, $class_name, $setup_args); |
| 266 | 266 | // does this addon work with this version of core or WordPress ? |
| 267 | - if (! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) { |
|
| 267 | + if ( ! EE_Register_Addon::_addon_is_compatible($addon_name, $addon_settings)) { |
|
| 268 | 268 | return; |
| 269 | 269 | } |
| 270 | 270 | // register namespaces |
@@ -328,7 +328,7 @@ discard block |
||
| 328 | 328 | ) |
| 329 | 329 | ); |
| 330 | 330 | } |
| 331 | - if (! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) { |
|
| 331 | + if ( ! isset($setup_args['main_file_path']) || empty($setup_args['main_file_path'])) { |
|
| 332 | 332 | throw new EE_Error( |
| 333 | 333 | sprintf( |
| 334 | 334 | __( |
@@ -340,7 +340,7 @@ discard block |
||
| 340 | 340 | ); |
| 341 | 341 | } |
| 342 | 342 | // check that addon has not already been registered with that name |
| 343 | - if (isset(self::$_settings[ $addon_name ]) && ! did_action('activate_plugin')) { |
|
| 343 | + if (isset(self::$_settings[$addon_name]) && ! did_action('activate_plugin')) { |
|
| 344 | 344 | throw new EE_Error( |
| 345 | 345 | sprintf( |
| 346 | 346 | __( |
@@ -372,7 +372,7 @@ discard block |
||
| 372 | 372 | // check if classname is fully qualified or is a legacy classname already prefixed with 'EE_' |
| 373 | 373 | return strpos($class_name, '\\') || strpos($class_name, 'EE_') === 0 |
| 374 | 374 | ? $class_name |
| 375 | - : 'EE_' . $class_name; |
|
| 375 | + : 'EE_'.$class_name; |
|
| 376 | 376 | } |
| 377 | 377 | |
| 378 | 378 | |
@@ -539,9 +539,9 @@ discard block |
||
| 539 | 539 | global $wp_version; |
| 540 | 540 | $incompatibility_message = ''; |
| 541 | 541 | // check whether this addon version is compatible with EE core |
| 542 | - if (isset(EE_Register_Addon::$_incompatible_addons[ $addon_name ]) |
|
| 542 | + if (isset(EE_Register_Addon::$_incompatible_addons[$addon_name]) |
|
| 543 | 543 | && ! self::_meets_min_core_version_requirement( |
| 544 | - EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 544 | + EE_Register_Addon::$_incompatible_addons[$addon_name], |
|
| 545 | 545 | $addon_settings['version'] |
| 546 | 546 | ) |
| 547 | 547 | ) { |
@@ -552,11 +552,11 @@ discard block |
||
| 552 | 552 | ), |
| 553 | 553 | $addon_name, |
| 554 | 554 | '<br />', |
| 555 | - EE_Register_Addon::$_incompatible_addons[ $addon_name ], |
|
| 555 | + EE_Register_Addon::$_incompatible_addons[$addon_name], |
|
| 556 | 556 | '<span style="font-weight: bold; color: #D54E21;">', |
| 557 | 557 | '</span><br />' |
| 558 | 558 | ); |
| 559 | - } elseif (! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version()) |
|
| 559 | + } elseif ( ! self::_meets_min_core_version_requirement($addon_settings['min_core_version'], espresso_version()) |
|
| 560 | 560 | ) { |
| 561 | 561 | $incompatibility_message = sprintf( |
| 562 | 562 | __( |
@@ -583,7 +583,7 @@ discard block |
||
| 583 | 583 | '</span><br />' |
| 584 | 584 | ); |
| 585 | 585 | } |
| 586 | - if (! empty($incompatibility_message)) { |
|
| 586 | + if ( ! empty($incompatibility_message)) { |
|
| 587 | 587 | // remove 'activate' from the REQUEST |
| 588 | 588 | // so WP doesn't erroneously tell the user the plugin activated fine when it didn't |
| 589 | 589 | unset($_GET['activate'], $_REQUEST['activate']); |
@@ -611,11 +611,11 @@ discard block |
||
| 611 | 611 | */ |
| 612 | 612 | private static function _parse_pue_options($addon_name, $class_name, array $setup_args) |
| 613 | 613 | { |
| 614 | - if (! empty($setup_args['pue_options'])) { |
|
| 615 | - self::$_settings[ $addon_name ]['pue_options'] = array( |
|
| 614 | + if ( ! empty($setup_args['pue_options'])) { |
|
| 615 | + self::$_settings[$addon_name]['pue_options'] = array( |
|
| 616 | 616 | 'pue_plugin_slug' => isset($setup_args['pue_options']['pue_plugin_slug']) |
| 617 | 617 | ? (string) $setup_args['pue_options']['pue_plugin_slug'] |
| 618 | - : 'espresso_' . strtolower($class_name), |
|
| 618 | + : 'espresso_'.strtolower($class_name), |
|
| 619 | 619 | 'plugin_basename' => isset($setup_args['pue_options']['plugin_basename']) |
| 620 | 620 | ? (string) $setup_args['pue_options']['plugin_basename'] |
| 621 | 621 | : plugin_basename($setup_args['main_file_path']), |
@@ -674,12 +674,12 @@ discard block |
||
| 674 | 674 | // (as the newly-activated addon wasn't around the first time addons were registered). |
| 675 | 675 | // Note: the presence of pue_options in the addon registration options will initialize the $_settings |
| 676 | 676 | // property for the add-on, but the add-on is only partially initialized. Hence, the additional check. |
| 677 | - if (! isset(self::$_settings[ $addon_name ]) |
|
| 678 | - || (isset(self::$_settings[ $addon_name ]) |
|
| 679 | - && ! isset(self::$_settings[ $addon_name ]['class_name']) |
|
| 677 | + if ( ! isset(self::$_settings[$addon_name]) |
|
| 678 | + || (isset(self::$_settings[$addon_name]) |
|
| 679 | + && ! isset(self::$_settings[$addon_name]['class_name']) |
|
| 680 | 680 | ) |
| 681 | 681 | ) { |
| 682 | - self::$_settings[ $addon_name ] = $addon_settings; |
|
| 682 | + self::$_settings[$addon_name] = $addon_settings; |
|
| 683 | 683 | $addon = self::_load_and_init_addon_class($addon_name); |
| 684 | 684 | $addon->set_activation_indicator_option(); |
| 685 | 685 | // dont bother setting up the rest of the addon. |
@@ -688,7 +688,7 @@ discard block |
||
| 688 | 688 | return true; |
| 689 | 689 | } |
| 690 | 690 | // make sure this was called in the right place! |
| 691 | - if (! did_action('AHEE__EE_System__load_espresso_addons') |
|
| 691 | + if ( ! did_action('AHEE__EE_System__load_espresso_addons') |
|
| 692 | 692 | || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin') |
| 693 | 693 | ) { |
| 694 | 694 | EE_Error::doing_it_wrong( |
@@ -704,10 +704,10 @@ discard block |
||
| 704 | 704 | ); |
| 705 | 705 | } |
| 706 | 706 | // make sure addon settings are set correctly without overwriting anything existing |
| 707 | - if (isset(self::$_settings[ $addon_name ])) { |
|
| 708 | - self::$_settings[ $addon_name ] += $addon_settings; |
|
| 707 | + if (isset(self::$_settings[$addon_name])) { |
|
| 708 | + self::$_settings[$addon_name] += $addon_settings; |
|
| 709 | 709 | } else { |
| 710 | - self::$_settings[ $addon_name ] = $addon_settings; |
|
| 710 | + self::$_settings[$addon_name] = $addon_settings; |
|
| 711 | 711 | } |
| 712 | 712 | return false; |
| 713 | 713 | } |
@@ -720,13 +720,13 @@ discard block |
||
| 720 | 720 | */ |
| 721 | 721 | private static function _setup_autoloaders($addon_name) |
| 722 | 722 | { |
| 723 | - if (! empty(self::$_settings[ $addon_name ]['autoloader_paths'])) { |
|
| 723 | + if ( ! empty(self::$_settings[$addon_name]['autoloader_paths'])) { |
|
| 724 | 724 | // setup autoloader for single file |
| 725 | - EEH_Autoloader::instance()->register_autoloader(self::$_settings[ $addon_name ]['autoloader_paths']); |
|
| 725 | + EEH_Autoloader::instance()->register_autoloader(self::$_settings[$addon_name]['autoloader_paths']); |
|
| 726 | 726 | } |
| 727 | 727 | // setup autoloaders for folders |
| 728 | - if (! empty(self::$_settings[ $addon_name ]['autoloader_folders'])) { |
|
| 729 | - foreach ((array) self::$_settings[ $addon_name ]['autoloader_folders'] as $autoloader_folder) { |
|
| 728 | + if ( ! empty(self::$_settings[$addon_name]['autoloader_folders'])) { |
|
| 729 | + foreach ((array) self::$_settings[$addon_name]['autoloader_folders'] as $autoloader_folder) { |
|
| 730 | 730 | EEH_Autoloader::register_autoloaders_for_each_file_in_folder($autoloader_folder); |
| 731 | 731 | } |
| 732 | 732 | } |
@@ -743,26 +743,26 @@ discard block |
||
| 743 | 743 | private static function _register_models_and_extensions($addon_name) |
| 744 | 744 | { |
| 745 | 745 | // register new models |
| 746 | - if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 747 | - || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 746 | + if ( ! empty(self::$_settings[$addon_name]['model_paths']) |
|
| 747 | + || ! empty(self::$_settings[$addon_name]['class_paths']) |
|
| 748 | 748 | ) { |
| 749 | 749 | EE_Register_Model::register( |
| 750 | 750 | $addon_name, |
| 751 | 751 | array( |
| 752 | - 'model_paths' => self::$_settings[ $addon_name ]['model_paths'], |
|
| 753 | - 'class_paths' => self::$_settings[ $addon_name ]['class_paths'], |
|
| 752 | + 'model_paths' => self::$_settings[$addon_name]['model_paths'], |
|
| 753 | + 'class_paths' => self::$_settings[$addon_name]['class_paths'], |
|
| 754 | 754 | ) |
| 755 | 755 | ); |
| 756 | 756 | } |
| 757 | 757 | // register model extensions |
| 758 | - if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 759 | - || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 758 | + if ( ! empty(self::$_settings[$addon_name]['model_extension_paths']) |
|
| 759 | + || ! empty(self::$_settings[$addon_name]['class_extension_paths']) |
|
| 760 | 760 | ) { |
| 761 | 761 | EE_Register_Model_Extensions::register( |
| 762 | 762 | $addon_name, |
| 763 | 763 | array( |
| 764 | - 'model_extension_paths' => self::$_settings[ $addon_name ]['model_extension_paths'], |
|
| 765 | - 'class_extension_paths' => self::$_settings[ $addon_name ]['class_extension_paths'], |
|
| 764 | + 'model_extension_paths' => self::$_settings[$addon_name]['model_extension_paths'], |
|
| 765 | + 'class_extension_paths' => self::$_settings[$addon_name]['class_extension_paths'], |
|
| 766 | 766 | ) |
| 767 | 767 | ); |
| 768 | 768 | } |
@@ -777,10 +777,10 @@ discard block |
||
| 777 | 777 | private static function _register_data_migration_scripts($addon_name) |
| 778 | 778 | { |
| 779 | 779 | // setup DMS |
| 780 | - if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 780 | + if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) { |
|
| 781 | 781 | EE_Register_Data_Migration_Scripts::register( |
| 782 | 782 | $addon_name, |
| 783 | - array('dms_paths' => self::$_settings[ $addon_name ]['dms_paths']) |
|
| 783 | + array('dms_paths' => self::$_settings[$addon_name]['dms_paths']) |
|
| 784 | 784 | ); |
| 785 | 785 | } |
| 786 | 786 | } |
@@ -794,12 +794,12 @@ discard block |
||
| 794 | 794 | private static function _register_config($addon_name) |
| 795 | 795 | { |
| 796 | 796 | // if config_class is present let's register config. |
| 797 | - if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 797 | + if ( ! empty(self::$_settings[$addon_name]['config_class'])) { |
|
| 798 | 798 | EE_Register_Config::register( |
| 799 | - self::$_settings[ $addon_name ]['config_class'], |
|
| 799 | + self::$_settings[$addon_name]['config_class'], |
|
| 800 | 800 | array( |
| 801 | - 'config_section' => self::$_settings[ $addon_name ]['config_section'], |
|
| 802 | - 'config_name' => self::$_settings[ $addon_name ]['config_name'], |
|
| 801 | + 'config_section' => self::$_settings[$addon_name]['config_section'], |
|
| 802 | + 'config_name' => self::$_settings[$addon_name]['config_name'], |
|
| 803 | 803 | ) |
| 804 | 804 | ); |
| 805 | 805 | } |
@@ -813,10 +813,10 @@ discard block |
||
| 813 | 813 | */ |
| 814 | 814 | private static function _register_admin_pages($addon_name) |
| 815 | 815 | { |
| 816 | - if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 816 | + if ( ! empty(self::$_settings[$addon_name]['admin_path'])) { |
|
| 817 | 817 | EE_Register_Admin_Page::register( |
| 818 | 818 | $addon_name, |
| 819 | - array('page_path' => self::$_settings[ $addon_name ]['admin_path']) |
|
| 819 | + array('page_path' => self::$_settings[$addon_name]['admin_path']) |
|
| 820 | 820 | ); |
| 821 | 821 | } |
| 822 | 822 | } |
@@ -829,10 +829,10 @@ discard block |
||
| 829 | 829 | */ |
| 830 | 830 | private static function _register_modules($addon_name) |
| 831 | 831 | { |
| 832 | - if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 832 | + if ( ! empty(self::$_settings[$addon_name]['module_paths'])) { |
|
| 833 | 833 | EE_Register_Module::register( |
| 834 | 834 | $addon_name, |
| 835 | - array('module_paths' => self::$_settings[ $addon_name ]['module_paths']) |
|
| 835 | + array('module_paths' => self::$_settings[$addon_name]['module_paths']) |
|
| 836 | 836 | ); |
| 837 | 837 | } |
| 838 | 838 | } |
@@ -845,17 +845,17 @@ discard block |
||
| 845 | 845 | */ |
| 846 | 846 | private static function _register_shortcodes($addon_name) |
| 847 | 847 | { |
| 848 | - if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 849 | - || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 848 | + if ( ! empty(self::$_settings[$addon_name]['shortcode_paths']) |
|
| 849 | + || ! empty(self::$_settings[$addon_name]['shortcode_fqcns']) |
|
| 850 | 850 | ) { |
| 851 | 851 | EE_Register_Shortcode::register( |
| 852 | 852 | $addon_name, |
| 853 | 853 | array( |
| 854 | - 'shortcode_paths' => isset(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 855 | - ? self::$_settings[ $addon_name ]['shortcode_paths'] |
|
| 854 | + 'shortcode_paths' => isset(self::$_settings[$addon_name]['shortcode_paths']) |
|
| 855 | + ? self::$_settings[$addon_name]['shortcode_paths'] |
|
| 856 | 856 | : array(), |
| 857 | - 'shortcode_fqcns' => isset(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 858 | - ? self::$_settings[ $addon_name ]['shortcode_fqcns'] |
|
| 857 | + 'shortcode_fqcns' => isset(self::$_settings[$addon_name]['shortcode_fqcns']) |
|
| 858 | + ? self::$_settings[$addon_name]['shortcode_fqcns'] |
|
| 859 | 859 | : array(), |
| 860 | 860 | ) |
| 861 | 861 | ); |
@@ -870,10 +870,10 @@ discard block |
||
| 870 | 870 | */ |
| 871 | 871 | private static function _register_widgets($addon_name) |
| 872 | 872 | { |
| 873 | - if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 873 | + if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) { |
|
| 874 | 874 | EE_Register_Widget::register( |
| 875 | 875 | $addon_name, |
| 876 | - array('widget_paths' => self::$_settings[ $addon_name ]['widget_paths']) |
|
| 876 | + array('widget_paths' => self::$_settings[$addon_name]['widget_paths']) |
|
| 877 | 877 | ); |
| 878 | 878 | } |
| 879 | 879 | } |
@@ -886,12 +886,12 @@ discard block |
||
| 886 | 886 | */ |
| 887 | 887 | private static function _register_capabilities($addon_name) |
| 888 | 888 | { |
| 889 | - if (! empty(self::$_settings[ $addon_name ]['capabilities'])) { |
|
| 889 | + if ( ! empty(self::$_settings[$addon_name]['capabilities'])) { |
|
| 890 | 890 | EE_Register_Capabilities::register( |
| 891 | 891 | $addon_name, |
| 892 | 892 | array( |
| 893 | - 'capabilities' => self::$_settings[ $addon_name ]['capabilities'], |
|
| 894 | - 'capability_maps' => self::$_settings[ $addon_name ]['capability_maps'], |
|
| 893 | + 'capabilities' => self::$_settings[$addon_name]['capabilities'], |
|
| 894 | + 'capability_maps' => self::$_settings[$addon_name]['capability_maps'], |
|
| 895 | 895 | ) |
| 896 | 896 | ); |
| 897 | 897 | } |
@@ -905,7 +905,7 @@ discard block |
||
| 905 | 905 | */ |
| 906 | 906 | private static function _register_message_types($addon_name) |
| 907 | 907 | { |
| 908 | - if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 908 | + if ( ! empty(self::$_settings[$addon_name]['message_types'])) { |
|
| 909 | 909 | add_action( |
| 910 | 910 | 'EE_Brewing_Regular___messages_caf', |
| 911 | 911 | array('EE_Register_Addon', 'register_message_types') |
@@ -921,15 +921,15 @@ discard block |
||
| 921 | 921 | */ |
| 922 | 922 | private static function _register_custom_post_types($addon_name) |
| 923 | 923 | { |
| 924 | - if (! empty(self::$_settings[ $addon_name ]['custom_post_types']) |
|
| 925 | - || ! empty(self::$_settings[ $addon_name ]['custom_taxonomies']) |
|
| 924 | + if ( ! empty(self::$_settings[$addon_name]['custom_post_types']) |
|
| 925 | + || ! empty(self::$_settings[$addon_name]['custom_taxonomies']) |
|
| 926 | 926 | ) { |
| 927 | 927 | EE_Register_CPT::register( |
| 928 | 928 | $addon_name, |
| 929 | 929 | array( |
| 930 | - 'cpts' => self::$_settings[ $addon_name ]['custom_post_types'], |
|
| 931 | - 'cts' => self::$_settings[ $addon_name ]['custom_taxonomies'], |
|
| 932 | - 'default_terms' => self::$_settings[ $addon_name ]['default_terms'], |
|
| 930 | + 'cpts' => self::$_settings[$addon_name]['custom_post_types'], |
|
| 931 | + 'cts' => self::$_settings[$addon_name]['custom_taxonomies'], |
|
| 932 | + 'default_terms' => self::$_settings[$addon_name]['default_terms'], |
|
| 933 | 933 | ) |
| 934 | 934 | ); |
| 935 | 935 | } |
@@ -947,10 +947,10 @@ discard block |
||
| 947 | 947 | */ |
| 948 | 948 | private static function _register_payment_methods($addon_name) |
| 949 | 949 | { |
| 950 | - if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 950 | + if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) { |
|
| 951 | 951 | EE_Register_Payment_Method::register( |
| 952 | 952 | $addon_name, |
| 953 | - array('payment_method_paths' => self::$_settings[ $addon_name ]['payment_method_paths']) |
|
| 953 | + array('payment_method_paths' => self::$_settings[$addon_name]['payment_method_paths']) |
|
| 954 | 954 | ); |
| 955 | 955 | } |
| 956 | 956 | } |
@@ -967,10 +967,10 @@ discard block |
||
| 967 | 967 | */ |
| 968 | 968 | private static function registerPrivacyPolicies($addon_name) |
| 969 | 969 | { |
| 970 | - if (! empty(self::$_settings[ $addon_name ]['privacy_policies'])) { |
|
| 970 | + if ( ! empty(self::$_settings[$addon_name]['privacy_policies'])) { |
|
| 971 | 971 | EE_Register_Privacy_Policy::register( |
| 972 | 972 | $addon_name, |
| 973 | - self::$_settings[ $addon_name ]['privacy_policies'] |
|
| 973 | + self::$_settings[$addon_name]['privacy_policies'] |
|
| 974 | 974 | ); |
| 975 | 975 | } |
| 976 | 976 | } |
@@ -982,10 +982,10 @@ discard block |
||
| 982 | 982 | */ |
| 983 | 983 | private static function registerPersonalDataExporters($addon_name) |
| 984 | 984 | { |
| 985 | - if (! empty(self::$_settings[ $addon_name ]['personal_data_exporters'])) { |
|
| 985 | + if ( ! empty(self::$_settings[$addon_name]['personal_data_exporters'])) { |
|
| 986 | 986 | EE_Register_Personal_Data_Eraser::register( |
| 987 | 987 | $addon_name, |
| 988 | - self::$_settings[ $addon_name ]['personal_data_exporters'] |
|
| 988 | + self::$_settings[$addon_name]['personal_data_exporters'] |
|
| 989 | 989 | ); |
| 990 | 990 | } |
| 991 | 991 | } |
@@ -997,10 +997,10 @@ discard block |
||
| 997 | 997 | */ |
| 998 | 998 | private static function registerPersonalDataErasers($addon_name) |
| 999 | 999 | { |
| 1000 | - if (! empty(self::$_settings[ $addon_name ]['personal_data_erasers'])) { |
|
| 1000 | + if ( ! empty(self::$_settings[$addon_name]['personal_data_erasers'])) { |
|
| 1001 | 1001 | EE_Register_Personal_Data_Eraser::register( |
| 1002 | 1002 | $addon_name, |
| 1003 | - self::$_settings[ $addon_name ]['personal_data_erasers'] |
|
| 1003 | + self::$_settings[$addon_name]['personal_data_erasers'] |
|
| 1004 | 1004 | ); |
| 1005 | 1005 | } |
| 1006 | 1006 | } |
@@ -1021,7 +1021,7 @@ discard block |
||
| 1021 | 1021 | { |
| 1022 | 1022 | $loader = EventEspresso\core\services\loaders\LoaderFactory::getLoader(); |
| 1023 | 1023 | $addon = $loader->getShared( |
| 1024 | - self::$_settings[ $addon_name ]['class_name'], |
|
| 1024 | + self::$_settings[$addon_name]['class_name'], |
|
| 1025 | 1025 | array('EE_Registry::create(addon)' => true) |
| 1026 | 1026 | ); |
| 1027 | 1027 | // setter inject dep map if required |
@@ -1033,19 +1033,19 @@ discard block |
||
| 1033 | 1033 | && $addon->domain() === null |
| 1034 | 1034 | ) { |
| 1035 | 1035 | // using supplied Domain object |
| 1036 | - $domain = self::$_settings[ $addon_name ]['domain'] instanceof DomainInterface |
|
| 1037 | - ? self::$_settings[ $addon_name ]['domain'] |
|
| 1036 | + $domain = self::$_settings[$addon_name]['domain'] instanceof DomainInterface |
|
| 1037 | + ? self::$_settings[$addon_name]['domain'] |
|
| 1038 | 1038 | : null; |
| 1039 | 1039 | // or construct one using Domain FQCN |
| 1040 | - if ($domain === null && self::$_settings[ $addon_name ]['domain_fqcn'] !== '') { |
|
| 1040 | + if ($domain === null && self::$_settings[$addon_name]['domain_fqcn'] !== '') { |
|
| 1041 | 1041 | $domain = $loader->getShared( |
| 1042 | - self::$_settings[ $addon_name ]['domain_fqcn'], |
|
| 1042 | + self::$_settings[$addon_name]['domain_fqcn'], |
|
| 1043 | 1043 | array( |
| 1044 | 1044 | new EventEspresso\core\domain\values\FilePath( |
| 1045 | - self::$_settings[ $addon_name ]['main_file_path'] |
|
| 1045 | + self::$_settings[$addon_name]['main_file_path'] |
|
| 1046 | 1046 | ), |
| 1047 | 1047 | EventEspresso\core\domain\values\Version::fromString( |
| 1048 | - self::$_settings[ $addon_name ]['version'] |
|
| 1048 | + self::$_settings[$addon_name]['version'] |
|
| 1049 | 1049 | ), |
| 1050 | 1050 | ) |
| 1051 | 1051 | ); |
@@ -1055,24 +1055,24 @@ discard block |
||
| 1055 | 1055 | } |
| 1056 | 1056 | } |
| 1057 | 1057 | $addon->set_name($addon_name); |
| 1058 | - $addon->set_plugin_slug(self::$_settings[ $addon_name ]['plugin_slug']); |
|
| 1059 | - $addon->set_plugin_basename(self::$_settings[ $addon_name ]['plugin_basename']); |
|
| 1060 | - $addon->set_main_plugin_file(self::$_settings[ $addon_name ]['main_file_path']); |
|
| 1061 | - $addon->set_plugin_action_slug(self::$_settings[ $addon_name ]['plugin_action_slug']); |
|
| 1062 | - $addon->set_plugins_page_row(self::$_settings[ $addon_name ]['plugins_page_row']); |
|
| 1063 | - $addon->set_version(self::$_settings[ $addon_name ]['version']); |
|
| 1064 | - $addon->set_min_core_version(self::_effective_version(self::$_settings[ $addon_name ]['min_core_version'])); |
|
| 1065 | - $addon->set_config_section(self::$_settings[ $addon_name ]['config_section']); |
|
| 1066 | - $addon->set_config_class(self::$_settings[ $addon_name ]['config_class']); |
|
| 1067 | - $addon->set_config_name(self::$_settings[ $addon_name ]['config_name']); |
|
| 1058 | + $addon->set_plugin_slug(self::$_settings[$addon_name]['plugin_slug']); |
|
| 1059 | + $addon->set_plugin_basename(self::$_settings[$addon_name]['plugin_basename']); |
|
| 1060 | + $addon->set_main_plugin_file(self::$_settings[$addon_name]['main_file_path']); |
|
| 1061 | + $addon->set_plugin_action_slug(self::$_settings[$addon_name]['plugin_action_slug']); |
|
| 1062 | + $addon->set_plugins_page_row(self::$_settings[$addon_name]['plugins_page_row']); |
|
| 1063 | + $addon->set_version(self::$_settings[$addon_name]['version']); |
|
| 1064 | + $addon->set_min_core_version(self::_effective_version(self::$_settings[$addon_name]['min_core_version'])); |
|
| 1065 | + $addon->set_config_section(self::$_settings[$addon_name]['config_section']); |
|
| 1066 | + $addon->set_config_class(self::$_settings[$addon_name]['config_class']); |
|
| 1067 | + $addon->set_config_name(self::$_settings[$addon_name]['config_name']); |
|
| 1068 | 1068 | // unfortunately this can't be hooked in upon construction, because we don't have |
| 1069 | 1069 | // the plugin mainfile's path upon construction. |
| 1070 | 1070 | register_deactivation_hook($addon->get_main_plugin_file(), array($addon, 'deactivation')); |
| 1071 | 1071 | // call any additional admin_callback functions during load_admin_controller hook |
| 1072 | - if (! empty(self::$_settings[ $addon_name ]['admin_callback'])) { |
|
| 1072 | + if ( ! empty(self::$_settings[$addon_name]['admin_callback'])) { |
|
| 1073 | 1073 | add_action( |
| 1074 | 1074 | 'AHEE__EE_System__load_controllers__load_admin_controllers', |
| 1075 | - array($addon, self::$_settings[ $addon_name ]['admin_callback']) |
|
| 1075 | + array($addon, self::$_settings[$addon_name]['admin_callback']) |
|
| 1076 | 1076 | ); |
| 1077 | 1077 | } |
| 1078 | 1078 | return $addon; |
@@ -1090,11 +1090,11 @@ discard block |
||
| 1090 | 1090 | public static function load_pue_update() |
| 1091 | 1091 | { |
| 1092 | 1092 | // load PUE client |
| 1093 | - require_once EE_THIRD_PARTY . 'pue/pue-client.php'; |
|
| 1093 | + require_once EE_THIRD_PARTY.'pue/pue-client.php'; |
|
| 1094 | 1094 | $license_server = defined('PUE_UPDATES_ENDPOINT') ? PUE_UPDATES_ENDPOINT : 'https://eventespresso.com'; |
| 1095 | 1095 | // cycle thru settings |
| 1096 | 1096 | foreach (self::$_settings as $settings) { |
| 1097 | - if (! empty($settings['pue_options'])) { |
|
| 1097 | + if ( ! empty($settings['pue_options'])) { |
|
| 1098 | 1098 | // initiate the class and start the plugin update engine! |
| 1099 | 1099 | new PluginUpdateEngineChecker( |
| 1100 | 1100 | // host file URL |
@@ -1102,7 +1102,7 @@ discard block |
||
| 1102 | 1102 | // plugin slug(s) |
| 1103 | 1103 | array( |
| 1104 | 1104 | 'premium' => array('p' => $settings['pue_options']['pue_plugin_slug']), |
| 1105 | - 'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'] . '-pr'), |
|
| 1105 | + 'prerelease' => array('beta' => $settings['pue_options']['pue_plugin_slug'].'-pr'), |
|
| 1106 | 1106 | ), |
| 1107 | 1107 | // options |
| 1108 | 1108 | array( |
@@ -1131,7 +1131,7 @@ discard block |
||
| 1131 | 1131 | public static function register_message_types() |
| 1132 | 1132 | { |
| 1133 | 1133 | foreach (self::$_settings as $addon_name => $settings) { |
| 1134 | - if (! empty($settings['message_types'])) { |
|
| 1134 | + if ( ! empty($settings['message_types'])) { |
|
| 1135 | 1135 | foreach ((array) $settings['message_types'] as $message_type => $message_type_settings) { |
| 1136 | 1136 | EE_Register_Message_Type::register($message_type, $message_type_settings); |
| 1137 | 1137 | } |
@@ -1153,70 +1153,70 @@ discard block |
||
| 1153 | 1153 | */ |
| 1154 | 1154 | public static function deregister($addon_name = null) |
| 1155 | 1155 | { |
| 1156 | - if (isset(self::$_settings[ $addon_name ]['class_name'])) { |
|
| 1156 | + if (isset(self::$_settings[$addon_name]['class_name'])) { |
|
| 1157 | 1157 | try { |
| 1158 | 1158 | do_action('AHEE__EE_Register_Addon__deregister__before', $addon_name); |
| 1159 | - $class_name = self::$_settings[ $addon_name ]['class_name']; |
|
| 1160 | - if (! empty(self::$_settings[ $addon_name ]['dms_paths'])) { |
|
| 1159 | + $class_name = self::$_settings[$addon_name]['class_name']; |
|
| 1160 | + if ( ! empty(self::$_settings[$addon_name]['dms_paths'])) { |
|
| 1161 | 1161 | // setup DMS |
| 1162 | 1162 | EE_Register_Data_Migration_Scripts::deregister($addon_name); |
| 1163 | 1163 | } |
| 1164 | - if (! empty(self::$_settings[ $addon_name ]['admin_path'])) { |
|
| 1164 | + if ( ! empty(self::$_settings[$addon_name]['admin_path'])) { |
|
| 1165 | 1165 | // register admin page |
| 1166 | 1166 | EE_Register_Admin_Page::deregister($addon_name); |
| 1167 | 1167 | } |
| 1168 | - if (! empty(self::$_settings[ $addon_name ]['module_paths'])) { |
|
| 1168 | + if ( ! empty(self::$_settings[$addon_name]['module_paths'])) { |
|
| 1169 | 1169 | // add to list of modules to be registered |
| 1170 | 1170 | EE_Register_Module::deregister($addon_name); |
| 1171 | 1171 | } |
| 1172 | - if (! empty(self::$_settings[ $addon_name ]['shortcode_paths']) |
|
| 1173 | - || ! empty(self::$_settings[ $addon_name ]['shortcode_fqcns']) |
|
| 1172 | + if ( ! empty(self::$_settings[$addon_name]['shortcode_paths']) |
|
| 1173 | + || ! empty(self::$_settings[$addon_name]['shortcode_fqcns']) |
|
| 1174 | 1174 | ) { |
| 1175 | 1175 | // add to list of shortcodes to be registered |
| 1176 | 1176 | EE_Register_Shortcode::deregister($addon_name); |
| 1177 | 1177 | } |
| 1178 | - if (! empty(self::$_settings[ $addon_name ]['config_class'])) { |
|
| 1178 | + if ( ! empty(self::$_settings[$addon_name]['config_class'])) { |
|
| 1179 | 1179 | // if config_class present let's register config. |
| 1180 | - EE_Register_Config::deregister(self::$_settings[ $addon_name ]['config_class']); |
|
| 1180 | + EE_Register_Config::deregister(self::$_settings[$addon_name]['config_class']); |
|
| 1181 | 1181 | } |
| 1182 | - if (! empty(self::$_settings[ $addon_name ]['widget_paths'])) { |
|
| 1182 | + if ( ! empty(self::$_settings[$addon_name]['widget_paths'])) { |
|
| 1183 | 1183 | // add to list of widgets to be registered |
| 1184 | 1184 | EE_Register_Widget::deregister($addon_name); |
| 1185 | 1185 | } |
| 1186 | - if (! empty(self::$_settings[ $addon_name ]['model_paths']) |
|
| 1187 | - || ! empty(self::$_settings[ $addon_name ]['class_paths']) |
|
| 1186 | + if ( ! empty(self::$_settings[$addon_name]['model_paths']) |
|
| 1187 | + || ! empty(self::$_settings[$addon_name]['class_paths']) |
|
| 1188 | 1188 | ) { |
| 1189 | 1189 | // add to list of shortcodes to be registered |
| 1190 | 1190 | EE_Register_Model::deregister($addon_name); |
| 1191 | 1191 | } |
| 1192 | - if (! empty(self::$_settings[ $addon_name ]['model_extension_paths']) |
|
| 1193 | - || ! empty(self::$_settings[ $addon_name ]['class_extension_paths']) |
|
| 1192 | + if ( ! empty(self::$_settings[$addon_name]['model_extension_paths']) |
|
| 1193 | + || ! empty(self::$_settings[$addon_name]['class_extension_paths']) |
|
| 1194 | 1194 | ) { |
| 1195 | 1195 | // add to list of shortcodes to be registered |
| 1196 | 1196 | EE_Register_Model_Extensions::deregister($addon_name); |
| 1197 | 1197 | } |
| 1198 | - if (! empty(self::$_settings[ $addon_name ]['message_types'])) { |
|
| 1199 | - foreach ((array) self::$_settings[ $addon_name ]['message_types'] as $message_type => $message_type_settings) { |
|
| 1198 | + if ( ! empty(self::$_settings[$addon_name]['message_types'])) { |
|
| 1199 | + foreach ((array) self::$_settings[$addon_name]['message_types'] as $message_type => $message_type_settings) { |
|
| 1200 | 1200 | EE_Register_Message_Type::deregister($message_type); |
| 1201 | 1201 | } |
| 1202 | 1202 | } |
| 1203 | 1203 | // deregister capabilities for addon |
| 1204 | - if (! empty(self::$_settings[ $addon_name ]['capabilities']) |
|
| 1205 | - || ! empty(self::$_settings[ $addon_name ]['capability_maps']) |
|
| 1204 | + if ( ! empty(self::$_settings[$addon_name]['capabilities']) |
|
| 1205 | + || ! empty(self::$_settings[$addon_name]['capability_maps']) |
|
| 1206 | 1206 | ) { |
| 1207 | 1207 | EE_Register_Capabilities::deregister($addon_name); |
| 1208 | 1208 | } |
| 1209 | 1209 | // deregister custom_post_types for addon |
| 1210 | - if (! empty(self::$_settings[ $addon_name ]['custom_post_types'])) { |
|
| 1210 | + if ( ! empty(self::$_settings[$addon_name]['custom_post_types'])) { |
|
| 1211 | 1211 | EE_Register_CPT::deregister($addon_name); |
| 1212 | 1212 | } |
| 1213 | - if (! empty(self::$_settings[ $addon_name ]['payment_method_paths'])) { |
|
| 1213 | + if ( ! empty(self::$_settings[$addon_name]['payment_method_paths'])) { |
|
| 1214 | 1214 | EE_Register_Payment_Method::deregister($addon_name); |
| 1215 | 1215 | } |
| 1216 | 1216 | $addon = EE_Registry::instance()->getAddon($class_name); |
| 1217 | 1217 | if ($addon instanceof EE_Addon) { |
| 1218 | 1218 | remove_action( |
| 1219 | - 'deactivate_' . $addon->get_main_plugin_file_basename(), |
|
| 1219 | + 'deactivate_'.$addon->get_main_plugin_file_basename(), |
|
| 1220 | 1220 | array($addon, 'deactivation') |
| 1221 | 1221 | ); |
| 1222 | 1222 | remove_action( |
@@ -1239,7 +1239,7 @@ discard block |
||
| 1239 | 1239 | } catch (Exception $e) { |
| 1240 | 1240 | new ExceptionLogger($e); |
| 1241 | 1241 | } |
| 1242 | - unset(self::$_settings[ $addon_name ]); |
|
| 1242 | + unset(self::$_settings[$addon_name]); |
|
| 1243 | 1243 | do_action('AHEE__EE_Register_Addon__deregister__after', $addon_name); |
| 1244 | 1244 | } |
| 1245 | 1245 | } |
@@ -14,1528 +14,1528 @@ |
||
| 14 | 14 | class EE_Form_Section_Proper extends EE_Form_Section_Validatable |
| 15 | 15 | { |
| 16 | 16 | |
| 17 | - const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data'; |
|
| 18 | - |
|
| 19 | - /** |
|
| 20 | - * Subsections |
|
| 21 | - * |
|
| 22 | - * @var EE_Form_Section_Validatable[] |
|
| 23 | - */ |
|
| 24 | - protected $_subsections = array(); |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * Strategy for laying out the form |
|
| 28 | - * |
|
| 29 | - * @var EE_Form_Section_Layout_Base |
|
| 30 | - */ |
|
| 31 | - protected $_layout_strategy; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * Whether or not this form has received and validated a form submission yet |
|
| 35 | - * |
|
| 36 | - * @var boolean |
|
| 37 | - */ |
|
| 38 | - protected $_received_submission = false; |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * message displayed to users upon successful form submission |
|
| 42 | - * |
|
| 43 | - * @var string |
|
| 44 | - */ |
|
| 45 | - protected $_form_submission_success_message = ''; |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * message displayed to users upon unsuccessful form submission |
|
| 49 | - * |
|
| 50 | - * @var string |
|
| 51 | - */ |
|
| 52 | - protected $_form_submission_error_message = ''; |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * @var array like $_REQUEST |
|
| 56 | - */ |
|
| 57 | - protected $cached_request_data; |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - * Stores whether this form (and its sub-sections) were found to be valid or not. |
|
| 61 | - * Starts off as null, but once the form is validated, it set to either true or false |
|
| 62 | - * @var boolean|null |
|
| 63 | - */ |
|
| 64 | - protected $is_valid; |
|
| 65 | - |
|
| 66 | - /** |
|
| 67 | - * Stores all the data that will localized for form validation |
|
| 68 | - * |
|
| 69 | - * @var array |
|
| 70 | - */ |
|
| 71 | - static protected $_js_localization = array(); |
|
| 72 | - |
|
| 73 | - /** |
|
| 74 | - * whether or not the form's localized validation JS vars have been set |
|
| 75 | - * |
|
| 76 | - * @type boolean |
|
| 77 | - */ |
|
| 78 | - static protected $_scripts_localized = false; |
|
| 79 | - |
|
| 80 | - |
|
| 81 | - /** |
|
| 82 | - * when constructing a proper form section, calls _construct_finalize on children |
|
| 83 | - * so that they know who their parent is, and what name they've been given. |
|
| 84 | - * |
|
| 85 | - * @param array[] $options_array { |
|
| 86 | - * @type $subsections EE_Form_Section_Validatable[] where keys are the section's name |
|
| 87 | - * @type $include string[] numerically-indexed where values are section names to be included, |
|
| 88 | - * and in that order. This is handy if you want |
|
| 89 | - * the subsections to be ordered differently than the default, and if you override |
|
| 90 | - * which fields are shown |
|
| 91 | - * @type $exclude string[] values are subsections to be excluded. This is handy if you want |
|
| 92 | - * to remove certain default subsections (note: if you specify BOTH 'include' AND |
|
| 93 | - * 'exclude', the inclusions will be applied first, and the exclusions will exclude |
|
| 94 | - * items from that list of inclusions) |
|
| 95 | - * @type $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form |
|
| 96 | - * } @see EE_Form_Section_Validatable::__construct() |
|
| 97 | - * @throws EE_Error |
|
| 98 | - */ |
|
| 99 | - public function __construct($options_array = array()) |
|
| 100 | - { |
|
| 101 | - $options_array = (array) apply_filters( |
|
| 102 | - 'FHEE__EE_Form_Section_Proper___construct__options_array', |
|
| 103 | - $options_array, |
|
| 104 | - $this |
|
| 105 | - ); |
|
| 106 | - // call parent first, as it may be setting the name |
|
| 107 | - parent::__construct($options_array); |
|
| 108 | - // if they've included subsections in the constructor, add them now |
|
| 109 | - if (isset($options_array['include'])) { |
|
| 110 | - // we are going to make sure we ONLY have those subsections to include |
|
| 111 | - // AND we are going to make sure they're in that specified order |
|
| 112 | - $reordered_subsections = array(); |
|
| 113 | - foreach ($options_array['include'] as $input_name) { |
|
| 114 | - if (isset($this->_subsections[ $input_name ])) { |
|
| 115 | - $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ]; |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - $this->_subsections = $reordered_subsections; |
|
| 119 | - } |
|
| 120 | - if (isset($options_array['exclude'])) { |
|
| 121 | - $exclude = $options_array['exclude']; |
|
| 122 | - $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude)); |
|
| 123 | - } |
|
| 124 | - if (isset($options_array['layout_strategy'])) { |
|
| 125 | - $this->_layout_strategy = $options_array['layout_strategy']; |
|
| 126 | - } |
|
| 127 | - if (! $this->_layout_strategy) { |
|
| 128 | - $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout(); |
|
| 129 | - } |
|
| 130 | - $this->_layout_strategy->_construct_finalize($this); |
|
| 131 | - // ok so we are definitely going to want the forms JS, |
|
| 132 | - // so enqueue it or remember to enqueue it during wp_enqueue_scripts |
|
| 133 | - if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) { |
|
| 134 | - // ok so they've constructed this object after when they should have. |
|
| 135 | - // just enqueue the generic form scripts and initialize the form immediately in the JS |
|
| 136 | - EE_Form_Section_Proper::wp_enqueue_scripts(true); |
|
| 137 | - } else { |
|
| 138 | - add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 139 | - add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 140 | - } |
|
| 141 | - add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1); |
|
| 142 | - /** |
|
| 143 | - * Gives other plugins a chance to hook in before construct finalize is called. |
|
| 144 | - * The form probably doesn't yet have a parent form section. |
|
| 145 | - * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form, |
|
| 146 | - * assuming you don't care what the form section's name, HTML ID, or HTML name etc are. |
|
| 147 | - * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end |
|
| 148 | - * |
|
| 149 | - * @since 4.9.32 |
|
| 150 | - * @param EE_Form_Section_Proper $this before __construct is done, but all of its logic, |
|
| 151 | - * except maybe calling _construct_finalize has been done |
|
| 152 | - * @param array $options_array options passed into the constructor |
|
| 153 | - */ |
|
| 154 | - do_action( |
|
| 155 | - 'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called', |
|
| 156 | - $this, |
|
| 157 | - $options_array |
|
| 158 | - ); |
|
| 159 | - if (isset($options_array['name'])) { |
|
| 160 | - $this->_construct_finalize(null, $options_array['name']); |
|
| 161 | - } |
|
| 162 | - } |
|
| 163 | - |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Finishes construction given the parent form section and this form section's name |
|
| 167 | - * |
|
| 168 | - * @param EE_Form_Section_Proper $parent_form_section |
|
| 169 | - * @param string $name |
|
| 170 | - * @throws EE_Error |
|
| 171 | - */ |
|
| 172 | - public function _construct_finalize($parent_form_section, $name) |
|
| 173 | - { |
|
| 174 | - parent::_construct_finalize($parent_form_section, $name); |
|
| 175 | - $this->_set_default_name_if_empty(); |
|
| 176 | - $this->_set_default_html_id_if_empty(); |
|
| 177 | - foreach ($this->_subsections as $subsection_name => $subsection) { |
|
| 178 | - if ($subsection instanceof EE_Form_Section_Base) { |
|
| 179 | - $subsection->_construct_finalize($this, $subsection_name); |
|
| 180 | - } else { |
|
| 181 | - throw new EE_Error( |
|
| 182 | - sprintf( |
|
| 183 | - esc_html__( |
|
| 184 | - 'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"', |
|
| 185 | - 'event_espresso' |
|
| 186 | - ), |
|
| 187 | - $subsection_name, |
|
| 188 | - get_class($this), |
|
| 189 | - $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 190 | - ) |
|
| 191 | - ); |
|
| 192 | - } |
|
| 193 | - } |
|
| 194 | - /** |
|
| 195 | - * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed. |
|
| 196 | - * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID |
|
| 197 | - * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done. |
|
| 198 | - * This might only happen just before displaying the form, or just before it receives form submission data. |
|
| 199 | - * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've |
|
| 200 | - * ensured it has a name, HTML IDs, etc |
|
| 201 | - * |
|
| 202 | - * @param EE_Form_Section_Proper $this |
|
| 203 | - * @param EE_Form_Section_Proper|null $parent_form_section |
|
| 204 | - * @param string $name |
|
| 205 | - */ |
|
| 206 | - do_action( |
|
| 207 | - 'AHEE__EE_Form_Section_Proper___construct_finalize__end', |
|
| 208 | - $this, |
|
| 209 | - $parent_form_section, |
|
| 210 | - $name |
|
| 211 | - ); |
|
| 212 | - } |
|
| 213 | - |
|
| 214 | - |
|
| 215 | - /** |
|
| 216 | - * Gets the layout strategy for this form section |
|
| 217 | - * |
|
| 218 | - * @return EE_Form_Section_Layout_Base |
|
| 219 | - */ |
|
| 220 | - public function get_layout_strategy() |
|
| 221 | - { |
|
| 222 | - return $this->_layout_strategy; |
|
| 223 | - } |
|
| 224 | - |
|
| 225 | - |
|
| 226 | - /** |
|
| 227 | - * Gets the HTML for a single input for this form section according |
|
| 228 | - * to the layout strategy |
|
| 229 | - * |
|
| 230 | - * @param EE_Form_Input_Base $input |
|
| 231 | - * @return string |
|
| 232 | - */ |
|
| 233 | - public function get_html_for_input($input) |
|
| 234 | - { |
|
| 235 | - return $this->_layout_strategy->layout_input($input); |
|
| 236 | - } |
|
| 237 | - |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * was_submitted - checks if form inputs are present in request data |
|
| 241 | - * Basically an alias for form_data_present_in() (which is used by both |
|
| 242 | - * proper form sections and form inputs) |
|
| 243 | - * |
|
| 244 | - * @param null $form_data |
|
| 245 | - * @return boolean |
|
| 246 | - * @throws EE_Error |
|
| 247 | - */ |
|
| 248 | - public function was_submitted($form_data = null) |
|
| 249 | - { |
|
| 250 | - return $this->form_data_present_in($form_data); |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - /** |
|
| 254 | - * Gets the cached request data; but if there is none, or $req_data was set with |
|
| 255 | - * something different, refresh the cache, and then return it |
|
| 256 | - * @param null $req_data |
|
| 257 | - * @return array |
|
| 258 | - */ |
|
| 259 | - protected function getCachedRequest($req_data = null) |
|
| 260 | - { |
|
| 261 | - if ($this->cached_request_data === null |
|
| 262 | - || ( |
|
| 263 | - $req_data !== null && |
|
| 264 | - $req_data !== $this->cached_request_data |
|
| 265 | - ) |
|
| 266 | - ) { |
|
| 267 | - $req_data = apply_filters( |
|
| 268 | - 'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', |
|
| 269 | - $req_data, |
|
| 270 | - $this |
|
| 271 | - ); |
|
| 272 | - if ($req_data === null) { |
|
| 273 | - $req_data = array_merge($_GET, $_POST); |
|
| 274 | - } |
|
| 275 | - $req_data = apply_filters( |
|
| 276 | - 'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', |
|
| 277 | - $req_data, |
|
| 278 | - $this |
|
| 279 | - ); |
|
| 280 | - $this->cached_request_data = (array) $req_data; |
|
| 281 | - } |
|
| 282 | - return $this->cached_request_data; |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - |
|
| 286 | - /** |
|
| 287 | - * After the form section is initially created, call this to sanitize the data in the submission |
|
| 288 | - * which relates to this form section, validate it, and set it as properties on the form. |
|
| 289 | - * |
|
| 290 | - * @param array|null $req_data should usually be $_POST (the default). |
|
| 291 | - * However, you CAN supply a different array. |
|
| 292 | - * Consider using set_defaults() instead however. |
|
| 293 | - * (If you rendered the form in the page using echo $form_x->get_html() |
|
| 294 | - * the inputs will have the correct name in the request data for this function |
|
| 295 | - * to find them and populate the form with them. |
|
| 296 | - * If you have a flat form (with only input subsections), |
|
| 297 | - * you can supply a flat array where keys |
|
| 298 | - * are the form input names and values are their values) |
|
| 299 | - * @param boolean $validate whether or not to perform validation on this data. Default is, |
|
| 300 | - * of course, to validate that data, and set errors on the invalid values. |
|
| 301 | - * But if the data has already been validated |
|
| 302 | - * (eg you validated the data then stored it in the DB) |
|
| 303 | - * you may want to skip this step. |
|
| 304 | - * @throws InvalidArgumentException |
|
| 305 | - * @throws InvalidInterfaceException |
|
| 306 | - * @throws InvalidDataTypeException |
|
| 307 | - * @throws EE_Error |
|
| 308 | - */ |
|
| 309 | - public function receive_form_submission($req_data = null, $validate = true) |
|
| 310 | - { |
|
| 311 | - $req_data = $this->getCachedRequest($req_data); |
|
| 312 | - $this->_normalize($req_data); |
|
| 313 | - if ($validate) { |
|
| 314 | - $this->_validate(); |
|
| 315 | - // if it's invalid, we're going to want to re-display so remember what they submitted |
|
| 316 | - if (! $this->is_valid()) { |
|
| 317 | - $this->store_submitted_form_data_in_session(); |
|
| 318 | - } |
|
| 319 | - } |
|
| 320 | - if ($this->submission_error_message() === '' && ! $this->is_valid()) { |
|
| 321 | - $this->set_submission_error_message(); |
|
| 322 | - } |
|
| 323 | - do_action( |
|
| 324 | - 'AHEE__EE_Form_Section_Proper__receive_form_submission__end', |
|
| 325 | - $req_data, |
|
| 326 | - $this, |
|
| 327 | - $validate |
|
| 328 | - ); |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - |
|
| 332 | - /** |
|
| 333 | - * caches the originally submitted input values in the session |
|
| 334 | - * so that they can be used to repopulate the form if it failed validation |
|
| 335 | - * |
|
| 336 | - * @return boolean whether or not the data was successfully stored in the session |
|
| 337 | - * @throws InvalidArgumentException |
|
| 338 | - * @throws InvalidInterfaceException |
|
| 339 | - * @throws InvalidDataTypeException |
|
| 340 | - * @throws EE_Error |
|
| 341 | - */ |
|
| 342 | - protected function store_submitted_form_data_in_session() |
|
| 343 | - { |
|
| 344 | - return EE_Registry::instance()->SSN->set_session_data( |
|
| 345 | - array( |
|
| 346 | - EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true), |
|
| 347 | - ) |
|
| 348 | - ); |
|
| 349 | - } |
|
| 350 | - |
|
| 351 | - |
|
| 352 | - /** |
|
| 353 | - * retrieves the originally submitted input values in the session |
|
| 354 | - * so that they can be used to repopulate the form if it failed validation |
|
| 355 | - * |
|
| 356 | - * @return array |
|
| 357 | - * @throws InvalidArgumentException |
|
| 358 | - * @throws InvalidInterfaceException |
|
| 359 | - * @throws InvalidDataTypeException |
|
| 360 | - */ |
|
| 361 | - protected function get_submitted_form_data_from_session() |
|
| 362 | - { |
|
| 363 | - $session = EE_Registry::instance()->SSN; |
|
| 364 | - if ($session instanceof EE_Session) { |
|
| 365 | - return $session->get_session_data( |
|
| 366 | - EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY |
|
| 367 | - ); |
|
| 368 | - } |
|
| 369 | - return array(); |
|
| 370 | - } |
|
| 371 | - |
|
| 372 | - |
|
| 373 | - /** |
|
| 374 | - * flushed the originally submitted input values from the session |
|
| 375 | - * |
|
| 376 | - * @return boolean whether or not the data was successfully removed from the session |
|
| 377 | - * @throws InvalidArgumentException |
|
| 378 | - * @throws InvalidInterfaceException |
|
| 379 | - * @throws InvalidDataTypeException |
|
| 380 | - */ |
|
| 381 | - public static function flush_submitted_form_data_from_session() |
|
| 382 | - { |
|
| 383 | - return EE_Registry::instance()->SSN->reset_data( |
|
| 384 | - array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY) |
|
| 385 | - ); |
|
| 386 | - } |
|
| 387 | - |
|
| 388 | - |
|
| 389 | - /** |
|
| 390 | - * Populates this form and its subsections with data from the session. |
|
| 391 | - * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows |
|
| 392 | - * validation errors when displaying too) |
|
| 393 | - * Returns true if the form was populated from the session, false otherwise |
|
| 394 | - * |
|
| 395 | - * @return boolean |
|
| 396 | - * @throws InvalidArgumentException |
|
| 397 | - * @throws InvalidInterfaceException |
|
| 398 | - * @throws InvalidDataTypeException |
|
| 399 | - * @throws EE_Error |
|
| 400 | - */ |
|
| 401 | - public function populate_from_session() |
|
| 402 | - { |
|
| 403 | - $form_data_in_session = $this->get_submitted_form_data_from_session(); |
|
| 404 | - if (empty($form_data_in_session)) { |
|
| 405 | - return false; |
|
| 406 | - } |
|
| 407 | - $this->receive_form_submission($form_data_in_session); |
|
| 408 | - add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session')); |
|
| 409 | - if ($this->form_data_present_in($form_data_in_session)) { |
|
| 410 | - return true; |
|
| 411 | - } |
|
| 412 | - return false; |
|
| 413 | - } |
|
| 414 | - |
|
| 415 | - |
|
| 416 | - /** |
|
| 417 | - * Populates the default data for the form, given an array where keys are |
|
| 418 | - * the input names, and values are their values (preferably normalized to be their |
|
| 419 | - * proper PHP types, not all strings... although that should be ok too). |
|
| 420 | - * Proper subsections are sub-arrays, the key being the subsection's name, and |
|
| 421 | - * the value being an array formatted in teh same way |
|
| 422 | - * |
|
| 423 | - * @param array $default_data |
|
| 424 | - * @throws EE_Error |
|
| 425 | - */ |
|
| 426 | - public function populate_defaults($default_data) |
|
| 427 | - { |
|
| 428 | - foreach ($this->subsections(false) as $subsection_name => $subsection) { |
|
| 429 | - if (isset($default_data[ $subsection_name ])) { |
|
| 430 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 431 | - $subsection->set_default($default_data[ $subsection_name ]); |
|
| 432 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 433 | - $subsection->populate_defaults($default_data[ $subsection_name ]); |
|
| 434 | - } |
|
| 435 | - } |
|
| 436 | - } |
|
| 437 | - } |
|
| 438 | - |
|
| 439 | - |
|
| 440 | - /** |
|
| 441 | - * returns true if subsection exists |
|
| 442 | - * |
|
| 443 | - * @param string $name |
|
| 444 | - * @return boolean |
|
| 445 | - */ |
|
| 446 | - public function subsection_exists($name) |
|
| 447 | - { |
|
| 448 | - return isset($this->_subsections[ $name ]) ? true : false; |
|
| 449 | - } |
|
| 450 | - |
|
| 451 | - |
|
| 452 | - /** |
|
| 453 | - * Gets the subsection specified by its name |
|
| 454 | - * |
|
| 455 | - * @param string $name |
|
| 456 | - * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE |
|
| 457 | - * so that the inputs will be properly configured. |
|
| 458 | - * However, some client code may be ok |
|
| 459 | - * with construction finalize being called later |
|
| 460 | - * (realizing that the subsections' html names |
|
| 461 | - * might not be set yet, etc.) |
|
| 462 | - * @return EE_Form_Section_Base |
|
| 463 | - * @throws EE_Error |
|
| 464 | - */ |
|
| 465 | - public function get_subsection($name, $require_construction_to_be_finalized = true) |
|
| 466 | - { |
|
| 467 | - if ($require_construction_to_be_finalized) { |
|
| 468 | - $this->ensure_construct_finalized_called(); |
|
| 469 | - } |
|
| 470 | - return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null; |
|
| 471 | - } |
|
| 472 | - |
|
| 473 | - |
|
| 474 | - /** |
|
| 475 | - * Gets all the validatable subsections of this form section |
|
| 476 | - * |
|
| 477 | - * @return EE_Form_Section_Validatable[] |
|
| 478 | - * @throws EE_Error |
|
| 479 | - */ |
|
| 480 | - public function get_validatable_subsections() |
|
| 481 | - { |
|
| 482 | - $validatable_subsections = array(); |
|
| 483 | - foreach ($this->subsections() as $name => $obj) { |
|
| 484 | - if ($obj instanceof EE_Form_Section_Validatable) { |
|
| 485 | - $validatable_subsections[ $name ] = $obj; |
|
| 486 | - } |
|
| 487 | - } |
|
| 488 | - return $validatable_subsections; |
|
| 489 | - } |
|
| 490 | - |
|
| 491 | - |
|
| 492 | - /** |
|
| 493 | - * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child, |
|
| 494 | - * throw an EE_Error. |
|
| 495 | - * |
|
| 496 | - * @param string $name |
|
| 497 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 498 | - * leave this as TRUE so that the inputs will be properly |
|
| 499 | - * configured. However, some client code may be ok with |
|
| 500 | - * construction finalize being called later |
|
| 501 | - * (realizing that the subsections' html names might not be |
|
| 502 | - * set yet, etc.) |
|
| 503 | - * @return EE_Form_Input_Base |
|
| 504 | - * @throws EE_Error |
|
| 505 | - */ |
|
| 506 | - public function get_input($name, $require_construction_to_be_finalized = true) |
|
| 507 | - { |
|
| 508 | - $subsection = $this->get_subsection( |
|
| 509 | - $name, |
|
| 510 | - $require_construction_to_be_finalized |
|
| 511 | - ); |
|
| 512 | - if (! $subsection instanceof EE_Form_Input_Base) { |
|
| 513 | - throw new EE_Error( |
|
| 514 | - sprintf( |
|
| 515 | - esc_html__( |
|
| 516 | - "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'", |
|
| 517 | - 'event_espresso' |
|
| 518 | - ), |
|
| 519 | - $name, |
|
| 520 | - get_class($this), |
|
| 521 | - $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 522 | - ) |
|
| 523 | - ); |
|
| 524 | - } |
|
| 525 | - return $subsection; |
|
| 526 | - } |
|
| 527 | - |
|
| 528 | - |
|
| 529 | - /** |
|
| 530 | - * Like get_input(), gets the proper subsection of the form given the name, |
|
| 531 | - * otherwise throws an EE_Error |
|
| 532 | - * |
|
| 533 | - * @param string $name |
|
| 534 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 535 | - * leave this as TRUE so that the inputs will be properly |
|
| 536 | - * configured. However, some client code may be ok with |
|
| 537 | - * construction finalize being called later |
|
| 538 | - * (realizing that the subsections' html names might not be |
|
| 539 | - * set yet, etc.) |
|
| 540 | - * @return EE_Form_Section_Proper |
|
| 541 | - * @throws EE_Error |
|
| 542 | - */ |
|
| 543 | - public function get_proper_subsection($name, $require_construction_to_be_finalized = true) |
|
| 544 | - { |
|
| 545 | - $subsection = $this->get_subsection( |
|
| 546 | - $name, |
|
| 547 | - $require_construction_to_be_finalized |
|
| 548 | - ); |
|
| 549 | - if (! $subsection instanceof EE_Form_Section_Proper) { |
|
| 550 | - throw new EE_Error( |
|
| 551 | - sprintf( |
|
| 552 | - esc_html__( |
|
| 553 | - "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", |
|
| 554 | - 'event_espresso' |
|
| 555 | - ), |
|
| 556 | - $name, |
|
| 557 | - get_class($this) |
|
| 558 | - ) |
|
| 559 | - ); |
|
| 560 | - } |
|
| 561 | - return $subsection; |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - |
|
| 565 | - /** |
|
| 566 | - * Gets the value of the specified input. Should be called after receive_form_submission() |
|
| 567 | - * or populate_defaults() on the form, where the normalized value on the input is set. |
|
| 568 | - * |
|
| 569 | - * @param string $name |
|
| 570 | - * @return mixed depending on the input's type and its normalization strategy |
|
| 571 | - * @throws EE_Error |
|
| 572 | - */ |
|
| 573 | - public function get_input_value($name) |
|
| 574 | - { |
|
| 575 | - $input = $this->get_input($name); |
|
| 576 | - return $input->normalized_value(); |
|
| 577 | - } |
|
| 578 | - |
|
| 579 | - |
|
| 580 | - /** |
|
| 581 | - * Checks if this form section itself is valid, and then checks its subsections |
|
| 582 | - * |
|
| 583 | - * @throws EE_Error |
|
| 584 | - * @return boolean |
|
| 585 | - */ |
|
| 586 | - public function is_valid() |
|
| 587 | - { |
|
| 588 | - if ($this->is_valid === null) { |
|
| 589 | - if (! $this->has_received_submission()) { |
|
| 590 | - throw new EE_Error( |
|
| 591 | - sprintf( |
|
| 592 | - esc_html__( |
|
| 593 | - 'You cannot check if a form is valid before receiving the form submission using receive_form_submission', |
|
| 594 | - 'event_espresso' |
|
| 595 | - ) |
|
| 596 | - ) |
|
| 597 | - ); |
|
| 598 | - } |
|
| 599 | - if (! parent::is_valid()) { |
|
| 600 | - $this->is_valid = false; |
|
| 601 | - } else { |
|
| 602 | - // ok so no general errors to this entire form section. |
|
| 603 | - // so let's check the subsections, but only set errors if that hasn't been done yet |
|
| 604 | - $this->is_valid = true; |
|
| 605 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 606 | - if (! $subsection->is_valid()) { |
|
| 607 | - $this->is_valid = false; |
|
| 608 | - } |
|
| 609 | - } |
|
| 610 | - } |
|
| 611 | - } |
|
| 612 | - return $this->is_valid; |
|
| 613 | - } |
|
| 614 | - |
|
| 615 | - |
|
| 616 | - /** |
|
| 617 | - * gets the default name of this form section if none is specified |
|
| 618 | - * |
|
| 619 | - * @return void |
|
| 620 | - */ |
|
| 621 | - protected function _set_default_name_if_empty() |
|
| 622 | - { |
|
| 623 | - if (! $this->_name) { |
|
| 624 | - $classname = get_class($this); |
|
| 625 | - $default_name = str_replace('EE_', '', $classname); |
|
| 626 | - $this->_name = $default_name; |
|
| 627 | - } |
|
| 628 | - } |
|
| 629 | - |
|
| 630 | - |
|
| 631 | - /** |
|
| 632 | - * Returns the HTML for the form, except for the form opening and closing tags |
|
| 633 | - * (as the form section doesn't know where you necessarily want to send the information to), |
|
| 634 | - * and except for a submit button. Enqueues JS and CSS; if called early enough we will |
|
| 635 | - * try to enqueue them in the header, otherwise they'll be enqueued in the footer. |
|
| 636 | - * Not doing_it_wrong because theoretically this CAN be used properly, |
|
| 637 | - * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue |
|
| 638 | - * any CSS. |
|
| 639 | - * |
|
| 640 | - * @throws InvalidArgumentException |
|
| 641 | - * @throws InvalidInterfaceException |
|
| 642 | - * @throws InvalidDataTypeException |
|
| 643 | - * @throws EE_Error |
|
| 644 | - */ |
|
| 645 | - public function get_html_and_js() |
|
| 646 | - { |
|
| 647 | - $this->enqueue_js(); |
|
| 648 | - return $this->get_html(); |
|
| 649 | - } |
|
| 650 | - |
|
| 651 | - |
|
| 652 | - /** |
|
| 653 | - * returns HTML for displaying this form section. recursively calls display_section() on all subsections |
|
| 654 | - * |
|
| 655 | - * @param bool $display_previously_submitted_data |
|
| 656 | - * @return string |
|
| 657 | - * @throws InvalidArgumentException |
|
| 658 | - * @throws InvalidInterfaceException |
|
| 659 | - * @throws InvalidDataTypeException |
|
| 660 | - * @throws EE_Error |
|
| 661 | - * @throws EE_Error |
|
| 662 | - * @throws EE_Error |
|
| 663 | - */ |
|
| 664 | - public function get_html($display_previously_submitted_data = true) |
|
| 665 | - { |
|
| 666 | - $this->ensure_construct_finalized_called(); |
|
| 667 | - if ($display_previously_submitted_data) { |
|
| 668 | - $this->populate_from_session(); |
|
| 669 | - } |
|
| 670 | - return $this->_form_html_filter |
|
| 671 | - ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this) |
|
| 672 | - : $this->_layout_strategy->layout_form(); |
|
| 673 | - } |
|
| 674 | - |
|
| 675 | - |
|
| 676 | - /** |
|
| 677 | - * enqueues JS and CSS for the form. |
|
| 678 | - * It is preferred to call this before wp_enqueue_scripts so the |
|
| 679 | - * scripts and styles can be put in the header, but if called later |
|
| 680 | - * they will be put in the footer (which is OK for JS, but in HTML4 CSS should |
|
| 681 | - * only be in the header; but in HTML5 its ok in the body. |
|
| 682 | - * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag. |
|
| 683 | - * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.) |
|
| 684 | - * |
|
| 685 | - * @return void |
|
| 686 | - * @throws EE_Error |
|
| 687 | - */ |
|
| 688 | - public function enqueue_js() |
|
| 689 | - { |
|
| 690 | - $this->_enqueue_and_localize_form_js(); |
|
| 691 | - foreach ($this->subsections() as $subsection) { |
|
| 692 | - $subsection->enqueue_js(); |
|
| 693 | - } |
|
| 694 | - } |
|
| 695 | - |
|
| 696 | - |
|
| 697 | - /** |
|
| 698 | - * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts(). |
|
| 699 | - * This must be done BEFORE wp_enqueue_scripts() gets called, which is on |
|
| 700 | - * the wp_enqueue_scripts hook. |
|
| 701 | - * However, registering the form js and localizing it can happen when we |
|
| 702 | - * actually output the form (which is preferred, seeing how teh form's fields |
|
| 703 | - * could change until it's actually outputted) |
|
| 704 | - * |
|
| 705 | - * @param boolean $init_form_validation_automatically whether or not we want the form validation |
|
| 706 | - * to be triggered automatically or not |
|
| 707 | - * @return void |
|
| 708 | - */ |
|
| 709 | - public static function wp_enqueue_scripts($init_form_validation_automatically = true) |
|
| 710 | - { |
|
| 711 | - wp_register_script( |
|
| 712 | - 'ee_form_section_validation', |
|
| 713 | - EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js', |
|
| 714 | - array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'), |
|
| 715 | - EVENT_ESPRESSO_VERSION, |
|
| 716 | - true |
|
| 717 | - ); |
|
| 718 | - wp_localize_script( |
|
| 719 | - 'ee_form_section_validation', |
|
| 720 | - 'ee_form_section_validation_init', |
|
| 721 | - array('init' => $init_form_validation_automatically ? '1' : '0') |
|
| 722 | - ); |
|
| 723 | - } |
|
| 724 | - |
|
| 725 | - |
|
| 726 | - /** |
|
| 727 | - * gets the variables used by form_section_validation.js. |
|
| 728 | - * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script, |
|
| 729 | - * but before the wordpress hook wp_loaded |
|
| 730 | - * |
|
| 731 | - * @throws EE_Error |
|
| 732 | - */ |
|
| 733 | - public function _enqueue_and_localize_form_js() |
|
| 734 | - { |
|
| 735 | - $this->ensure_construct_finalized_called(); |
|
| 736 | - // actually, we don't want to localize just yet. There may be other forms on the page. |
|
| 737 | - // so we need to add our form section data to a static variable accessible by all form sections |
|
| 738 | - // and localize it just before the footer |
|
| 739 | - $this->localize_validation_rules(); |
|
| 740 | - add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2); |
|
| 741 | - add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms')); |
|
| 742 | - } |
|
| 743 | - |
|
| 744 | - |
|
| 745 | - /** |
|
| 746 | - * add our form section data to a static variable accessible by all form sections |
|
| 747 | - * |
|
| 748 | - * @param bool $return_for_subsection |
|
| 749 | - * @return void |
|
| 750 | - * @throws EE_Error |
|
| 751 | - */ |
|
| 752 | - public function localize_validation_rules($return_for_subsection = false) |
|
| 753 | - { |
|
| 754 | - // we only want to localize vars ONCE for the entire form, |
|
| 755 | - // so if the form section doesn't have a parent, then it must be the top dog |
|
| 756 | - if ($return_for_subsection || ! $this->parent_section()) { |
|
| 757 | - EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array( |
|
| 758 | - 'form_section_id' => $this->html_id(true), |
|
| 759 | - 'validation_rules' => $this->get_jquery_validation_rules(), |
|
| 760 | - 'other_data' => $this->get_other_js_data(), |
|
| 761 | - 'errors' => $this->subsection_validation_errors_by_html_name(), |
|
| 762 | - ); |
|
| 763 | - EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 764 | - } |
|
| 765 | - } |
|
| 766 | - |
|
| 767 | - |
|
| 768 | - /** |
|
| 769 | - * Gets an array of extra data that will be useful for client-side javascript. |
|
| 770 | - * This is primarily data added by inputs and forms in addition to any |
|
| 771 | - * scripts they might enqueue |
|
| 772 | - * |
|
| 773 | - * @param array $form_other_js_data |
|
| 774 | - * @return array |
|
| 775 | - * @throws EE_Error |
|
| 776 | - */ |
|
| 777 | - public function get_other_js_data($form_other_js_data = array()) |
|
| 778 | - { |
|
| 779 | - foreach ($this->subsections() as $subsection) { |
|
| 780 | - $form_other_js_data = $subsection->get_other_js_data($form_other_js_data); |
|
| 781 | - } |
|
| 782 | - return $form_other_js_data; |
|
| 783 | - } |
|
| 784 | - |
|
| 785 | - |
|
| 786 | - /** |
|
| 787 | - * Gets a flat array of inputs for this form section and its subsections. |
|
| 788 | - * Keys are their form names, and values are the inputs themselves |
|
| 789 | - * |
|
| 790 | - * @return EE_Form_Input_Base |
|
| 791 | - * @throws EE_Error |
|
| 792 | - */ |
|
| 793 | - public function inputs_in_subsections() |
|
| 794 | - { |
|
| 795 | - $inputs = array(); |
|
| 796 | - foreach ($this->subsections() as $subsection) { |
|
| 797 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 798 | - $inputs[ $subsection->html_name() ] = $subsection; |
|
| 799 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 800 | - $inputs += $subsection->inputs_in_subsections(); |
|
| 801 | - } |
|
| 802 | - } |
|
| 803 | - return $inputs; |
|
| 804 | - } |
|
| 805 | - |
|
| 806 | - |
|
| 807 | - /** |
|
| 808 | - * Gets a flat array of all the validation errors. |
|
| 809 | - * Keys are html names (because those should be unique) |
|
| 810 | - * and values are a string of all their validation errors |
|
| 811 | - * |
|
| 812 | - * @return string[] |
|
| 813 | - * @throws EE_Error |
|
| 814 | - */ |
|
| 815 | - public function subsection_validation_errors_by_html_name() |
|
| 816 | - { |
|
| 817 | - $inputs = $this->inputs(); |
|
| 818 | - $errors = array(); |
|
| 819 | - foreach ($inputs as $form_input) { |
|
| 820 | - if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) { |
|
| 821 | - $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string(); |
|
| 822 | - } |
|
| 823 | - } |
|
| 824 | - return $errors; |
|
| 825 | - } |
|
| 826 | - |
|
| 827 | - |
|
| 828 | - /** |
|
| 829 | - * passes all the form data required by the JS to the JS, and enqueues the few required JS files. |
|
| 830 | - * Should be setup by each form during the _enqueues_and_localize_form_js |
|
| 831 | - * |
|
| 832 | - * @throws InvalidArgumentException |
|
| 833 | - * @throws InvalidInterfaceException |
|
| 834 | - * @throws InvalidDataTypeException |
|
| 835 | - */ |
|
| 836 | - public static function localize_script_for_all_forms() |
|
| 837 | - { |
|
| 838 | - // allow inputs and stuff to hook in their JS and stuff here |
|
| 839 | - do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin'); |
|
| 840 | - EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages(); |
|
| 841 | - $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level) |
|
| 842 | - ? EE_Registry::instance()->CFG->registration->email_validation_level |
|
| 843 | - : 'wp_default'; |
|
| 844 | - EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 845 | - wp_enqueue_script('ee_form_section_validation'); |
|
| 846 | - wp_localize_script( |
|
| 847 | - 'ee_form_section_validation', |
|
| 848 | - 'ee_form_section_vars', |
|
| 849 | - EE_Form_Section_Proper::$_js_localization |
|
| 850 | - ); |
|
| 851 | - } |
|
| 852 | - |
|
| 853 | - |
|
| 854 | - /** |
|
| 855 | - * ensure_scripts_localized |
|
| 856 | - * |
|
| 857 | - * @throws EE_Error |
|
| 858 | - */ |
|
| 859 | - public function ensure_scripts_localized() |
|
| 860 | - { |
|
| 861 | - if (! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 862 | - $this->_enqueue_and_localize_form_js(); |
|
| 863 | - } |
|
| 864 | - } |
|
| 865 | - |
|
| 866 | - |
|
| 867 | - /** |
|
| 868 | - * Gets the hard-coded validation error messages to be used in the JS. The convention |
|
| 869 | - * is that the key here should be the same as the custom validation rule put in the JS file |
|
| 870 | - * |
|
| 871 | - * @return array keys are custom validation rules, and values are internationalized strings |
|
| 872 | - */ |
|
| 873 | - private static function _get_localized_error_messages() |
|
| 874 | - { |
|
| 875 | - return array( |
|
| 876 | - 'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'), |
|
| 877 | - 'regex' => esc_html__('Please check your input', 'event_espresso'), |
|
| 878 | - ); |
|
| 879 | - } |
|
| 880 | - |
|
| 881 | - |
|
| 882 | - /** |
|
| 883 | - * @return array |
|
| 884 | - */ |
|
| 885 | - public static function js_localization() |
|
| 886 | - { |
|
| 887 | - return self::$_js_localization; |
|
| 888 | - } |
|
| 889 | - |
|
| 890 | - |
|
| 891 | - /** |
|
| 892 | - * @return void |
|
| 893 | - */ |
|
| 894 | - public static function reset_js_localization() |
|
| 895 | - { |
|
| 896 | - self::$_js_localization = array(); |
|
| 897 | - } |
|
| 898 | - |
|
| 899 | - |
|
| 900 | - /** |
|
| 901 | - * Gets the JS to put inside the jquery validation rules for subsection of this form section. |
|
| 902 | - * See parent function for more... |
|
| 903 | - * |
|
| 904 | - * @return array |
|
| 905 | - * @throws EE_Error |
|
| 906 | - */ |
|
| 907 | - public function get_jquery_validation_rules() |
|
| 908 | - { |
|
| 909 | - $jquery_validation_rules = array(); |
|
| 910 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 911 | - $jquery_validation_rules = array_merge( |
|
| 912 | - $jquery_validation_rules, |
|
| 913 | - $subsection->get_jquery_validation_rules() |
|
| 914 | - ); |
|
| 915 | - } |
|
| 916 | - return $jquery_validation_rules; |
|
| 917 | - } |
|
| 918 | - |
|
| 919 | - |
|
| 920 | - /** |
|
| 921 | - * Sanitizes all the data and sets the sanitized value of each field |
|
| 922 | - * |
|
| 923 | - * @param array $req_data like $_POST |
|
| 924 | - * @return void |
|
| 925 | - * @throws EE_Error |
|
| 926 | - */ |
|
| 927 | - protected function _normalize($req_data) |
|
| 928 | - { |
|
| 929 | - $this->_received_submission = true; |
|
| 930 | - $this->_validation_errors = array(); |
|
| 931 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 932 | - try { |
|
| 933 | - $subsection->_normalize($req_data); |
|
| 934 | - } catch (EE_Validation_Error $e) { |
|
| 935 | - $subsection->add_validation_error($e); |
|
| 936 | - } |
|
| 937 | - } |
|
| 938 | - } |
|
| 939 | - |
|
| 940 | - |
|
| 941 | - /** |
|
| 942 | - * Performs validation on this form section and its subsections. |
|
| 943 | - * For each subsection, |
|
| 944 | - * calls _validate_{subsection_name} on THIS form (if the function exists) |
|
| 945 | - * and passes it the subsection, then calls _validate on that subsection. |
|
| 946 | - * If you need to perform validation on the form as a whole (considering multiple) |
|
| 947 | - * you would be best to override this _validate method, |
|
| 948 | - * calling parent::_validate() first. |
|
| 949 | - * |
|
| 950 | - * @throws EE_Error |
|
| 951 | - */ |
|
| 952 | - protected function _validate() |
|
| 953 | - { |
|
| 954 | - // reset the cache of whether this form is valid or not- we're re-validating it now |
|
| 955 | - $this->is_valid = null; |
|
| 956 | - foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
| 957 | - if (method_exists($this, '_validate_' . $subsection_name)) { |
|
| 958 | - call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection)); |
|
| 959 | - } |
|
| 960 | - $subsection->_validate(); |
|
| 961 | - } |
|
| 962 | - } |
|
| 963 | - |
|
| 964 | - |
|
| 965 | - /** |
|
| 966 | - * Gets all the validated inputs for the form section |
|
| 967 | - * |
|
| 968 | - * @return array |
|
| 969 | - * @throws EE_Error |
|
| 970 | - */ |
|
| 971 | - public function valid_data() |
|
| 972 | - { |
|
| 973 | - $inputs = array(); |
|
| 974 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 975 | - if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 976 | - $inputs[ $subsection_name ] = $subsection->valid_data(); |
|
| 977 | - } elseif ($subsection instanceof EE_Form_Input_Base) { |
|
| 978 | - $inputs[ $subsection_name ] = $subsection->normalized_value(); |
|
| 979 | - } |
|
| 980 | - } |
|
| 981 | - return $inputs; |
|
| 982 | - } |
|
| 983 | - |
|
| 984 | - |
|
| 985 | - /** |
|
| 986 | - * Gets all the inputs on this form section |
|
| 987 | - * |
|
| 988 | - * @return EE_Form_Input_Base[] |
|
| 989 | - * @throws EE_Error |
|
| 990 | - */ |
|
| 991 | - public function inputs() |
|
| 992 | - { |
|
| 993 | - $inputs = array(); |
|
| 994 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 995 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 996 | - $inputs[ $subsection_name ] = $subsection; |
|
| 997 | - } |
|
| 998 | - } |
|
| 999 | - return $inputs; |
|
| 1000 | - } |
|
| 1001 | - |
|
| 1002 | - |
|
| 1003 | - /** |
|
| 1004 | - * Gets all the subsections which are a proper form |
|
| 1005 | - * |
|
| 1006 | - * @return EE_Form_Section_Proper[] |
|
| 1007 | - * @throws EE_Error |
|
| 1008 | - */ |
|
| 1009 | - public function subforms() |
|
| 1010 | - { |
|
| 1011 | - $form_sections = array(); |
|
| 1012 | - foreach ($this->subsections() as $name => $obj) { |
|
| 1013 | - if ($obj instanceof EE_Form_Section_Proper) { |
|
| 1014 | - $form_sections[ $name ] = $obj; |
|
| 1015 | - } |
|
| 1016 | - } |
|
| 1017 | - return $form_sections; |
|
| 1018 | - } |
|
| 1019 | - |
|
| 1020 | - |
|
| 1021 | - /** |
|
| 1022 | - * Gets all the subsections (inputs, proper subsections, or html-only sections). |
|
| 1023 | - * Consider using inputs() or subforms() |
|
| 1024 | - * if you only want form inputs or proper form sections. |
|
| 1025 | - * |
|
| 1026 | - * @param boolean $require_construction_to_be_finalized most client code should |
|
| 1027 | - * leave this as TRUE so that the inputs will be properly |
|
| 1028 | - * configured. However, some client code may be ok with |
|
| 1029 | - * construction finalize being called later |
|
| 1030 | - * (realizing that the subsections' html names might not be |
|
| 1031 | - * set yet, etc.) |
|
| 1032 | - * @return EE_Form_Section_Proper[] |
|
| 1033 | - * @throws EE_Error |
|
| 1034 | - */ |
|
| 1035 | - public function subsections($require_construction_to_be_finalized = true) |
|
| 1036 | - { |
|
| 1037 | - if ($require_construction_to_be_finalized) { |
|
| 1038 | - $this->ensure_construct_finalized_called(); |
|
| 1039 | - } |
|
| 1040 | - return $this->_subsections; |
|
| 1041 | - } |
|
| 1042 | - |
|
| 1043 | - |
|
| 1044 | - /** |
|
| 1045 | - * Returns whether this form has any subforms or inputs |
|
| 1046 | - * @return bool |
|
| 1047 | - */ |
|
| 1048 | - public function hasSubsections() |
|
| 1049 | - { |
|
| 1050 | - return ! empty($this->_subsections); |
|
| 1051 | - } |
|
| 1052 | - |
|
| 1053 | - |
|
| 1054 | - /** |
|
| 1055 | - * Returns a simple array where keys are input names, and values are their normalized |
|
| 1056 | - * values. (Similar to calling get_input_value on inputs) |
|
| 1057 | - * |
|
| 1058 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1059 | - * or just this forms' direct children inputs |
|
| 1060 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1061 | - * or allow multidimensional array |
|
| 1062 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1063 | - * with array keys being input names |
|
| 1064 | - * (regardless of whether they are from a subsection or not), |
|
| 1065 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1066 | - * where keys are always subsection names and values are either |
|
| 1067 | - * the input's normalized value, or an array like the top-level array |
|
| 1068 | - * @throws EE_Error |
|
| 1069 | - */ |
|
| 1070 | - public function input_values($include_subform_inputs = false, $flatten = false) |
|
| 1071 | - { |
|
| 1072 | - return $this->_input_values(false, $include_subform_inputs, $flatten); |
|
| 1073 | - } |
|
| 1074 | - |
|
| 1075 | - |
|
| 1076 | - /** |
|
| 1077 | - * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value' |
|
| 1078 | - * of each input. On some inputs (especially radio boxes or checkboxes), the value stored |
|
| 1079 | - * is not necessarily the value we want to display to users. This creates an array |
|
| 1080 | - * where keys are the input names, and values are their display values |
|
| 1081 | - * |
|
| 1082 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1083 | - * or just this forms' direct children inputs |
|
| 1084 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1085 | - * or allow multidimensional array |
|
| 1086 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1087 | - * with array keys being input names |
|
| 1088 | - * (regardless of whether they are from a subsection or not), |
|
| 1089 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1090 | - * where keys are always subsection names and values are either |
|
| 1091 | - * the input's normalized value, or an array like the top-level array |
|
| 1092 | - * @throws EE_Error |
|
| 1093 | - */ |
|
| 1094 | - public function input_pretty_values($include_subform_inputs = false, $flatten = false) |
|
| 1095 | - { |
|
| 1096 | - return $this->_input_values(true, $include_subform_inputs, $flatten); |
|
| 1097 | - } |
|
| 1098 | - |
|
| 1099 | - |
|
| 1100 | - /** |
|
| 1101 | - * Gets the input values from the form |
|
| 1102 | - * |
|
| 1103 | - * @param boolean $pretty Whether to retrieve the pretty value, |
|
| 1104 | - * or just the normalized value |
|
| 1105 | - * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1106 | - * or just this forms' direct children inputs |
|
| 1107 | - * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1108 | - * or allow multidimensional array |
|
| 1109 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being |
|
| 1110 | - * input names (regardless of whether they are from a subsection or not), |
|
| 1111 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1112 | - * where keys are always subsection names and values are either |
|
| 1113 | - * the input's normalized value, or an array like the top-level array |
|
| 1114 | - * @throws EE_Error |
|
| 1115 | - */ |
|
| 1116 | - public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false) |
|
| 1117 | - { |
|
| 1118 | - $input_values = array(); |
|
| 1119 | - foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 1120 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1121 | - $input_values[ $subsection_name ] = $pretty |
|
| 1122 | - ? $subsection->pretty_value() |
|
| 1123 | - : $subsection->normalized_value(); |
|
| 1124 | - } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) { |
|
| 1125 | - $subform_input_values = $subsection->_input_values( |
|
| 1126 | - $pretty, |
|
| 1127 | - $include_subform_inputs, |
|
| 1128 | - $flatten |
|
| 1129 | - ); |
|
| 1130 | - if ($flatten) { |
|
| 1131 | - $input_values = array_merge($input_values, $subform_input_values); |
|
| 1132 | - } else { |
|
| 1133 | - $input_values[ $subsection_name ] = $subform_input_values; |
|
| 1134 | - } |
|
| 1135 | - } |
|
| 1136 | - } |
|
| 1137 | - return $input_values; |
|
| 1138 | - } |
|
| 1139 | - |
|
| 1140 | - |
|
| 1141 | - /** |
|
| 1142 | - * Gets the originally submitted input values from the form |
|
| 1143 | - * |
|
| 1144 | - * @param boolean $include_subforms Whether to include inputs from subforms, |
|
| 1145 | - * or just this forms' direct children inputs |
|
| 1146 | - * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1147 | - * with array keys being input names |
|
| 1148 | - * (regardless of whether they are from a subsection or not), |
|
| 1149 | - * and if $flatten is FALSE it can be a multidimensional array |
|
| 1150 | - * where keys are always subsection names and values are either |
|
| 1151 | - * the input's normalized value, or an array like the top-level array |
|
| 1152 | - * @throws EE_Error |
|
| 1153 | - */ |
|
| 1154 | - public function submitted_values($include_subforms = false) |
|
| 1155 | - { |
|
| 1156 | - $submitted_values = array(); |
|
| 1157 | - foreach ($this->subsections() as $subsection) { |
|
| 1158 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1159 | - // is this input part of an array of inputs? |
|
| 1160 | - if (strpos($subsection->html_name(), '[') !== false) { |
|
| 1161 | - $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1162 | - explode( |
|
| 1163 | - '[', |
|
| 1164 | - str_replace(']', '', $subsection->html_name()) |
|
| 1165 | - ), |
|
| 1166 | - $subsection->raw_value() |
|
| 1167 | - ); |
|
| 1168 | - $submitted_values = array_replace_recursive($submitted_values, $full_input_name); |
|
| 1169 | - } else { |
|
| 1170 | - $submitted_values[ $subsection->html_name() ] = $subsection->raw_value(); |
|
| 1171 | - } |
|
| 1172 | - } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) { |
|
| 1173 | - $subform_input_values = $subsection->submitted_values($include_subforms); |
|
| 1174 | - $submitted_values = array_replace_recursive($submitted_values, $subform_input_values); |
|
| 1175 | - } |
|
| 1176 | - } |
|
| 1177 | - return $submitted_values; |
|
| 1178 | - } |
|
| 1179 | - |
|
| 1180 | - |
|
| 1181 | - /** |
|
| 1182 | - * Indicates whether or not this form has received a submission yet |
|
| 1183 | - * (ie, had receive_form_submission called on it yet) |
|
| 1184 | - * |
|
| 1185 | - * @return boolean |
|
| 1186 | - * @throws EE_Error |
|
| 1187 | - */ |
|
| 1188 | - public function has_received_submission() |
|
| 1189 | - { |
|
| 1190 | - $this->ensure_construct_finalized_called(); |
|
| 1191 | - return $this->_received_submission; |
|
| 1192 | - } |
|
| 1193 | - |
|
| 1194 | - |
|
| 1195 | - /** |
|
| 1196 | - * Equivalent to passing 'exclude' in the constructor's options array. |
|
| 1197 | - * Removes the listed inputs from the form |
|
| 1198 | - * |
|
| 1199 | - * @param array $inputs_to_exclude values are the input names |
|
| 1200 | - * @return void |
|
| 1201 | - */ |
|
| 1202 | - public function exclude(array $inputs_to_exclude = array()) |
|
| 1203 | - { |
|
| 1204 | - foreach ($inputs_to_exclude as $input_to_exclude_name) { |
|
| 1205 | - unset($this->_subsections[ $input_to_exclude_name ]); |
|
| 1206 | - } |
|
| 1207 | - } |
|
| 1208 | - |
|
| 1209 | - |
|
| 1210 | - /** |
|
| 1211 | - * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy. |
|
| 1212 | - * @param array $inputs_to_hide |
|
| 1213 | - * @throws EE_Error |
|
| 1214 | - */ |
|
| 1215 | - public function hide(array $inputs_to_hide = array()) |
|
| 1216 | - { |
|
| 1217 | - foreach ($inputs_to_hide as $input_to_hide) { |
|
| 1218 | - $input = $this->get_input($input_to_hide); |
|
| 1219 | - $input->set_display_strategy(new EE_Hidden_Display_Strategy()); |
|
| 1220 | - } |
|
| 1221 | - } |
|
| 1222 | - |
|
| 1223 | - |
|
| 1224 | - /** |
|
| 1225 | - * add_subsections |
|
| 1226 | - * Adds the listed subsections to the form section. |
|
| 1227 | - * If $subsection_name_to_target is provided, |
|
| 1228 | - * then new subsections are added before or after that subsection, |
|
| 1229 | - * otherwise to the start or end of the entire subsections array. |
|
| 1230 | - * |
|
| 1231 | - * @param EE_Form_Section_Base[] $new_subsections array of new form subsections |
|
| 1232 | - * where keys are their names |
|
| 1233 | - * @param string $subsection_name_to_target an existing for section that $new_subsections |
|
| 1234 | - * should be added before or after |
|
| 1235 | - * IF $subsection_name_to_target is null, |
|
| 1236 | - * then $new_subsections will be added to |
|
| 1237 | - * the beginning or end of the entire subsections array |
|
| 1238 | - * @param boolean $add_before whether to add $new_subsections, before or after |
|
| 1239 | - * $subsection_name_to_target, |
|
| 1240 | - * or if $subsection_name_to_target is null, |
|
| 1241 | - * before or after entire subsections array |
|
| 1242 | - * @return void |
|
| 1243 | - * @throws EE_Error |
|
| 1244 | - */ |
|
| 1245 | - public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true) |
|
| 1246 | - { |
|
| 1247 | - foreach ($new_subsections as $subsection_name => $subsection) { |
|
| 1248 | - if (! $subsection instanceof EE_Form_Section_Base) { |
|
| 1249 | - EE_Error::add_error( |
|
| 1250 | - sprintf( |
|
| 1251 | - esc_html__( |
|
| 1252 | - "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.", |
|
| 1253 | - 'event_espresso' |
|
| 1254 | - ), |
|
| 1255 | - get_class($subsection), |
|
| 1256 | - $subsection_name, |
|
| 1257 | - $this->name() |
|
| 1258 | - ) |
|
| 1259 | - ); |
|
| 1260 | - unset($new_subsections[ $subsection_name ]); |
|
| 1261 | - } |
|
| 1262 | - } |
|
| 1263 | - $this->_subsections = EEH_Array::insert_into_array( |
|
| 1264 | - $this->_subsections, |
|
| 1265 | - $new_subsections, |
|
| 1266 | - $subsection_name_to_target, |
|
| 1267 | - $add_before |
|
| 1268 | - ); |
|
| 1269 | - if ($this->_construction_finalized) { |
|
| 1270 | - foreach ($this->_subsections as $name => $subsection) { |
|
| 1271 | - $subsection->_construct_finalize($this, $name); |
|
| 1272 | - } |
|
| 1273 | - } |
|
| 1274 | - } |
|
| 1275 | - |
|
| 1276 | - |
|
| 1277 | - /** |
|
| 1278 | - * @param string $subsection_name |
|
| 1279 | - * @param bool $recursive |
|
| 1280 | - * @return bool |
|
| 1281 | - */ |
|
| 1282 | - public function has_subsection($subsection_name, $recursive = false) |
|
| 1283 | - { |
|
| 1284 | - foreach ($this->_subsections as $name => $subsection) { |
|
| 1285 | - if ($name === $subsection_name |
|
| 1286 | - || ( |
|
| 1287 | - $recursive |
|
| 1288 | - && $subsection instanceof EE_Form_Section_Proper |
|
| 1289 | - && $subsection->has_subsection($subsection_name, $recursive) |
|
| 1290 | - ) |
|
| 1291 | - ) { |
|
| 1292 | - return true; |
|
| 1293 | - } |
|
| 1294 | - } |
|
| 1295 | - return false; |
|
| 1296 | - } |
|
| 1297 | - |
|
| 1298 | - |
|
| 1299 | - |
|
| 1300 | - /** |
|
| 1301 | - * Just gets all validatable subsections to clean their sensitive data |
|
| 1302 | - * |
|
| 1303 | - * @throws EE_Error |
|
| 1304 | - */ |
|
| 1305 | - public function clean_sensitive_data() |
|
| 1306 | - { |
|
| 1307 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1308 | - $subsection->clean_sensitive_data(); |
|
| 1309 | - } |
|
| 1310 | - } |
|
| 1311 | - |
|
| 1312 | - |
|
| 1313 | - /** |
|
| 1314 | - * Sets the submission error message (aka validation error message for this form section and all sub-sections) |
|
| 1315 | - * @param string $form_submission_error_message |
|
| 1316 | - * @param EE_Form_Section_Validatable $form_section unused |
|
| 1317 | - * @throws EE_Error |
|
| 1318 | - */ |
|
| 1319 | - public function set_submission_error_message( |
|
| 1320 | - $form_submission_error_message = '' |
|
| 1321 | - ) { |
|
| 1322 | - $this->_form_submission_error_message = ! empty($form_submission_error_message) |
|
| 1323 | - ? $form_submission_error_message |
|
| 1324 | - : $this->getAllValidationErrorsString(); |
|
| 1325 | - } |
|
| 1326 | - |
|
| 1327 | - |
|
| 1328 | - /** |
|
| 1329 | - * Returns the cached error message. A default value is set for this during _validate(), |
|
| 1330 | - * (called during receive_form_submission) but it can be explicitly set using |
|
| 1331 | - * set_submission_error_message |
|
| 1332 | - * |
|
| 1333 | - * @return string |
|
| 1334 | - */ |
|
| 1335 | - public function submission_error_message() |
|
| 1336 | - { |
|
| 1337 | - return $this->_form_submission_error_message; |
|
| 1338 | - } |
|
| 1339 | - |
|
| 1340 | - |
|
| 1341 | - /** |
|
| 1342 | - * Sets a message to display if the data submitted to the form was valid. |
|
| 1343 | - * @param string $form_submission_success_message |
|
| 1344 | - */ |
|
| 1345 | - public function set_submission_success_message($form_submission_success_message = '') |
|
| 1346 | - { |
|
| 1347 | - $this->_form_submission_success_message = ! empty($form_submission_success_message) |
|
| 1348 | - ? $form_submission_success_message |
|
| 1349 | - : esc_html__('Form submitted successfully', 'event_espresso'); |
|
| 1350 | - } |
|
| 1351 | - |
|
| 1352 | - |
|
| 1353 | - /** |
|
| 1354 | - * Gets a message appropriate for display when the form is correctly submitted |
|
| 1355 | - * @return string |
|
| 1356 | - */ |
|
| 1357 | - public function submission_success_message() |
|
| 1358 | - { |
|
| 1359 | - return $this->_form_submission_success_message; |
|
| 1360 | - } |
|
| 1361 | - |
|
| 1362 | - |
|
| 1363 | - /** |
|
| 1364 | - * Returns the prefix that should be used on child of this form section for |
|
| 1365 | - * their html names. If this form section itself has a parent, prepends ITS |
|
| 1366 | - * prefix onto this form section's prefix. Used primarily by |
|
| 1367 | - * EE_Form_Input_Base::_set_default_html_name_if_empty |
|
| 1368 | - * |
|
| 1369 | - * @return string |
|
| 1370 | - * @throws EE_Error |
|
| 1371 | - */ |
|
| 1372 | - public function html_name_prefix() |
|
| 1373 | - { |
|
| 1374 | - if ($this->parent_section() instanceof EE_Form_Section_Proper) { |
|
| 1375 | - return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']'; |
|
| 1376 | - } |
|
| 1377 | - return $this->name(); |
|
| 1378 | - } |
|
| 1379 | - |
|
| 1380 | - |
|
| 1381 | - /** |
|
| 1382 | - * Gets the name, but first checks _construct_finalize has been called. If not, |
|
| 1383 | - * calls it (assumes there is no parent and that we want the name to be whatever |
|
| 1384 | - * was set, which is probably nothing, or the classname) |
|
| 1385 | - * |
|
| 1386 | - * @return string |
|
| 1387 | - * @throws EE_Error |
|
| 1388 | - */ |
|
| 1389 | - public function name() |
|
| 1390 | - { |
|
| 1391 | - $this->ensure_construct_finalized_called(); |
|
| 1392 | - return parent::name(); |
|
| 1393 | - } |
|
| 1394 | - |
|
| 1395 | - |
|
| 1396 | - /** |
|
| 1397 | - * @return EE_Form_Section_Proper |
|
| 1398 | - * @throws EE_Error |
|
| 1399 | - */ |
|
| 1400 | - public function parent_section() |
|
| 1401 | - { |
|
| 1402 | - $this->ensure_construct_finalized_called(); |
|
| 1403 | - return parent::parent_section(); |
|
| 1404 | - } |
|
| 1405 | - |
|
| 1406 | - |
|
| 1407 | - /** |
|
| 1408 | - * make sure construction finalized was called, otherwise children might not be ready |
|
| 1409 | - * |
|
| 1410 | - * @return void |
|
| 1411 | - * @throws EE_Error |
|
| 1412 | - */ |
|
| 1413 | - public function ensure_construct_finalized_called() |
|
| 1414 | - { |
|
| 1415 | - if (! $this->_construction_finalized) { |
|
| 1416 | - $this->_construct_finalize($this->_parent_section, $this->_name); |
|
| 1417 | - } |
|
| 1418 | - } |
|
| 1419 | - |
|
| 1420 | - |
|
| 1421 | - /** |
|
| 1422 | - * Checks if any of this form section's inputs, or any of its children's inputs, |
|
| 1423 | - * are in teh form data. If any are found, returns true. Else false |
|
| 1424 | - * |
|
| 1425 | - * @param array $req_data |
|
| 1426 | - * @return boolean |
|
| 1427 | - * @throws EE_Error |
|
| 1428 | - */ |
|
| 1429 | - public function form_data_present_in($req_data = null) |
|
| 1430 | - { |
|
| 1431 | - $req_data = $this->getCachedRequest($req_data); |
|
| 1432 | - foreach ($this->subsections() as $subsection) { |
|
| 1433 | - if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1434 | - if ($subsection->form_data_present_in($req_data)) { |
|
| 1435 | - return true; |
|
| 1436 | - } |
|
| 1437 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1438 | - if ($subsection->form_data_present_in($req_data)) { |
|
| 1439 | - return true; |
|
| 1440 | - } |
|
| 1441 | - } |
|
| 1442 | - } |
|
| 1443 | - return false; |
|
| 1444 | - } |
|
| 1445 | - |
|
| 1446 | - |
|
| 1447 | - /** |
|
| 1448 | - * Gets validation errors for this form section and subsections |
|
| 1449 | - * Similar to EE_Form_Section_Validatable::get_validation_errors() except this |
|
| 1450 | - * gets the validation errors for ALL subsection |
|
| 1451 | - * |
|
| 1452 | - * @return EE_Validation_Error[] |
|
| 1453 | - * @throws EE_Error |
|
| 1454 | - */ |
|
| 1455 | - public function get_validation_errors_accumulated() |
|
| 1456 | - { |
|
| 1457 | - $validation_errors = $this->get_validation_errors(); |
|
| 1458 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1459 | - if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1460 | - $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated(); |
|
| 1461 | - } else { |
|
| 1462 | - $validation_errors_on_this_subsection = $subsection->get_validation_errors(); |
|
| 1463 | - } |
|
| 1464 | - if ($validation_errors_on_this_subsection) { |
|
| 1465 | - $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection); |
|
| 1466 | - } |
|
| 1467 | - } |
|
| 1468 | - return $validation_errors; |
|
| 1469 | - } |
|
| 1470 | - |
|
| 1471 | - /** |
|
| 1472 | - * Fetch validation errors from children and grandchildren and puts them in a single string. |
|
| 1473 | - * This traverses the form section tree to generate this, but you probably want to instead use |
|
| 1474 | - * get_form_submission_error_message() which is usually this message cached (or a custom validation error message) |
|
| 1475 | - * |
|
| 1476 | - * @return string |
|
| 1477 | - * @since 4.9.59.p |
|
| 1478 | - */ |
|
| 1479 | - protected function getAllValidationErrorsString() |
|
| 1480 | - { |
|
| 1481 | - $submission_error_messages = array(); |
|
| 1482 | - // bad, bad, bad registrant |
|
| 1483 | - foreach ($this->get_validation_errors_accumulated() as $validation_error) { |
|
| 1484 | - if ($validation_error instanceof EE_Validation_Error) { |
|
| 1485 | - $form_section = $validation_error->get_form_section(); |
|
| 1486 | - if ($form_section instanceof EE_Form_Input_Base) { |
|
| 1487 | - $label = $validation_error->get_form_section()->html_label_text(); |
|
| 1488 | - } elseif ($form_section instanceof EE_Form_Section_Validatable) { |
|
| 1489 | - $label = $validation_error->get_form_section()->name(); |
|
| 1490 | - } else { |
|
| 1491 | - $label = esc_html__('Unknown', 'event_espresso'); |
|
| 1492 | - } |
|
| 1493 | - $submission_error_messages[] = sprintf( |
|
| 1494 | - __('%s : %s', 'event_espresso'), |
|
| 1495 | - $label, |
|
| 1496 | - $validation_error->getMessage() |
|
| 1497 | - ); |
|
| 1498 | - } |
|
| 1499 | - } |
|
| 1500 | - return implode('<br', $submission_error_messages); |
|
| 1501 | - } |
|
| 1502 | - |
|
| 1503 | - |
|
| 1504 | - /** |
|
| 1505 | - * This isn't just the name of an input, it's a path pointing to an input. The |
|
| 1506 | - * path is similar to a folder path: slash (/) means to descend into a subsection, |
|
| 1507 | - * dot-dot-slash (../) means to ascend into the parent section. |
|
| 1508 | - * After a series of slashes and dot-dot-slashes, there should be the name of an input, |
|
| 1509 | - * which will be returned. |
|
| 1510 | - * Eg, if you want the related input to be conditional on a sibling input name 'foobar' |
|
| 1511 | - * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name |
|
| 1512 | - * 'baz', use '../baz'. If you want it to be conditional on a cousin input, |
|
| 1513 | - * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'. |
|
| 1514 | - * Etc |
|
| 1515 | - * |
|
| 1516 | - * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false |
|
| 1517 | - * @return EE_Form_Section_Base |
|
| 1518 | - * @throws EE_Error |
|
| 1519 | - */ |
|
| 1520 | - public function find_section_from_path($form_section_path) |
|
| 1521 | - { |
|
| 1522 | - // check if we can find the input from purely going straight up the tree |
|
| 1523 | - $input = parent::find_section_from_path($form_section_path); |
|
| 1524 | - if ($input instanceof EE_Form_Section_Base) { |
|
| 1525 | - return $input; |
|
| 1526 | - } |
|
| 1527 | - $next_slash_pos = strpos($form_section_path, '/'); |
|
| 1528 | - if ($next_slash_pos !== false) { |
|
| 1529 | - $child_section_name = substr($form_section_path, 0, $next_slash_pos); |
|
| 1530 | - $subpath = substr($form_section_path, $next_slash_pos + 1); |
|
| 1531 | - } else { |
|
| 1532 | - $child_section_name = $form_section_path; |
|
| 1533 | - $subpath = ''; |
|
| 1534 | - } |
|
| 1535 | - $child_section = $this->get_subsection($child_section_name); |
|
| 1536 | - if ($child_section instanceof EE_Form_Section_Base) { |
|
| 1537 | - return $child_section->find_section_from_path($subpath); |
|
| 1538 | - } |
|
| 1539 | - return null; |
|
| 1540 | - } |
|
| 17 | + const SUBMITTED_FORM_DATA_SSN_KEY = 'submitted_form_data'; |
|
| 18 | + |
|
| 19 | + /** |
|
| 20 | + * Subsections |
|
| 21 | + * |
|
| 22 | + * @var EE_Form_Section_Validatable[] |
|
| 23 | + */ |
|
| 24 | + protected $_subsections = array(); |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * Strategy for laying out the form |
|
| 28 | + * |
|
| 29 | + * @var EE_Form_Section_Layout_Base |
|
| 30 | + */ |
|
| 31 | + protected $_layout_strategy; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * Whether or not this form has received and validated a form submission yet |
|
| 35 | + * |
|
| 36 | + * @var boolean |
|
| 37 | + */ |
|
| 38 | + protected $_received_submission = false; |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * message displayed to users upon successful form submission |
|
| 42 | + * |
|
| 43 | + * @var string |
|
| 44 | + */ |
|
| 45 | + protected $_form_submission_success_message = ''; |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * message displayed to users upon unsuccessful form submission |
|
| 49 | + * |
|
| 50 | + * @var string |
|
| 51 | + */ |
|
| 52 | + protected $_form_submission_error_message = ''; |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * @var array like $_REQUEST |
|
| 56 | + */ |
|
| 57 | + protected $cached_request_data; |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + * Stores whether this form (and its sub-sections) were found to be valid or not. |
|
| 61 | + * Starts off as null, but once the form is validated, it set to either true or false |
|
| 62 | + * @var boolean|null |
|
| 63 | + */ |
|
| 64 | + protected $is_valid; |
|
| 65 | + |
|
| 66 | + /** |
|
| 67 | + * Stores all the data that will localized for form validation |
|
| 68 | + * |
|
| 69 | + * @var array |
|
| 70 | + */ |
|
| 71 | + static protected $_js_localization = array(); |
|
| 72 | + |
|
| 73 | + /** |
|
| 74 | + * whether or not the form's localized validation JS vars have been set |
|
| 75 | + * |
|
| 76 | + * @type boolean |
|
| 77 | + */ |
|
| 78 | + static protected $_scripts_localized = false; |
|
| 79 | + |
|
| 80 | + |
|
| 81 | + /** |
|
| 82 | + * when constructing a proper form section, calls _construct_finalize on children |
|
| 83 | + * so that they know who their parent is, and what name they've been given. |
|
| 84 | + * |
|
| 85 | + * @param array[] $options_array { |
|
| 86 | + * @type $subsections EE_Form_Section_Validatable[] where keys are the section's name |
|
| 87 | + * @type $include string[] numerically-indexed where values are section names to be included, |
|
| 88 | + * and in that order. This is handy if you want |
|
| 89 | + * the subsections to be ordered differently than the default, and if you override |
|
| 90 | + * which fields are shown |
|
| 91 | + * @type $exclude string[] values are subsections to be excluded. This is handy if you want |
|
| 92 | + * to remove certain default subsections (note: if you specify BOTH 'include' AND |
|
| 93 | + * 'exclude', the inclusions will be applied first, and the exclusions will exclude |
|
| 94 | + * items from that list of inclusions) |
|
| 95 | + * @type $layout_strategy EE_Form_Section_Layout_Base strategy for laying out the form |
|
| 96 | + * } @see EE_Form_Section_Validatable::__construct() |
|
| 97 | + * @throws EE_Error |
|
| 98 | + */ |
|
| 99 | + public function __construct($options_array = array()) |
|
| 100 | + { |
|
| 101 | + $options_array = (array) apply_filters( |
|
| 102 | + 'FHEE__EE_Form_Section_Proper___construct__options_array', |
|
| 103 | + $options_array, |
|
| 104 | + $this |
|
| 105 | + ); |
|
| 106 | + // call parent first, as it may be setting the name |
|
| 107 | + parent::__construct($options_array); |
|
| 108 | + // if they've included subsections in the constructor, add them now |
|
| 109 | + if (isset($options_array['include'])) { |
|
| 110 | + // we are going to make sure we ONLY have those subsections to include |
|
| 111 | + // AND we are going to make sure they're in that specified order |
|
| 112 | + $reordered_subsections = array(); |
|
| 113 | + foreach ($options_array['include'] as $input_name) { |
|
| 114 | + if (isset($this->_subsections[ $input_name ])) { |
|
| 115 | + $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ]; |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + $this->_subsections = $reordered_subsections; |
|
| 119 | + } |
|
| 120 | + if (isset($options_array['exclude'])) { |
|
| 121 | + $exclude = $options_array['exclude']; |
|
| 122 | + $this->_subsections = array_diff_key($this->_subsections, array_flip($exclude)); |
|
| 123 | + } |
|
| 124 | + if (isset($options_array['layout_strategy'])) { |
|
| 125 | + $this->_layout_strategy = $options_array['layout_strategy']; |
|
| 126 | + } |
|
| 127 | + if (! $this->_layout_strategy) { |
|
| 128 | + $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout(); |
|
| 129 | + } |
|
| 130 | + $this->_layout_strategy->_construct_finalize($this); |
|
| 131 | + // ok so we are definitely going to want the forms JS, |
|
| 132 | + // so enqueue it or remember to enqueue it during wp_enqueue_scripts |
|
| 133 | + if (did_action('wp_enqueue_scripts') || did_action('admin_enqueue_scripts')) { |
|
| 134 | + // ok so they've constructed this object after when they should have. |
|
| 135 | + // just enqueue the generic form scripts and initialize the form immediately in the JS |
|
| 136 | + EE_Form_Section_Proper::wp_enqueue_scripts(true); |
|
| 137 | + } else { |
|
| 138 | + add_action('wp_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 139 | + add_action('admin_enqueue_scripts', array('EE_Form_Section_Proper', 'wp_enqueue_scripts')); |
|
| 140 | + } |
|
| 141 | + add_action('wp_footer', array($this, 'ensure_scripts_localized'), 1); |
|
| 142 | + /** |
|
| 143 | + * Gives other plugins a chance to hook in before construct finalize is called. |
|
| 144 | + * The form probably doesn't yet have a parent form section. |
|
| 145 | + * Since 4.9.32, when this action was introduced, this is the best place to add a subsection onto a form, |
|
| 146 | + * assuming you don't care what the form section's name, HTML ID, or HTML name etc are. |
|
| 147 | + * Also see AHEE__EE_Form_Section_Proper___construct_finalize__end |
|
| 148 | + * |
|
| 149 | + * @since 4.9.32 |
|
| 150 | + * @param EE_Form_Section_Proper $this before __construct is done, but all of its logic, |
|
| 151 | + * except maybe calling _construct_finalize has been done |
|
| 152 | + * @param array $options_array options passed into the constructor |
|
| 153 | + */ |
|
| 154 | + do_action( |
|
| 155 | + 'AHEE__EE_Form_Input_Base___construct__before_construct_finalize_called', |
|
| 156 | + $this, |
|
| 157 | + $options_array |
|
| 158 | + ); |
|
| 159 | + if (isset($options_array['name'])) { |
|
| 160 | + $this->_construct_finalize(null, $options_array['name']); |
|
| 161 | + } |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Finishes construction given the parent form section and this form section's name |
|
| 167 | + * |
|
| 168 | + * @param EE_Form_Section_Proper $parent_form_section |
|
| 169 | + * @param string $name |
|
| 170 | + * @throws EE_Error |
|
| 171 | + */ |
|
| 172 | + public function _construct_finalize($parent_form_section, $name) |
|
| 173 | + { |
|
| 174 | + parent::_construct_finalize($parent_form_section, $name); |
|
| 175 | + $this->_set_default_name_if_empty(); |
|
| 176 | + $this->_set_default_html_id_if_empty(); |
|
| 177 | + foreach ($this->_subsections as $subsection_name => $subsection) { |
|
| 178 | + if ($subsection instanceof EE_Form_Section_Base) { |
|
| 179 | + $subsection->_construct_finalize($this, $subsection_name); |
|
| 180 | + } else { |
|
| 181 | + throw new EE_Error( |
|
| 182 | + sprintf( |
|
| 183 | + esc_html__( |
|
| 184 | + 'Subsection "%s" is not an instanceof EE_Form_Section_Base on form "%s". It is a "%s"', |
|
| 185 | + 'event_espresso' |
|
| 186 | + ), |
|
| 187 | + $subsection_name, |
|
| 188 | + get_class($this), |
|
| 189 | + $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 190 | + ) |
|
| 191 | + ); |
|
| 192 | + } |
|
| 193 | + } |
|
| 194 | + /** |
|
| 195 | + * Action performed just after form has been given a name (and HTML ID etc) and is fully constructed. |
|
| 196 | + * If you have code that should modify the form and needs it and its subsections to have a name, HTML ID |
|
| 197 | + * (or other attributes derived from the name like the HTML label id, etc), this is where it should be done. |
|
| 198 | + * This might only happen just before displaying the form, or just before it receives form submission data. |
|
| 199 | + * If you need to modify the form or its subsections before _construct_finalize is called on it (and we've |
|
| 200 | + * ensured it has a name, HTML IDs, etc |
|
| 201 | + * |
|
| 202 | + * @param EE_Form_Section_Proper $this |
|
| 203 | + * @param EE_Form_Section_Proper|null $parent_form_section |
|
| 204 | + * @param string $name |
|
| 205 | + */ |
|
| 206 | + do_action( |
|
| 207 | + 'AHEE__EE_Form_Section_Proper___construct_finalize__end', |
|
| 208 | + $this, |
|
| 209 | + $parent_form_section, |
|
| 210 | + $name |
|
| 211 | + ); |
|
| 212 | + } |
|
| 213 | + |
|
| 214 | + |
|
| 215 | + /** |
|
| 216 | + * Gets the layout strategy for this form section |
|
| 217 | + * |
|
| 218 | + * @return EE_Form_Section_Layout_Base |
|
| 219 | + */ |
|
| 220 | + public function get_layout_strategy() |
|
| 221 | + { |
|
| 222 | + return $this->_layout_strategy; |
|
| 223 | + } |
|
| 224 | + |
|
| 225 | + |
|
| 226 | + /** |
|
| 227 | + * Gets the HTML for a single input for this form section according |
|
| 228 | + * to the layout strategy |
|
| 229 | + * |
|
| 230 | + * @param EE_Form_Input_Base $input |
|
| 231 | + * @return string |
|
| 232 | + */ |
|
| 233 | + public function get_html_for_input($input) |
|
| 234 | + { |
|
| 235 | + return $this->_layout_strategy->layout_input($input); |
|
| 236 | + } |
|
| 237 | + |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * was_submitted - checks if form inputs are present in request data |
|
| 241 | + * Basically an alias for form_data_present_in() (which is used by both |
|
| 242 | + * proper form sections and form inputs) |
|
| 243 | + * |
|
| 244 | + * @param null $form_data |
|
| 245 | + * @return boolean |
|
| 246 | + * @throws EE_Error |
|
| 247 | + */ |
|
| 248 | + public function was_submitted($form_data = null) |
|
| 249 | + { |
|
| 250 | + return $this->form_data_present_in($form_data); |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + /** |
|
| 254 | + * Gets the cached request data; but if there is none, or $req_data was set with |
|
| 255 | + * something different, refresh the cache, and then return it |
|
| 256 | + * @param null $req_data |
|
| 257 | + * @return array |
|
| 258 | + */ |
|
| 259 | + protected function getCachedRequest($req_data = null) |
|
| 260 | + { |
|
| 261 | + if ($this->cached_request_data === null |
|
| 262 | + || ( |
|
| 263 | + $req_data !== null && |
|
| 264 | + $req_data !== $this->cached_request_data |
|
| 265 | + ) |
|
| 266 | + ) { |
|
| 267 | + $req_data = apply_filters( |
|
| 268 | + 'FHEE__EE_Form_Section_Proper__receive_form_submission__req_data', |
|
| 269 | + $req_data, |
|
| 270 | + $this |
|
| 271 | + ); |
|
| 272 | + if ($req_data === null) { |
|
| 273 | + $req_data = array_merge($_GET, $_POST); |
|
| 274 | + } |
|
| 275 | + $req_data = apply_filters( |
|
| 276 | + 'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data', |
|
| 277 | + $req_data, |
|
| 278 | + $this |
|
| 279 | + ); |
|
| 280 | + $this->cached_request_data = (array) $req_data; |
|
| 281 | + } |
|
| 282 | + return $this->cached_request_data; |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + |
|
| 286 | + /** |
|
| 287 | + * After the form section is initially created, call this to sanitize the data in the submission |
|
| 288 | + * which relates to this form section, validate it, and set it as properties on the form. |
|
| 289 | + * |
|
| 290 | + * @param array|null $req_data should usually be $_POST (the default). |
|
| 291 | + * However, you CAN supply a different array. |
|
| 292 | + * Consider using set_defaults() instead however. |
|
| 293 | + * (If you rendered the form in the page using echo $form_x->get_html() |
|
| 294 | + * the inputs will have the correct name in the request data for this function |
|
| 295 | + * to find them and populate the form with them. |
|
| 296 | + * If you have a flat form (with only input subsections), |
|
| 297 | + * you can supply a flat array where keys |
|
| 298 | + * are the form input names and values are their values) |
|
| 299 | + * @param boolean $validate whether or not to perform validation on this data. Default is, |
|
| 300 | + * of course, to validate that data, and set errors on the invalid values. |
|
| 301 | + * But if the data has already been validated |
|
| 302 | + * (eg you validated the data then stored it in the DB) |
|
| 303 | + * you may want to skip this step. |
|
| 304 | + * @throws InvalidArgumentException |
|
| 305 | + * @throws InvalidInterfaceException |
|
| 306 | + * @throws InvalidDataTypeException |
|
| 307 | + * @throws EE_Error |
|
| 308 | + */ |
|
| 309 | + public function receive_form_submission($req_data = null, $validate = true) |
|
| 310 | + { |
|
| 311 | + $req_data = $this->getCachedRequest($req_data); |
|
| 312 | + $this->_normalize($req_data); |
|
| 313 | + if ($validate) { |
|
| 314 | + $this->_validate(); |
|
| 315 | + // if it's invalid, we're going to want to re-display so remember what they submitted |
|
| 316 | + if (! $this->is_valid()) { |
|
| 317 | + $this->store_submitted_form_data_in_session(); |
|
| 318 | + } |
|
| 319 | + } |
|
| 320 | + if ($this->submission_error_message() === '' && ! $this->is_valid()) { |
|
| 321 | + $this->set_submission_error_message(); |
|
| 322 | + } |
|
| 323 | + do_action( |
|
| 324 | + 'AHEE__EE_Form_Section_Proper__receive_form_submission__end', |
|
| 325 | + $req_data, |
|
| 326 | + $this, |
|
| 327 | + $validate |
|
| 328 | + ); |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + |
|
| 332 | + /** |
|
| 333 | + * caches the originally submitted input values in the session |
|
| 334 | + * so that they can be used to repopulate the form if it failed validation |
|
| 335 | + * |
|
| 336 | + * @return boolean whether or not the data was successfully stored in the session |
|
| 337 | + * @throws InvalidArgumentException |
|
| 338 | + * @throws InvalidInterfaceException |
|
| 339 | + * @throws InvalidDataTypeException |
|
| 340 | + * @throws EE_Error |
|
| 341 | + */ |
|
| 342 | + protected function store_submitted_form_data_in_session() |
|
| 343 | + { |
|
| 344 | + return EE_Registry::instance()->SSN->set_session_data( |
|
| 345 | + array( |
|
| 346 | + EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY => $this->submitted_values(true), |
|
| 347 | + ) |
|
| 348 | + ); |
|
| 349 | + } |
|
| 350 | + |
|
| 351 | + |
|
| 352 | + /** |
|
| 353 | + * retrieves the originally submitted input values in the session |
|
| 354 | + * so that they can be used to repopulate the form if it failed validation |
|
| 355 | + * |
|
| 356 | + * @return array |
|
| 357 | + * @throws InvalidArgumentException |
|
| 358 | + * @throws InvalidInterfaceException |
|
| 359 | + * @throws InvalidDataTypeException |
|
| 360 | + */ |
|
| 361 | + protected function get_submitted_form_data_from_session() |
|
| 362 | + { |
|
| 363 | + $session = EE_Registry::instance()->SSN; |
|
| 364 | + if ($session instanceof EE_Session) { |
|
| 365 | + return $session->get_session_data( |
|
| 366 | + EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY |
|
| 367 | + ); |
|
| 368 | + } |
|
| 369 | + return array(); |
|
| 370 | + } |
|
| 371 | + |
|
| 372 | + |
|
| 373 | + /** |
|
| 374 | + * flushed the originally submitted input values from the session |
|
| 375 | + * |
|
| 376 | + * @return boolean whether or not the data was successfully removed from the session |
|
| 377 | + * @throws InvalidArgumentException |
|
| 378 | + * @throws InvalidInterfaceException |
|
| 379 | + * @throws InvalidDataTypeException |
|
| 380 | + */ |
|
| 381 | + public static function flush_submitted_form_data_from_session() |
|
| 382 | + { |
|
| 383 | + return EE_Registry::instance()->SSN->reset_data( |
|
| 384 | + array(EE_Form_Section_Proper::SUBMITTED_FORM_DATA_SSN_KEY) |
|
| 385 | + ); |
|
| 386 | + } |
|
| 387 | + |
|
| 388 | + |
|
| 389 | + /** |
|
| 390 | + * Populates this form and its subsections with data from the session. |
|
| 391 | + * (Wrapper for EE_Form_Section_Proper::receive_form_submission, so it shows |
|
| 392 | + * validation errors when displaying too) |
|
| 393 | + * Returns true if the form was populated from the session, false otherwise |
|
| 394 | + * |
|
| 395 | + * @return boolean |
|
| 396 | + * @throws InvalidArgumentException |
|
| 397 | + * @throws InvalidInterfaceException |
|
| 398 | + * @throws InvalidDataTypeException |
|
| 399 | + * @throws EE_Error |
|
| 400 | + */ |
|
| 401 | + public function populate_from_session() |
|
| 402 | + { |
|
| 403 | + $form_data_in_session = $this->get_submitted_form_data_from_session(); |
|
| 404 | + if (empty($form_data_in_session)) { |
|
| 405 | + return false; |
|
| 406 | + } |
|
| 407 | + $this->receive_form_submission($form_data_in_session); |
|
| 408 | + add_action('shutdown', array('EE_Form_Section_Proper', 'flush_submitted_form_data_from_session')); |
|
| 409 | + if ($this->form_data_present_in($form_data_in_session)) { |
|
| 410 | + return true; |
|
| 411 | + } |
|
| 412 | + return false; |
|
| 413 | + } |
|
| 414 | + |
|
| 415 | + |
|
| 416 | + /** |
|
| 417 | + * Populates the default data for the form, given an array where keys are |
|
| 418 | + * the input names, and values are their values (preferably normalized to be their |
|
| 419 | + * proper PHP types, not all strings... although that should be ok too). |
|
| 420 | + * Proper subsections are sub-arrays, the key being the subsection's name, and |
|
| 421 | + * the value being an array formatted in teh same way |
|
| 422 | + * |
|
| 423 | + * @param array $default_data |
|
| 424 | + * @throws EE_Error |
|
| 425 | + */ |
|
| 426 | + public function populate_defaults($default_data) |
|
| 427 | + { |
|
| 428 | + foreach ($this->subsections(false) as $subsection_name => $subsection) { |
|
| 429 | + if (isset($default_data[ $subsection_name ])) { |
|
| 430 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 431 | + $subsection->set_default($default_data[ $subsection_name ]); |
|
| 432 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 433 | + $subsection->populate_defaults($default_data[ $subsection_name ]); |
|
| 434 | + } |
|
| 435 | + } |
|
| 436 | + } |
|
| 437 | + } |
|
| 438 | + |
|
| 439 | + |
|
| 440 | + /** |
|
| 441 | + * returns true if subsection exists |
|
| 442 | + * |
|
| 443 | + * @param string $name |
|
| 444 | + * @return boolean |
|
| 445 | + */ |
|
| 446 | + public function subsection_exists($name) |
|
| 447 | + { |
|
| 448 | + return isset($this->_subsections[ $name ]) ? true : false; |
|
| 449 | + } |
|
| 450 | + |
|
| 451 | + |
|
| 452 | + /** |
|
| 453 | + * Gets the subsection specified by its name |
|
| 454 | + * |
|
| 455 | + * @param string $name |
|
| 456 | + * @param boolean $require_construction_to_be_finalized most client code should leave this as TRUE |
|
| 457 | + * so that the inputs will be properly configured. |
|
| 458 | + * However, some client code may be ok |
|
| 459 | + * with construction finalize being called later |
|
| 460 | + * (realizing that the subsections' html names |
|
| 461 | + * might not be set yet, etc.) |
|
| 462 | + * @return EE_Form_Section_Base |
|
| 463 | + * @throws EE_Error |
|
| 464 | + */ |
|
| 465 | + public function get_subsection($name, $require_construction_to_be_finalized = true) |
|
| 466 | + { |
|
| 467 | + if ($require_construction_to_be_finalized) { |
|
| 468 | + $this->ensure_construct_finalized_called(); |
|
| 469 | + } |
|
| 470 | + return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null; |
|
| 471 | + } |
|
| 472 | + |
|
| 473 | + |
|
| 474 | + /** |
|
| 475 | + * Gets all the validatable subsections of this form section |
|
| 476 | + * |
|
| 477 | + * @return EE_Form_Section_Validatable[] |
|
| 478 | + * @throws EE_Error |
|
| 479 | + */ |
|
| 480 | + public function get_validatable_subsections() |
|
| 481 | + { |
|
| 482 | + $validatable_subsections = array(); |
|
| 483 | + foreach ($this->subsections() as $name => $obj) { |
|
| 484 | + if ($obj instanceof EE_Form_Section_Validatable) { |
|
| 485 | + $validatable_subsections[ $name ] = $obj; |
|
| 486 | + } |
|
| 487 | + } |
|
| 488 | + return $validatable_subsections; |
|
| 489 | + } |
|
| 490 | + |
|
| 491 | + |
|
| 492 | + /** |
|
| 493 | + * Gets an input by the given name. If not found, or if its not an EE_FOrm_Input_Base child, |
|
| 494 | + * throw an EE_Error. |
|
| 495 | + * |
|
| 496 | + * @param string $name |
|
| 497 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 498 | + * leave this as TRUE so that the inputs will be properly |
|
| 499 | + * configured. However, some client code may be ok with |
|
| 500 | + * construction finalize being called later |
|
| 501 | + * (realizing that the subsections' html names might not be |
|
| 502 | + * set yet, etc.) |
|
| 503 | + * @return EE_Form_Input_Base |
|
| 504 | + * @throws EE_Error |
|
| 505 | + */ |
|
| 506 | + public function get_input($name, $require_construction_to_be_finalized = true) |
|
| 507 | + { |
|
| 508 | + $subsection = $this->get_subsection( |
|
| 509 | + $name, |
|
| 510 | + $require_construction_to_be_finalized |
|
| 511 | + ); |
|
| 512 | + if (! $subsection instanceof EE_Form_Input_Base) { |
|
| 513 | + throw new EE_Error( |
|
| 514 | + sprintf( |
|
| 515 | + esc_html__( |
|
| 516 | + "Subsection '%s' is not an instanceof EE_Form_Input_Base on form '%s'. It is a '%s'", |
|
| 517 | + 'event_espresso' |
|
| 518 | + ), |
|
| 519 | + $name, |
|
| 520 | + get_class($this), |
|
| 521 | + $subsection ? get_class($subsection) : esc_html__('NULL', 'event_espresso') |
|
| 522 | + ) |
|
| 523 | + ); |
|
| 524 | + } |
|
| 525 | + return $subsection; |
|
| 526 | + } |
|
| 527 | + |
|
| 528 | + |
|
| 529 | + /** |
|
| 530 | + * Like get_input(), gets the proper subsection of the form given the name, |
|
| 531 | + * otherwise throws an EE_Error |
|
| 532 | + * |
|
| 533 | + * @param string $name |
|
| 534 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 535 | + * leave this as TRUE so that the inputs will be properly |
|
| 536 | + * configured. However, some client code may be ok with |
|
| 537 | + * construction finalize being called later |
|
| 538 | + * (realizing that the subsections' html names might not be |
|
| 539 | + * set yet, etc.) |
|
| 540 | + * @return EE_Form_Section_Proper |
|
| 541 | + * @throws EE_Error |
|
| 542 | + */ |
|
| 543 | + public function get_proper_subsection($name, $require_construction_to_be_finalized = true) |
|
| 544 | + { |
|
| 545 | + $subsection = $this->get_subsection( |
|
| 546 | + $name, |
|
| 547 | + $require_construction_to_be_finalized |
|
| 548 | + ); |
|
| 549 | + if (! $subsection instanceof EE_Form_Section_Proper) { |
|
| 550 | + throw new EE_Error( |
|
| 551 | + sprintf( |
|
| 552 | + esc_html__( |
|
| 553 | + "Subsection '%'s is not an instanceof EE_Form_Section_Proper on form '%s'", |
|
| 554 | + 'event_espresso' |
|
| 555 | + ), |
|
| 556 | + $name, |
|
| 557 | + get_class($this) |
|
| 558 | + ) |
|
| 559 | + ); |
|
| 560 | + } |
|
| 561 | + return $subsection; |
|
| 562 | + } |
|
| 563 | + |
|
| 564 | + |
|
| 565 | + /** |
|
| 566 | + * Gets the value of the specified input. Should be called after receive_form_submission() |
|
| 567 | + * or populate_defaults() on the form, where the normalized value on the input is set. |
|
| 568 | + * |
|
| 569 | + * @param string $name |
|
| 570 | + * @return mixed depending on the input's type and its normalization strategy |
|
| 571 | + * @throws EE_Error |
|
| 572 | + */ |
|
| 573 | + public function get_input_value($name) |
|
| 574 | + { |
|
| 575 | + $input = $this->get_input($name); |
|
| 576 | + return $input->normalized_value(); |
|
| 577 | + } |
|
| 578 | + |
|
| 579 | + |
|
| 580 | + /** |
|
| 581 | + * Checks if this form section itself is valid, and then checks its subsections |
|
| 582 | + * |
|
| 583 | + * @throws EE_Error |
|
| 584 | + * @return boolean |
|
| 585 | + */ |
|
| 586 | + public function is_valid() |
|
| 587 | + { |
|
| 588 | + if ($this->is_valid === null) { |
|
| 589 | + if (! $this->has_received_submission()) { |
|
| 590 | + throw new EE_Error( |
|
| 591 | + sprintf( |
|
| 592 | + esc_html__( |
|
| 593 | + 'You cannot check if a form is valid before receiving the form submission using receive_form_submission', |
|
| 594 | + 'event_espresso' |
|
| 595 | + ) |
|
| 596 | + ) |
|
| 597 | + ); |
|
| 598 | + } |
|
| 599 | + if (! parent::is_valid()) { |
|
| 600 | + $this->is_valid = false; |
|
| 601 | + } else { |
|
| 602 | + // ok so no general errors to this entire form section. |
|
| 603 | + // so let's check the subsections, but only set errors if that hasn't been done yet |
|
| 604 | + $this->is_valid = true; |
|
| 605 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 606 | + if (! $subsection->is_valid()) { |
|
| 607 | + $this->is_valid = false; |
|
| 608 | + } |
|
| 609 | + } |
|
| 610 | + } |
|
| 611 | + } |
|
| 612 | + return $this->is_valid; |
|
| 613 | + } |
|
| 614 | + |
|
| 615 | + |
|
| 616 | + /** |
|
| 617 | + * gets the default name of this form section if none is specified |
|
| 618 | + * |
|
| 619 | + * @return void |
|
| 620 | + */ |
|
| 621 | + protected function _set_default_name_if_empty() |
|
| 622 | + { |
|
| 623 | + if (! $this->_name) { |
|
| 624 | + $classname = get_class($this); |
|
| 625 | + $default_name = str_replace('EE_', '', $classname); |
|
| 626 | + $this->_name = $default_name; |
|
| 627 | + } |
|
| 628 | + } |
|
| 629 | + |
|
| 630 | + |
|
| 631 | + /** |
|
| 632 | + * Returns the HTML for the form, except for the form opening and closing tags |
|
| 633 | + * (as the form section doesn't know where you necessarily want to send the information to), |
|
| 634 | + * and except for a submit button. Enqueues JS and CSS; if called early enough we will |
|
| 635 | + * try to enqueue them in the header, otherwise they'll be enqueued in the footer. |
|
| 636 | + * Not doing_it_wrong because theoretically this CAN be used properly, |
|
| 637 | + * provided its used during "wp_enqueue_scripts", or it doesn't need to enqueue |
|
| 638 | + * any CSS. |
|
| 639 | + * |
|
| 640 | + * @throws InvalidArgumentException |
|
| 641 | + * @throws InvalidInterfaceException |
|
| 642 | + * @throws InvalidDataTypeException |
|
| 643 | + * @throws EE_Error |
|
| 644 | + */ |
|
| 645 | + public function get_html_and_js() |
|
| 646 | + { |
|
| 647 | + $this->enqueue_js(); |
|
| 648 | + return $this->get_html(); |
|
| 649 | + } |
|
| 650 | + |
|
| 651 | + |
|
| 652 | + /** |
|
| 653 | + * returns HTML for displaying this form section. recursively calls display_section() on all subsections |
|
| 654 | + * |
|
| 655 | + * @param bool $display_previously_submitted_data |
|
| 656 | + * @return string |
|
| 657 | + * @throws InvalidArgumentException |
|
| 658 | + * @throws InvalidInterfaceException |
|
| 659 | + * @throws InvalidDataTypeException |
|
| 660 | + * @throws EE_Error |
|
| 661 | + * @throws EE_Error |
|
| 662 | + * @throws EE_Error |
|
| 663 | + */ |
|
| 664 | + public function get_html($display_previously_submitted_data = true) |
|
| 665 | + { |
|
| 666 | + $this->ensure_construct_finalized_called(); |
|
| 667 | + if ($display_previously_submitted_data) { |
|
| 668 | + $this->populate_from_session(); |
|
| 669 | + } |
|
| 670 | + return $this->_form_html_filter |
|
| 671 | + ? $this->_form_html_filter->filterHtml($this->_layout_strategy->layout_form(), $this) |
|
| 672 | + : $this->_layout_strategy->layout_form(); |
|
| 673 | + } |
|
| 674 | + |
|
| 675 | + |
|
| 676 | + /** |
|
| 677 | + * enqueues JS and CSS for the form. |
|
| 678 | + * It is preferred to call this before wp_enqueue_scripts so the |
|
| 679 | + * scripts and styles can be put in the header, but if called later |
|
| 680 | + * they will be put in the footer (which is OK for JS, but in HTML4 CSS should |
|
| 681 | + * only be in the header; but in HTML5 its ok in the body. |
|
| 682 | + * See http://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag. |
|
| 683 | + * So if your form enqueues CSS, it's preferred to call this before wp_enqueue_scripts.) |
|
| 684 | + * |
|
| 685 | + * @return void |
|
| 686 | + * @throws EE_Error |
|
| 687 | + */ |
|
| 688 | + public function enqueue_js() |
|
| 689 | + { |
|
| 690 | + $this->_enqueue_and_localize_form_js(); |
|
| 691 | + foreach ($this->subsections() as $subsection) { |
|
| 692 | + $subsection->enqueue_js(); |
|
| 693 | + } |
|
| 694 | + } |
|
| 695 | + |
|
| 696 | + |
|
| 697 | + /** |
|
| 698 | + * adds a filter so that jquery validate gets enqueued in EE_System::wp_enqueue_scripts(). |
|
| 699 | + * This must be done BEFORE wp_enqueue_scripts() gets called, which is on |
|
| 700 | + * the wp_enqueue_scripts hook. |
|
| 701 | + * However, registering the form js and localizing it can happen when we |
|
| 702 | + * actually output the form (which is preferred, seeing how teh form's fields |
|
| 703 | + * could change until it's actually outputted) |
|
| 704 | + * |
|
| 705 | + * @param boolean $init_form_validation_automatically whether or not we want the form validation |
|
| 706 | + * to be triggered automatically or not |
|
| 707 | + * @return void |
|
| 708 | + */ |
|
| 709 | + public static function wp_enqueue_scripts($init_form_validation_automatically = true) |
|
| 710 | + { |
|
| 711 | + wp_register_script( |
|
| 712 | + 'ee_form_section_validation', |
|
| 713 | + EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js', |
|
| 714 | + array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'), |
|
| 715 | + EVENT_ESPRESSO_VERSION, |
|
| 716 | + true |
|
| 717 | + ); |
|
| 718 | + wp_localize_script( |
|
| 719 | + 'ee_form_section_validation', |
|
| 720 | + 'ee_form_section_validation_init', |
|
| 721 | + array('init' => $init_form_validation_automatically ? '1' : '0') |
|
| 722 | + ); |
|
| 723 | + } |
|
| 724 | + |
|
| 725 | + |
|
| 726 | + /** |
|
| 727 | + * gets the variables used by form_section_validation.js. |
|
| 728 | + * This needs to be called AFTER we've called $this->_enqueue_jquery_validate_script, |
|
| 729 | + * but before the wordpress hook wp_loaded |
|
| 730 | + * |
|
| 731 | + * @throws EE_Error |
|
| 732 | + */ |
|
| 733 | + public function _enqueue_and_localize_form_js() |
|
| 734 | + { |
|
| 735 | + $this->ensure_construct_finalized_called(); |
|
| 736 | + // actually, we don't want to localize just yet. There may be other forms on the page. |
|
| 737 | + // so we need to add our form section data to a static variable accessible by all form sections |
|
| 738 | + // and localize it just before the footer |
|
| 739 | + $this->localize_validation_rules(); |
|
| 740 | + add_action('wp_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms'), 2); |
|
| 741 | + add_action('admin_footer', array('EE_Form_Section_Proper', 'localize_script_for_all_forms')); |
|
| 742 | + } |
|
| 743 | + |
|
| 744 | + |
|
| 745 | + /** |
|
| 746 | + * add our form section data to a static variable accessible by all form sections |
|
| 747 | + * |
|
| 748 | + * @param bool $return_for_subsection |
|
| 749 | + * @return void |
|
| 750 | + * @throws EE_Error |
|
| 751 | + */ |
|
| 752 | + public function localize_validation_rules($return_for_subsection = false) |
|
| 753 | + { |
|
| 754 | + // we only want to localize vars ONCE for the entire form, |
|
| 755 | + // so if the form section doesn't have a parent, then it must be the top dog |
|
| 756 | + if ($return_for_subsection || ! $this->parent_section()) { |
|
| 757 | + EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array( |
|
| 758 | + 'form_section_id' => $this->html_id(true), |
|
| 759 | + 'validation_rules' => $this->get_jquery_validation_rules(), |
|
| 760 | + 'other_data' => $this->get_other_js_data(), |
|
| 761 | + 'errors' => $this->subsection_validation_errors_by_html_name(), |
|
| 762 | + ); |
|
| 763 | + EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 764 | + } |
|
| 765 | + } |
|
| 766 | + |
|
| 767 | + |
|
| 768 | + /** |
|
| 769 | + * Gets an array of extra data that will be useful for client-side javascript. |
|
| 770 | + * This is primarily data added by inputs and forms in addition to any |
|
| 771 | + * scripts they might enqueue |
|
| 772 | + * |
|
| 773 | + * @param array $form_other_js_data |
|
| 774 | + * @return array |
|
| 775 | + * @throws EE_Error |
|
| 776 | + */ |
|
| 777 | + public function get_other_js_data($form_other_js_data = array()) |
|
| 778 | + { |
|
| 779 | + foreach ($this->subsections() as $subsection) { |
|
| 780 | + $form_other_js_data = $subsection->get_other_js_data($form_other_js_data); |
|
| 781 | + } |
|
| 782 | + return $form_other_js_data; |
|
| 783 | + } |
|
| 784 | + |
|
| 785 | + |
|
| 786 | + /** |
|
| 787 | + * Gets a flat array of inputs for this form section and its subsections. |
|
| 788 | + * Keys are their form names, and values are the inputs themselves |
|
| 789 | + * |
|
| 790 | + * @return EE_Form_Input_Base |
|
| 791 | + * @throws EE_Error |
|
| 792 | + */ |
|
| 793 | + public function inputs_in_subsections() |
|
| 794 | + { |
|
| 795 | + $inputs = array(); |
|
| 796 | + foreach ($this->subsections() as $subsection) { |
|
| 797 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 798 | + $inputs[ $subsection->html_name() ] = $subsection; |
|
| 799 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 800 | + $inputs += $subsection->inputs_in_subsections(); |
|
| 801 | + } |
|
| 802 | + } |
|
| 803 | + return $inputs; |
|
| 804 | + } |
|
| 805 | + |
|
| 806 | + |
|
| 807 | + /** |
|
| 808 | + * Gets a flat array of all the validation errors. |
|
| 809 | + * Keys are html names (because those should be unique) |
|
| 810 | + * and values are a string of all their validation errors |
|
| 811 | + * |
|
| 812 | + * @return string[] |
|
| 813 | + * @throws EE_Error |
|
| 814 | + */ |
|
| 815 | + public function subsection_validation_errors_by_html_name() |
|
| 816 | + { |
|
| 817 | + $inputs = $this->inputs(); |
|
| 818 | + $errors = array(); |
|
| 819 | + foreach ($inputs as $form_input) { |
|
| 820 | + if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) { |
|
| 821 | + $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string(); |
|
| 822 | + } |
|
| 823 | + } |
|
| 824 | + return $errors; |
|
| 825 | + } |
|
| 826 | + |
|
| 827 | + |
|
| 828 | + /** |
|
| 829 | + * passes all the form data required by the JS to the JS, and enqueues the few required JS files. |
|
| 830 | + * Should be setup by each form during the _enqueues_and_localize_form_js |
|
| 831 | + * |
|
| 832 | + * @throws InvalidArgumentException |
|
| 833 | + * @throws InvalidInterfaceException |
|
| 834 | + * @throws InvalidDataTypeException |
|
| 835 | + */ |
|
| 836 | + public static function localize_script_for_all_forms() |
|
| 837 | + { |
|
| 838 | + // allow inputs and stuff to hook in their JS and stuff here |
|
| 839 | + do_action('AHEE__EE_Form_Section_Proper__localize_script_for_all_forms__begin'); |
|
| 840 | + EE_Form_Section_Proper::$_js_localization['localized_error_messages'] = EE_Form_Section_Proper::_get_localized_error_messages(); |
|
| 841 | + $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level) |
|
| 842 | + ? EE_Registry::instance()->CFG->registration->email_validation_level |
|
| 843 | + : 'wp_default'; |
|
| 844 | + EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 845 | + wp_enqueue_script('ee_form_section_validation'); |
|
| 846 | + wp_localize_script( |
|
| 847 | + 'ee_form_section_validation', |
|
| 848 | + 'ee_form_section_vars', |
|
| 849 | + EE_Form_Section_Proper::$_js_localization |
|
| 850 | + ); |
|
| 851 | + } |
|
| 852 | + |
|
| 853 | + |
|
| 854 | + /** |
|
| 855 | + * ensure_scripts_localized |
|
| 856 | + * |
|
| 857 | + * @throws EE_Error |
|
| 858 | + */ |
|
| 859 | + public function ensure_scripts_localized() |
|
| 860 | + { |
|
| 861 | + if (! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 862 | + $this->_enqueue_and_localize_form_js(); |
|
| 863 | + } |
|
| 864 | + } |
|
| 865 | + |
|
| 866 | + |
|
| 867 | + /** |
|
| 868 | + * Gets the hard-coded validation error messages to be used in the JS. The convention |
|
| 869 | + * is that the key here should be the same as the custom validation rule put in the JS file |
|
| 870 | + * |
|
| 871 | + * @return array keys are custom validation rules, and values are internationalized strings |
|
| 872 | + */ |
|
| 873 | + private static function _get_localized_error_messages() |
|
| 874 | + { |
|
| 875 | + return array( |
|
| 876 | + 'validUrl' => esc_html__('This is not a valid absolute URL. Eg, http://domain.com/monkey.jpg', 'event_espresso'), |
|
| 877 | + 'regex' => esc_html__('Please check your input', 'event_espresso'), |
|
| 878 | + ); |
|
| 879 | + } |
|
| 880 | + |
|
| 881 | + |
|
| 882 | + /** |
|
| 883 | + * @return array |
|
| 884 | + */ |
|
| 885 | + public static function js_localization() |
|
| 886 | + { |
|
| 887 | + return self::$_js_localization; |
|
| 888 | + } |
|
| 889 | + |
|
| 890 | + |
|
| 891 | + /** |
|
| 892 | + * @return void |
|
| 893 | + */ |
|
| 894 | + public static function reset_js_localization() |
|
| 895 | + { |
|
| 896 | + self::$_js_localization = array(); |
|
| 897 | + } |
|
| 898 | + |
|
| 899 | + |
|
| 900 | + /** |
|
| 901 | + * Gets the JS to put inside the jquery validation rules for subsection of this form section. |
|
| 902 | + * See parent function for more... |
|
| 903 | + * |
|
| 904 | + * @return array |
|
| 905 | + * @throws EE_Error |
|
| 906 | + */ |
|
| 907 | + public function get_jquery_validation_rules() |
|
| 908 | + { |
|
| 909 | + $jquery_validation_rules = array(); |
|
| 910 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 911 | + $jquery_validation_rules = array_merge( |
|
| 912 | + $jquery_validation_rules, |
|
| 913 | + $subsection->get_jquery_validation_rules() |
|
| 914 | + ); |
|
| 915 | + } |
|
| 916 | + return $jquery_validation_rules; |
|
| 917 | + } |
|
| 918 | + |
|
| 919 | + |
|
| 920 | + /** |
|
| 921 | + * Sanitizes all the data and sets the sanitized value of each field |
|
| 922 | + * |
|
| 923 | + * @param array $req_data like $_POST |
|
| 924 | + * @return void |
|
| 925 | + * @throws EE_Error |
|
| 926 | + */ |
|
| 927 | + protected function _normalize($req_data) |
|
| 928 | + { |
|
| 929 | + $this->_received_submission = true; |
|
| 930 | + $this->_validation_errors = array(); |
|
| 931 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 932 | + try { |
|
| 933 | + $subsection->_normalize($req_data); |
|
| 934 | + } catch (EE_Validation_Error $e) { |
|
| 935 | + $subsection->add_validation_error($e); |
|
| 936 | + } |
|
| 937 | + } |
|
| 938 | + } |
|
| 939 | + |
|
| 940 | + |
|
| 941 | + /** |
|
| 942 | + * Performs validation on this form section and its subsections. |
|
| 943 | + * For each subsection, |
|
| 944 | + * calls _validate_{subsection_name} on THIS form (if the function exists) |
|
| 945 | + * and passes it the subsection, then calls _validate on that subsection. |
|
| 946 | + * If you need to perform validation on the form as a whole (considering multiple) |
|
| 947 | + * you would be best to override this _validate method, |
|
| 948 | + * calling parent::_validate() first. |
|
| 949 | + * |
|
| 950 | + * @throws EE_Error |
|
| 951 | + */ |
|
| 952 | + protected function _validate() |
|
| 953 | + { |
|
| 954 | + // reset the cache of whether this form is valid or not- we're re-validating it now |
|
| 955 | + $this->is_valid = null; |
|
| 956 | + foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
| 957 | + if (method_exists($this, '_validate_' . $subsection_name)) { |
|
| 958 | + call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection)); |
|
| 959 | + } |
|
| 960 | + $subsection->_validate(); |
|
| 961 | + } |
|
| 962 | + } |
|
| 963 | + |
|
| 964 | + |
|
| 965 | + /** |
|
| 966 | + * Gets all the validated inputs for the form section |
|
| 967 | + * |
|
| 968 | + * @return array |
|
| 969 | + * @throws EE_Error |
|
| 970 | + */ |
|
| 971 | + public function valid_data() |
|
| 972 | + { |
|
| 973 | + $inputs = array(); |
|
| 974 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 975 | + if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 976 | + $inputs[ $subsection_name ] = $subsection->valid_data(); |
|
| 977 | + } elseif ($subsection instanceof EE_Form_Input_Base) { |
|
| 978 | + $inputs[ $subsection_name ] = $subsection->normalized_value(); |
|
| 979 | + } |
|
| 980 | + } |
|
| 981 | + return $inputs; |
|
| 982 | + } |
|
| 983 | + |
|
| 984 | + |
|
| 985 | + /** |
|
| 986 | + * Gets all the inputs on this form section |
|
| 987 | + * |
|
| 988 | + * @return EE_Form_Input_Base[] |
|
| 989 | + * @throws EE_Error |
|
| 990 | + */ |
|
| 991 | + public function inputs() |
|
| 992 | + { |
|
| 993 | + $inputs = array(); |
|
| 994 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 995 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 996 | + $inputs[ $subsection_name ] = $subsection; |
|
| 997 | + } |
|
| 998 | + } |
|
| 999 | + return $inputs; |
|
| 1000 | + } |
|
| 1001 | + |
|
| 1002 | + |
|
| 1003 | + /** |
|
| 1004 | + * Gets all the subsections which are a proper form |
|
| 1005 | + * |
|
| 1006 | + * @return EE_Form_Section_Proper[] |
|
| 1007 | + * @throws EE_Error |
|
| 1008 | + */ |
|
| 1009 | + public function subforms() |
|
| 1010 | + { |
|
| 1011 | + $form_sections = array(); |
|
| 1012 | + foreach ($this->subsections() as $name => $obj) { |
|
| 1013 | + if ($obj instanceof EE_Form_Section_Proper) { |
|
| 1014 | + $form_sections[ $name ] = $obj; |
|
| 1015 | + } |
|
| 1016 | + } |
|
| 1017 | + return $form_sections; |
|
| 1018 | + } |
|
| 1019 | + |
|
| 1020 | + |
|
| 1021 | + /** |
|
| 1022 | + * Gets all the subsections (inputs, proper subsections, or html-only sections). |
|
| 1023 | + * Consider using inputs() or subforms() |
|
| 1024 | + * if you only want form inputs or proper form sections. |
|
| 1025 | + * |
|
| 1026 | + * @param boolean $require_construction_to_be_finalized most client code should |
|
| 1027 | + * leave this as TRUE so that the inputs will be properly |
|
| 1028 | + * configured. However, some client code may be ok with |
|
| 1029 | + * construction finalize being called later |
|
| 1030 | + * (realizing that the subsections' html names might not be |
|
| 1031 | + * set yet, etc.) |
|
| 1032 | + * @return EE_Form_Section_Proper[] |
|
| 1033 | + * @throws EE_Error |
|
| 1034 | + */ |
|
| 1035 | + public function subsections($require_construction_to_be_finalized = true) |
|
| 1036 | + { |
|
| 1037 | + if ($require_construction_to_be_finalized) { |
|
| 1038 | + $this->ensure_construct_finalized_called(); |
|
| 1039 | + } |
|
| 1040 | + return $this->_subsections; |
|
| 1041 | + } |
|
| 1042 | + |
|
| 1043 | + |
|
| 1044 | + /** |
|
| 1045 | + * Returns whether this form has any subforms or inputs |
|
| 1046 | + * @return bool |
|
| 1047 | + */ |
|
| 1048 | + public function hasSubsections() |
|
| 1049 | + { |
|
| 1050 | + return ! empty($this->_subsections); |
|
| 1051 | + } |
|
| 1052 | + |
|
| 1053 | + |
|
| 1054 | + /** |
|
| 1055 | + * Returns a simple array where keys are input names, and values are their normalized |
|
| 1056 | + * values. (Similar to calling get_input_value on inputs) |
|
| 1057 | + * |
|
| 1058 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1059 | + * or just this forms' direct children inputs |
|
| 1060 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1061 | + * or allow multidimensional array |
|
| 1062 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1063 | + * with array keys being input names |
|
| 1064 | + * (regardless of whether they are from a subsection or not), |
|
| 1065 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1066 | + * where keys are always subsection names and values are either |
|
| 1067 | + * the input's normalized value, or an array like the top-level array |
|
| 1068 | + * @throws EE_Error |
|
| 1069 | + */ |
|
| 1070 | + public function input_values($include_subform_inputs = false, $flatten = false) |
|
| 1071 | + { |
|
| 1072 | + return $this->_input_values(false, $include_subform_inputs, $flatten); |
|
| 1073 | + } |
|
| 1074 | + |
|
| 1075 | + |
|
| 1076 | + /** |
|
| 1077 | + * Similar to EE_Form_Section_Proper::input_values(), except this returns the 'display_value' |
|
| 1078 | + * of each input. On some inputs (especially radio boxes or checkboxes), the value stored |
|
| 1079 | + * is not necessarily the value we want to display to users. This creates an array |
|
| 1080 | + * where keys are the input names, and values are their display values |
|
| 1081 | + * |
|
| 1082 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1083 | + * or just this forms' direct children inputs |
|
| 1084 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1085 | + * or allow multidimensional array |
|
| 1086 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1087 | + * with array keys being input names |
|
| 1088 | + * (regardless of whether they are from a subsection or not), |
|
| 1089 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1090 | + * where keys are always subsection names and values are either |
|
| 1091 | + * the input's normalized value, or an array like the top-level array |
|
| 1092 | + * @throws EE_Error |
|
| 1093 | + */ |
|
| 1094 | + public function input_pretty_values($include_subform_inputs = false, $flatten = false) |
|
| 1095 | + { |
|
| 1096 | + return $this->_input_values(true, $include_subform_inputs, $flatten); |
|
| 1097 | + } |
|
| 1098 | + |
|
| 1099 | + |
|
| 1100 | + /** |
|
| 1101 | + * Gets the input values from the form |
|
| 1102 | + * |
|
| 1103 | + * @param boolean $pretty Whether to retrieve the pretty value, |
|
| 1104 | + * or just the normalized value |
|
| 1105 | + * @param boolean $include_subform_inputs Whether to include inputs from subforms, |
|
| 1106 | + * or just this forms' direct children inputs |
|
| 1107 | + * @param boolean $flatten Whether to force the results into 1-dimensional array, |
|
| 1108 | + * or allow multidimensional array |
|
| 1109 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array with array keys being |
|
| 1110 | + * input names (regardless of whether they are from a subsection or not), |
|
| 1111 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1112 | + * where keys are always subsection names and values are either |
|
| 1113 | + * the input's normalized value, or an array like the top-level array |
|
| 1114 | + * @throws EE_Error |
|
| 1115 | + */ |
|
| 1116 | + public function _input_values($pretty = false, $include_subform_inputs = false, $flatten = false) |
|
| 1117 | + { |
|
| 1118 | + $input_values = array(); |
|
| 1119 | + foreach ($this->subsections() as $subsection_name => $subsection) { |
|
| 1120 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1121 | + $input_values[ $subsection_name ] = $pretty |
|
| 1122 | + ? $subsection->pretty_value() |
|
| 1123 | + : $subsection->normalized_value(); |
|
| 1124 | + } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) { |
|
| 1125 | + $subform_input_values = $subsection->_input_values( |
|
| 1126 | + $pretty, |
|
| 1127 | + $include_subform_inputs, |
|
| 1128 | + $flatten |
|
| 1129 | + ); |
|
| 1130 | + if ($flatten) { |
|
| 1131 | + $input_values = array_merge($input_values, $subform_input_values); |
|
| 1132 | + } else { |
|
| 1133 | + $input_values[ $subsection_name ] = $subform_input_values; |
|
| 1134 | + } |
|
| 1135 | + } |
|
| 1136 | + } |
|
| 1137 | + return $input_values; |
|
| 1138 | + } |
|
| 1139 | + |
|
| 1140 | + |
|
| 1141 | + /** |
|
| 1142 | + * Gets the originally submitted input values from the form |
|
| 1143 | + * |
|
| 1144 | + * @param boolean $include_subforms Whether to include inputs from subforms, |
|
| 1145 | + * or just this forms' direct children inputs |
|
| 1146 | + * @return array if $flatten is TRUE it will always be a 1-dimensional array |
|
| 1147 | + * with array keys being input names |
|
| 1148 | + * (regardless of whether they are from a subsection or not), |
|
| 1149 | + * and if $flatten is FALSE it can be a multidimensional array |
|
| 1150 | + * where keys are always subsection names and values are either |
|
| 1151 | + * the input's normalized value, or an array like the top-level array |
|
| 1152 | + * @throws EE_Error |
|
| 1153 | + */ |
|
| 1154 | + public function submitted_values($include_subforms = false) |
|
| 1155 | + { |
|
| 1156 | + $submitted_values = array(); |
|
| 1157 | + foreach ($this->subsections() as $subsection) { |
|
| 1158 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1159 | + // is this input part of an array of inputs? |
|
| 1160 | + if (strpos($subsection->html_name(), '[') !== false) { |
|
| 1161 | + $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1162 | + explode( |
|
| 1163 | + '[', |
|
| 1164 | + str_replace(']', '', $subsection->html_name()) |
|
| 1165 | + ), |
|
| 1166 | + $subsection->raw_value() |
|
| 1167 | + ); |
|
| 1168 | + $submitted_values = array_replace_recursive($submitted_values, $full_input_name); |
|
| 1169 | + } else { |
|
| 1170 | + $submitted_values[ $subsection->html_name() ] = $subsection->raw_value(); |
|
| 1171 | + } |
|
| 1172 | + } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) { |
|
| 1173 | + $subform_input_values = $subsection->submitted_values($include_subforms); |
|
| 1174 | + $submitted_values = array_replace_recursive($submitted_values, $subform_input_values); |
|
| 1175 | + } |
|
| 1176 | + } |
|
| 1177 | + return $submitted_values; |
|
| 1178 | + } |
|
| 1179 | + |
|
| 1180 | + |
|
| 1181 | + /** |
|
| 1182 | + * Indicates whether or not this form has received a submission yet |
|
| 1183 | + * (ie, had receive_form_submission called on it yet) |
|
| 1184 | + * |
|
| 1185 | + * @return boolean |
|
| 1186 | + * @throws EE_Error |
|
| 1187 | + */ |
|
| 1188 | + public function has_received_submission() |
|
| 1189 | + { |
|
| 1190 | + $this->ensure_construct_finalized_called(); |
|
| 1191 | + return $this->_received_submission; |
|
| 1192 | + } |
|
| 1193 | + |
|
| 1194 | + |
|
| 1195 | + /** |
|
| 1196 | + * Equivalent to passing 'exclude' in the constructor's options array. |
|
| 1197 | + * Removes the listed inputs from the form |
|
| 1198 | + * |
|
| 1199 | + * @param array $inputs_to_exclude values are the input names |
|
| 1200 | + * @return void |
|
| 1201 | + */ |
|
| 1202 | + public function exclude(array $inputs_to_exclude = array()) |
|
| 1203 | + { |
|
| 1204 | + foreach ($inputs_to_exclude as $input_to_exclude_name) { |
|
| 1205 | + unset($this->_subsections[ $input_to_exclude_name ]); |
|
| 1206 | + } |
|
| 1207 | + } |
|
| 1208 | + |
|
| 1209 | + |
|
| 1210 | + /** |
|
| 1211 | + * Changes these inputs' display strategy to be EE_Hidden_Display_Strategy. |
|
| 1212 | + * @param array $inputs_to_hide |
|
| 1213 | + * @throws EE_Error |
|
| 1214 | + */ |
|
| 1215 | + public function hide(array $inputs_to_hide = array()) |
|
| 1216 | + { |
|
| 1217 | + foreach ($inputs_to_hide as $input_to_hide) { |
|
| 1218 | + $input = $this->get_input($input_to_hide); |
|
| 1219 | + $input->set_display_strategy(new EE_Hidden_Display_Strategy()); |
|
| 1220 | + } |
|
| 1221 | + } |
|
| 1222 | + |
|
| 1223 | + |
|
| 1224 | + /** |
|
| 1225 | + * add_subsections |
|
| 1226 | + * Adds the listed subsections to the form section. |
|
| 1227 | + * If $subsection_name_to_target is provided, |
|
| 1228 | + * then new subsections are added before or after that subsection, |
|
| 1229 | + * otherwise to the start or end of the entire subsections array. |
|
| 1230 | + * |
|
| 1231 | + * @param EE_Form_Section_Base[] $new_subsections array of new form subsections |
|
| 1232 | + * where keys are their names |
|
| 1233 | + * @param string $subsection_name_to_target an existing for section that $new_subsections |
|
| 1234 | + * should be added before or after |
|
| 1235 | + * IF $subsection_name_to_target is null, |
|
| 1236 | + * then $new_subsections will be added to |
|
| 1237 | + * the beginning or end of the entire subsections array |
|
| 1238 | + * @param boolean $add_before whether to add $new_subsections, before or after |
|
| 1239 | + * $subsection_name_to_target, |
|
| 1240 | + * or if $subsection_name_to_target is null, |
|
| 1241 | + * before or after entire subsections array |
|
| 1242 | + * @return void |
|
| 1243 | + * @throws EE_Error |
|
| 1244 | + */ |
|
| 1245 | + public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true) |
|
| 1246 | + { |
|
| 1247 | + foreach ($new_subsections as $subsection_name => $subsection) { |
|
| 1248 | + if (! $subsection instanceof EE_Form_Section_Base) { |
|
| 1249 | + EE_Error::add_error( |
|
| 1250 | + sprintf( |
|
| 1251 | + esc_html__( |
|
| 1252 | + "Trying to add a %s as a subsection (it was named '%s') to the form section '%s'. It was removed.", |
|
| 1253 | + 'event_espresso' |
|
| 1254 | + ), |
|
| 1255 | + get_class($subsection), |
|
| 1256 | + $subsection_name, |
|
| 1257 | + $this->name() |
|
| 1258 | + ) |
|
| 1259 | + ); |
|
| 1260 | + unset($new_subsections[ $subsection_name ]); |
|
| 1261 | + } |
|
| 1262 | + } |
|
| 1263 | + $this->_subsections = EEH_Array::insert_into_array( |
|
| 1264 | + $this->_subsections, |
|
| 1265 | + $new_subsections, |
|
| 1266 | + $subsection_name_to_target, |
|
| 1267 | + $add_before |
|
| 1268 | + ); |
|
| 1269 | + if ($this->_construction_finalized) { |
|
| 1270 | + foreach ($this->_subsections as $name => $subsection) { |
|
| 1271 | + $subsection->_construct_finalize($this, $name); |
|
| 1272 | + } |
|
| 1273 | + } |
|
| 1274 | + } |
|
| 1275 | + |
|
| 1276 | + |
|
| 1277 | + /** |
|
| 1278 | + * @param string $subsection_name |
|
| 1279 | + * @param bool $recursive |
|
| 1280 | + * @return bool |
|
| 1281 | + */ |
|
| 1282 | + public function has_subsection($subsection_name, $recursive = false) |
|
| 1283 | + { |
|
| 1284 | + foreach ($this->_subsections as $name => $subsection) { |
|
| 1285 | + if ($name === $subsection_name |
|
| 1286 | + || ( |
|
| 1287 | + $recursive |
|
| 1288 | + && $subsection instanceof EE_Form_Section_Proper |
|
| 1289 | + && $subsection->has_subsection($subsection_name, $recursive) |
|
| 1290 | + ) |
|
| 1291 | + ) { |
|
| 1292 | + return true; |
|
| 1293 | + } |
|
| 1294 | + } |
|
| 1295 | + return false; |
|
| 1296 | + } |
|
| 1297 | + |
|
| 1298 | + |
|
| 1299 | + |
|
| 1300 | + /** |
|
| 1301 | + * Just gets all validatable subsections to clean their sensitive data |
|
| 1302 | + * |
|
| 1303 | + * @throws EE_Error |
|
| 1304 | + */ |
|
| 1305 | + public function clean_sensitive_data() |
|
| 1306 | + { |
|
| 1307 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1308 | + $subsection->clean_sensitive_data(); |
|
| 1309 | + } |
|
| 1310 | + } |
|
| 1311 | + |
|
| 1312 | + |
|
| 1313 | + /** |
|
| 1314 | + * Sets the submission error message (aka validation error message for this form section and all sub-sections) |
|
| 1315 | + * @param string $form_submission_error_message |
|
| 1316 | + * @param EE_Form_Section_Validatable $form_section unused |
|
| 1317 | + * @throws EE_Error |
|
| 1318 | + */ |
|
| 1319 | + public function set_submission_error_message( |
|
| 1320 | + $form_submission_error_message = '' |
|
| 1321 | + ) { |
|
| 1322 | + $this->_form_submission_error_message = ! empty($form_submission_error_message) |
|
| 1323 | + ? $form_submission_error_message |
|
| 1324 | + : $this->getAllValidationErrorsString(); |
|
| 1325 | + } |
|
| 1326 | + |
|
| 1327 | + |
|
| 1328 | + /** |
|
| 1329 | + * Returns the cached error message. A default value is set for this during _validate(), |
|
| 1330 | + * (called during receive_form_submission) but it can be explicitly set using |
|
| 1331 | + * set_submission_error_message |
|
| 1332 | + * |
|
| 1333 | + * @return string |
|
| 1334 | + */ |
|
| 1335 | + public function submission_error_message() |
|
| 1336 | + { |
|
| 1337 | + return $this->_form_submission_error_message; |
|
| 1338 | + } |
|
| 1339 | + |
|
| 1340 | + |
|
| 1341 | + /** |
|
| 1342 | + * Sets a message to display if the data submitted to the form was valid. |
|
| 1343 | + * @param string $form_submission_success_message |
|
| 1344 | + */ |
|
| 1345 | + public function set_submission_success_message($form_submission_success_message = '') |
|
| 1346 | + { |
|
| 1347 | + $this->_form_submission_success_message = ! empty($form_submission_success_message) |
|
| 1348 | + ? $form_submission_success_message |
|
| 1349 | + : esc_html__('Form submitted successfully', 'event_espresso'); |
|
| 1350 | + } |
|
| 1351 | + |
|
| 1352 | + |
|
| 1353 | + /** |
|
| 1354 | + * Gets a message appropriate for display when the form is correctly submitted |
|
| 1355 | + * @return string |
|
| 1356 | + */ |
|
| 1357 | + public function submission_success_message() |
|
| 1358 | + { |
|
| 1359 | + return $this->_form_submission_success_message; |
|
| 1360 | + } |
|
| 1361 | + |
|
| 1362 | + |
|
| 1363 | + /** |
|
| 1364 | + * Returns the prefix that should be used on child of this form section for |
|
| 1365 | + * their html names. If this form section itself has a parent, prepends ITS |
|
| 1366 | + * prefix onto this form section's prefix. Used primarily by |
|
| 1367 | + * EE_Form_Input_Base::_set_default_html_name_if_empty |
|
| 1368 | + * |
|
| 1369 | + * @return string |
|
| 1370 | + * @throws EE_Error |
|
| 1371 | + */ |
|
| 1372 | + public function html_name_prefix() |
|
| 1373 | + { |
|
| 1374 | + if ($this->parent_section() instanceof EE_Form_Section_Proper) { |
|
| 1375 | + return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']'; |
|
| 1376 | + } |
|
| 1377 | + return $this->name(); |
|
| 1378 | + } |
|
| 1379 | + |
|
| 1380 | + |
|
| 1381 | + /** |
|
| 1382 | + * Gets the name, but first checks _construct_finalize has been called. If not, |
|
| 1383 | + * calls it (assumes there is no parent and that we want the name to be whatever |
|
| 1384 | + * was set, which is probably nothing, or the classname) |
|
| 1385 | + * |
|
| 1386 | + * @return string |
|
| 1387 | + * @throws EE_Error |
|
| 1388 | + */ |
|
| 1389 | + public function name() |
|
| 1390 | + { |
|
| 1391 | + $this->ensure_construct_finalized_called(); |
|
| 1392 | + return parent::name(); |
|
| 1393 | + } |
|
| 1394 | + |
|
| 1395 | + |
|
| 1396 | + /** |
|
| 1397 | + * @return EE_Form_Section_Proper |
|
| 1398 | + * @throws EE_Error |
|
| 1399 | + */ |
|
| 1400 | + public function parent_section() |
|
| 1401 | + { |
|
| 1402 | + $this->ensure_construct_finalized_called(); |
|
| 1403 | + return parent::parent_section(); |
|
| 1404 | + } |
|
| 1405 | + |
|
| 1406 | + |
|
| 1407 | + /** |
|
| 1408 | + * make sure construction finalized was called, otherwise children might not be ready |
|
| 1409 | + * |
|
| 1410 | + * @return void |
|
| 1411 | + * @throws EE_Error |
|
| 1412 | + */ |
|
| 1413 | + public function ensure_construct_finalized_called() |
|
| 1414 | + { |
|
| 1415 | + if (! $this->_construction_finalized) { |
|
| 1416 | + $this->_construct_finalize($this->_parent_section, $this->_name); |
|
| 1417 | + } |
|
| 1418 | + } |
|
| 1419 | + |
|
| 1420 | + |
|
| 1421 | + /** |
|
| 1422 | + * Checks if any of this form section's inputs, or any of its children's inputs, |
|
| 1423 | + * are in teh form data. If any are found, returns true. Else false |
|
| 1424 | + * |
|
| 1425 | + * @param array $req_data |
|
| 1426 | + * @return boolean |
|
| 1427 | + * @throws EE_Error |
|
| 1428 | + */ |
|
| 1429 | + public function form_data_present_in($req_data = null) |
|
| 1430 | + { |
|
| 1431 | + $req_data = $this->getCachedRequest($req_data); |
|
| 1432 | + foreach ($this->subsections() as $subsection) { |
|
| 1433 | + if ($subsection instanceof EE_Form_Input_Base) { |
|
| 1434 | + if ($subsection->form_data_present_in($req_data)) { |
|
| 1435 | + return true; |
|
| 1436 | + } |
|
| 1437 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1438 | + if ($subsection->form_data_present_in($req_data)) { |
|
| 1439 | + return true; |
|
| 1440 | + } |
|
| 1441 | + } |
|
| 1442 | + } |
|
| 1443 | + return false; |
|
| 1444 | + } |
|
| 1445 | + |
|
| 1446 | + |
|
| 1447 | + /** |
|
| 1448 | + * Gets validation errors for this form section and subsections |
|
| 1449 | + * Similar to EE_Form_Section_Validatable::get_validation_errors() except this |
|
| 1450 | + * gets the validation errors for ALL subsection |
|
| 1451 | + * |
|
| 1452 | + * @return EE_Validation_Error[] |
|
| 1453 | + * @throws EE_Error |
|
| 1454 | + */ |
|
| 1455 | + public function get_validation_errors_accumulated() |
|
| 1456 | + { |
|
| 1457 | + $validation_errors = $this->get_validation_errors(); |
|
| 1458 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
| 1459 | + if ($subsection instanceof EE_Form_Section_Proper) { |
|
| 1460 | + $validation_errors_on_this_subsection = $subsection->get_validation_errors_accumulated(); |
|
| 1461 | + } else { |
|
| 1462 | + $validation_errors_on_this_subsection = $subsection->get_validation_errors(); |
|
| 1463 | + } |
|
| 1464 | + if ($validation_errors_on_this_subsection) { |
|
| 1465 | + $validation_errors = array_merge($validation_errors, $validation_errors_on_this_subsection); |
|
| 1466 | + } |
|
| 1467 | + } |
|
| 1468 | + return $validation_errors; |
|
| 1469 | + } |
|
| 1470 | + |
|
| 1471 | + /** |
|
| 1472 | + * Fetch validation errors from children and grandchildren and puts them in a single string. |
|
| 1473 | + * This traverses the form section tree to generate this, but you probably want to instead use |
|
| 1474 | + * get_form_submission_error_message() which is usually this message cached (or a custom validation error message) |
|
| 1475 | + * |
|
| 1476 | + * @return string |
|
| 1477 | + * @since 4.9.59.p |
|
| 1478 | + */ |
|
| 1479 | + protected function getAllValidationErrorsString() |
|
| 1480 | + { |
|
| 1481 | + $submission_error_messages = array(); |
|
| 1482 | + // bad, bad, bad registrant |
|
| 1483 | + foreach ($this->get_validation_errors_accumulated() as $validation_error) { |
|
| 1484 | + if ($validation_error instanceof EE_Validation_Error) { |
|
| 1485 | + $form_section = $validation_error->get_form_section(); |
|
| 1486 | + if ($form_section instanceof EE_Form_Input_Base) { |
|
| 1487 | + $label = $validation_error->get_form_section()->html_label_text(); |
|
| 1488 | + } elseif ($form_section instanceof EE_Form_Section_Validatable) { |
|
| 1489 | + $label = $validation_error->get_form_section()->name(); |
|
| 1490 | + } else { |
|
| 1491 | + $label = esc_html__('Unknown', 'event_espresso'); |
|
| 1492 | + } |
|
| 1493 | + $submission_error_messages[] = sprintf( |
|
| 1494 | + __('%s : %s', 'event_espresso'), |
|
| 1495 | + $label, |
|
| 1496 | + $validation_error->getMessage() |
|
| 1497 | + ); |
|
| 1498 | + } |
|
| 1499 | + } |
|
| 1500 | + return implode('<br', $submission_error_messages); |
|
| 1501 | + } |
|
| 1502 | + |
|
| 1503 | + |
|
| 1504 | + /** |
|
| 1505 | + * This isn't just the name of an input, it's a path pointing to an input. The |
|
| 1506 | + * path is similar to a folder path: slash (/) means to descend into a subsection, |
|
| 1507 | + * dot-dot-slash (../) means to ascend into the parent section. |
|
| 1508 | + * After a series of slashes and dot-dot-slashes, there should be the name of an input, |
|
| 1509 | + * which will be returned. |
|
| 1510 | + * Eg, if you want the related input to be conditional on a sibling input name 'foobar' |
|
| 1511 | + * just use 'foobar'. If you want it to be conditional on an aunt/uncle input name |
|
| 1512 | + * 'baz', use '../baz'. If you want it to be conditional on a cousin input, |
|
| 1513 | + * the child of 'baz_section' named 'baz_child', use '../baz_section/baz_child'. |
|
| 1514 | + * Etc |
|
| 1515 | + * |
|
| 1516 | + * @param string|false $form_section_path we accept false also because substr( '../', '../' ) = false |
|
| 1517 | + * @return EE_Form_Section_Base |
|
| 1518 | + * @throws EE_Error |
|
| 1519 | + */ |
|
| 1520 | + public function find_section_from_path($form_section_path) |
|
| 1521 | + { |
|
| 1522 | + // check if we can find the input from purely going straight up the tree |
|
| 1523 | + $input = parent::find_section_from_path($form_section_path); |
|
| 1524 | + if ($input instanceof EE_Form_Section_Base) { |
|
| 1525 | + return $input; |
|
| 1526 | + } |
|
| 1527 | + $next_slash_pos = strpos($form_section_path, '/'); |
|
| 1528 | + if ($next_slash_pos !== false) { |
|
| 1529 | + $child_section_name = substr($form_section_path, 0, $next_slash_pos); |
|
| 1530 | + $subpath = substr($form_section_path, $next_slash_pos + 1); |
|
| 1531 | + } else { |
|
| 1532 | + $child_section_name = $form_section_path; |
|
| 1533 | + $subpath = ''; |
|
| 1534 | + } |
|
| 1535 | + $child_section = $this->get_subsection($child_section_name); |
|
| 1536 | + if ($child_section instanceof EE_Form_Section_Base) { |
|
| 1537 | + return $child_section->find_section_from_path($subpath); |
|
| 1538 | + } |
|
| 1539 | + return null; |
|
| 1540 | + } |
|
| 1541 | 1541 | } |
@@ -111,8 +111,8 @@ discard block |
||
| 111 | 111 | // AND we are going to make sure they're in that specified order |
| 112 | 112 | $reordered_subsections = array(); |
| 113 | 113 | foreach ($options_array['include'] as $input_name) { |
| 114 | - if (isset($this->_subsections[ $input_name ])) { |
|
| 115 | - $reordered_subsections[ $input_name ] = $this->_subsections[ $input_name ]; |
|
| 114 | + if (isset($this->_subsections[$input_name])) { |
|
| 115 | + $reordered_subsections[$input_name] = $this->_subsections[$input_name]; |
|
| 116 | 116 | } |
| 117 | 117 | } |
| 118 | 118 | $this->_subsections = $reordered_subsections; |
@@ -124,7 +124,7 @@ discard block |
||
| 124 | 124 | if (isset($options_array['layout_strategy'])) { |
| 125 | 125 | $this->_layout_strategy = $options_array['layout_strategy']; |
| 126 | 126 | } |
| 127 | - if (! $this->_layout_strategy) { |
|
| 127 | + if ( ! $this->_layout_strategy) { |
|
| 128 | 128 | $this->_layout_strategy = is_admin() ? new EE_Admin_Two_Column_Layout() : new EE_Two_Column_Layout(); |
| 129 | 129 | } |
| 130 | 130 | $this->_layout_strategy->_construct_finalize($this); |
@@ -313,7 +313,7 @@ discard block |
||
| 313 | 313 | if ($validate) { |
| 314 | 314 | $this->_validate(); |
| 315 | 315 | // if it's invalid, we're going to want to re-display so remember what they submitted |
| 316 | - if (! $this->is_valid()) { |
|
| 316 | + if ( ! $this->is_valid()) { |
|
| 317 | 317 | $this->store_submitted_form_data_in_session(); |
| 318 | 318 | } |
| 319 | 319 | } |
@@ -426,11 +426,11 @@ discard block |
||
| 426 | 426 | public function populate_defaults($default_data) |
| 427 | 427 | { |
| 428 | 428 | foreach ($this->subsections(false) as $subsection_name => $subsection) { |
| 429 | - if (isset($default_data[ $subsection_name ])) { |
|
| 429 | + if (isset($default_data[$subsection_name])) { |
|
| 430 | 430 | if ($subsection instanceof EE_Form_Input_Base) { |
| 431 | - $subsection->set_default($default_data[ $subsection_name ]); |
|
| 431 | + $subsection->set_default($default_data[$subsection_name]); |
|
| 432 | 432 | } elseif ($subsection instanceof EE_Form_Section_Proper) { |
| 433 | - $subsection->populate_defaults($default_data[ $subsection_name ]); |
|
| 433 | + $subsection->populate_defaults($default_data[$subsection_name]); |
|
| 434 | 434 | } |
| 435 | 435 | } |
| 436 | 436 | } |
@@ -445,7 +445,7 @@ discard block |
||
| 445 | 445 | */ |
| 446 | 446 | public function subsection_exists($name) |
| 447 | 447 | { |
| 448 | - return isset($this->_subsections[ $name ]) ? true : false; |
|
| 448 | + return isset($this->_subsections[$name]) ? true : false; |
|
| 449 | 449 | } |
| 450 | 450 | |
| 451 | 451 | |
@@ -467,7 +467,7 @@ discard block |
||
| 467 | 467 | if ($require_construction_to_be_finalized) { |
| 468 | 468 | $this->ensure_construct_finalized_called(); |
| 469 | 469 | } |
| 470 | - return $this->subsection_exists($name) ? $this->_subsections[ $name ] : null; |
|
| 470 | + return $this->subsection_exists($name) ? $this->_subsections[$name] : null; |
|
| 471 | 471 | } |
| 472 | 472 | |
| 473 | 473 | |
@@ -482,7 +482,7 @@ discard block |
||
| 482 | 482 | $validatable_subsections = array(); |
| 483 | 483 | foreach ($this->subsections() as $name => $obj) { |
| 484 | 484 | if ($obj instanceof EE_Form_Section_Validatable) { |
| 485 | - $validatable_subsections[ $name ] = $obj; |
|
| 485 | + $validatable_subsections[$name] = $obj; |
|
| 486 | 486 | } |
| 487 | 487 | } |
| 488 | 488 | return $validatable_subsections; |
@@ -509,7 +509,7 @@ discard block |
||
| 509 | 509 | $name, |
| 510 | 510 | $require_construction_to_be_finalized |
| 511 | 511 | ); |
| 512 | - if (! $subsection instanceof EE_Form_Input_Base) { |
|
| 512 | + if ( ! $subsection instanceof EE_Form_Input_Base) { |
|
| 513 | 513 | throw new EE_Error( |
| 514 | 514 | sprintf( |
| 515 | 515 | esc_html__( |
@@ -546,7 +546,7 @@ discard block |
||
| 546 | 546 | $name, |
| 547 | 547 | $require_construction_to_be_finalized |
| 548 | 548 | ); |
| 549 | - if (! $subsection instanceof EE_Form_Section_Proper) { |
|
| 549 | + if ( ! $subsection instanceof EE_Form_Section_Proper) { |
|
| 550 | 550 | throw new EE_Error( |
| 551 | 551 | sprintf( |
| 552 | 552 | esc_html__( |
@@ -586,7 +586,7 @@ discard block |
||
| 586 | 586 | public function is_valid() |
| 587 | 587 | { |
| 588 | 588 | if ($this->is_valid === null) { |
| 589 | - if (! $this->has_received_submission()) { |
|
| 589 | + if ( ! $this->has_received_submission()) { |
|
| 590 | 590 | throw new EE_Error( |
| 591 | 591 | sprintf( |
| 592 | 592 | esc_html__( |
@@ -596,14 +596,14 @@ discard block |
||
| 596 | 596 | ) |
| 597 | 597 | ); |
| 598 | 598 | } |
| 599 | - if (! parent::is_valid()) { |
|
| 599 | + if ( ! parent::is_valid()) { |
|
| 600 | 600 | $this->is_valid = false; |
| 601 | 601 | } else { |
| 602 | 602 | // ok so no general errors to this entire form section. |
| 603 | 603 | // so let's check the subsections, but only set errors if that hasn't been done yet |
| 604 | 604 | $this->is_valid = true; |
| 605 | 605 | foreach ($this->get_validatable_subsections() as $subsection) { |
| 606 | - if (! $subsection->is_valid()) { |
|
| 606 | + if ( ! $subsection->is_valid()) { |
|
| 607 | 607 | $this->is_valid = false; |
| 608 | 608 | } |
| 609 | 609 | } |
@@ -620,7 +620,7 @@ discard block |
||
| 620 | 620 | */ |
| 621 | 621 | protected function _set_default_name_if_empty() |
| 622 | 622 | { |
| 623 | - if (! $this->_name) { |
|
| 623 | + if ( ! $this->_name) { |
|
| 624 | 624 | $classname = get_class($this); |
| 625 | 625 | $default_name = str_replace('EE_', '', $classname); |
| 626 | 626 | $this->_name = $default_name; |
@@ -710,7 +710,7 @@ discard block |
||
| 710 | 710 | { |
| 711 | 711 | wp_register_script( |
| 712 | 712 | 'ee_form_section_validation', |
| 713 | - EE_GLOBAL_ASSETS_URL . 'scripts' . '/form_section_validation.js', |
|
| 713 | + EE_GLOBAL_ASSETS_URL.'scripts'.'/form_section_validation.js', |
|
| 714 | 714 | array('jquery-validate', 'jquery-ui-datepicker', 'jquery-validate-extra-methods'), |
| 715 | 715 | EVENT_ESPRESSO_VERSION, |
| 716 | 716 | true |
@@ -754,13 +754,13 @@ discard block |
||
| 754 | 754 | // we only want to localize vars ONCE for the entire form, |
| 755 | 755 | // so if the form section doesn't have a parent, then it must be the top dog |
| 756 | 756 | if ($return_for_subsection || ! $this->parent_section()) { |
| 757 | - EE_Form_Section_Proper::$_js_localization['form_data'][ $this->html_id() ] = array( |
|
| 757 | + EE_Form_Section_Proper::$_js_localization['form_data'][$this->html_id()] = array( |
|
| 758 | 758 | 'form_section_id' => $this->html_id(true), |
| 759 | 759 | 'validation_rules' => $this->get_jquery_validation_rules(), |
| 760 | 760 | 'other_data' => $this->get_other_js_data(), |
| 761 | 761 | 'errors' => $this->subsection_validation_errors_by_html_name(), |
| 762 | 762 | ); |
| 763 | - EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 763 | + EE_Form_Section_Proper::$_scripts_localized = true; |
|
| 764 | 764 | } |
| 765 | 765 | } |
| 766 | 766 | |
@@ -795,7 +795,7 @@ discard block |
||
| 795 | 795 | $inputs = array(); |
| 796 | 796 | foreach ($this->subsections() as $subsection) { |
| 797 | 797 | if ($subsection instanceof EE_Form_Input_Base) { |
| 798 | - $inputs[ $subsection->html_name() ] = $subsection; |
|
| 798 | + $inputs[$subsection->html_name()] = $subsection; |
|
| 799 | 799 | } elseif ($subsection instanceof EE_Form_Section_Proper) { |
| 800 | 800 | $inputs += $subsection->inputs_in_subsections(); |
| 801 | 801 | } |
@@ -818,7 +818,7 @@ discard block |
||
| 818 | 818 | $errors = array(); |
| 819 | 819 | foreach ($inputs as $form_input) { |
| 820 | 820 | if ($form_input instanceof EE_Form_Input_Base && $form_input->get_validation_errors()) { |
| 821 | - $errors[ $form_input->html_name() ] = $form_input->get_validation_error_string(); |
|
| 821 | + $errors[$form_input->html_name()] = $form_input->get_validation_error_string(); |
|
| 822 | 822 | } |
| 823 | 823 | } |
| 824 | 824 | return $errors; |
@@ -841,7 +841,7 @@ discard block |
||
| 841 | 841 | $email_validation_level = isset(EE_Registry::instance()->CFG->registration->email_validation_level) |
| 842 | 842 | ? EE_Registry::instance()->CFG->registration->email_validation_level |
| 843 | 843 | : 'wp_default'; |
| 844 | - EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 844 | + EE_Form_Section_Proper::$_js_localization['email_validation_level'] = $email_validation_level; |
|
| 845 | 845 | wp_enqueue_script('ee_form_section_validation'); |
| 846 | 846 | wp_localize_script( |
| 847 | 847 | 'ee_form_section_validation', |
@@ -858,7 +858,7 @@ discard block |
||
| 858 | 858 | */ |
| 859 | 859 | public function ensure_scripts_localized() |
| 860 | 860 | { |
| 861 | - if (! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 861 | + if ( ! EE_Form_Section_Proper::$_scripts_localized) { |
|
| 862 | 862 | $this->_enqueue_and_localize_form_js(); |
| 863 | 863 | } |
| 864 | 864 | } |
@@ -954,8 +954,8 @@ discard block |
||
| 954 | 954 | // reset the cache of whether this form is valid or not- we're re-validating it now |
| 955 | 955 | $this->is_valid = null; |
| 956 | 956 | foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
| 957 | - if (method_exists($this, '_validate_' . $subsection_name)) { |
|
| 958 | - call_user_func_array(array($this, '_validate_' . $subsection_name), array($subsection)); |
|
| 957 | + if (method_exists($this, '_validate_'.$subsection_name)) { |
|
| 958 | + call_user_func_array(array($this, '_validate_'.$subsection_name), array($subsection)); |
|
| 959 | 959 | } |
| 960 | 960 | $subsection->_validate(); |
| 961 | 961 | } |
@@ -973,9 +973,9 @@ discard block |
||
| 973 | 973 | $inputs = array(); |
| 974 | 974 | foreach ($this->subsections() as $subsection_name => $subsection) { |
| 975 | 975 | if ($subsection instanceof EE_Form_Section_Proper) { |
| 976 | - $inputs[ $subsection_name ] = $subsection->valid_data(); |
|
| 976 | + $inputs[$subsection_name] = $subsection->valid_data(); |
|
| 977 | 977 | } elseif ($subsection instanceof EE_Form_Input_Base) { |
| 978 | - $inputs[ $subsection_name ] = $subsection->normalized_value(); |
|
| 978 | + $inputs[$subsection_name] = $subsection->normalized_value(); |
|
| 979 | 979 | } |
| 980 | 980 | } |
| 981 | 981 | return $inputs; |
@@ -993,7 +993,7 @@ discard block |
||
| 993 | 993 | $inputs = array(); |
| 994 | 994 | foreach ($this->subsections() as $subsection_name => $subsection) { |
| 995 | 995 | if ($subsection instanceof EE_Form_Input_Base) { |
| 996 | - $inputs[ $subsection_name ] = $subsection; |
|
| 996 | + $inputs[$subsection_name] = $subsection; |
|
| 997 | 997 | } |
| 998 | 998 | } |
| 999 | 999 | return $inputs; |
@@ -1011,7 +1011,7 @@ discard block |
||
| 1011 | 1011 | $form_sections = array(); |
| 1012 | 1012 | foreach ($this->subsections() as $name => $obj) { |
| 1013 | 1013 | if ($obj instanceof EE_Form_Section_Proper) { |
| 1014 | - $form_sections[ $name ] = $obj; |
|
| 1014 | + $form_sections[$name] = $obj; |
|
| 1015 | 1015 | } |
| 1016 | 1016 | } |
| 1017 | 1017 | return $form_sections; |
@@ -1118,7 +1118,7 @@ discard block |
||
| 1118 | 1118 | $input_values = array(); |
| 1119 | 1119 | foreach ($this->subsections() as $subsection_name => $subsection) { |
| 1120 | 1120 | if ($subsection instanceof EE_Form_Input_Base) { |
| 1121 | - $input_values[ $subsection_name ] = $pretty |
|
| 1121 | + $input_values[$subsection_name] = $pretty |
|
| 1122 | 1122 | ? $subsection->pretty_value() |
| 1123 | 1123 | : $subsection->normalized_value(); |
| 1124 | 1124 | } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subform_inputs) { |
@@ -1130,7 +1130,7 @@ discard block |
||
| 1130 | 1130 | if ($flatten) { |
| 1131 | 1131 | $input_values = array_merge($input_values, $subform_input_values); |
| 1132 | 1132 | } else { |
| 1133 | - $input_values[ $subsection_name ] = $subform_input_values; |
|
| 1133 | + $input_values[$subsection_name] = $subform_input_values; |
|
| 1134 | 1134 | } |
| 1135 | 1135 | } |
| 1136 | 1136 | } |
@@ -1158,7 +1158,7 @@ discard block |
||
| 1158 | 1158 | if ($subsection instanceof EE_Form_Input_Base) { |
| 1159 | 1159 | // is this input part of an array of inputs? |
| 1160 | 1160 | if (strpos($subsection->html_name(), '[') !== false) { |
| 1161 | - $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1161 | + $full_input_name = EEH_Array::convert_array_values_to_keys( |
|
| 1162 | 1162 | explode( |
| 1163 | 1163 | '[', |
| 1164 | 1164 | str_replace(']', '', $subsection->html_name()) |
@@ -1167,7 +1167,7 @@ discard block |
||
| 1167 | 1167 | ); |
| 1168 | 1168 | $submitted_values = array_replace_recursive($submitted_values, $full_input_name); |
| 1169 | 1169 | } else { |
| 1170 | - $submitted_values[ $subsection->html_name() ] = $subsection->raw_value(); |
|
| 1170 | + $submitted_values[$subsection->html_name()] = $subsection->raw_value(); |
|
| 1171 | 1171 | } |
| 1172 | 1172 | } elseif ($subsection instanceof EE_Form_Section_Proper && $include_subforms) { |
| 1173 | 1173 | $subform_input_values = $subsection->submitted_values($include_subforms); |
@@ -1202,7 +1202,7 @@ discard block |
||
| 1202 | 1202 | public function exclude(array $inputs_to_exclude = array()) |
| 1203 | 1203 | { |
| 1204 | 1204 | foreach ($inputs_to_exclude as $input_to_exclude_name) { |
| 1205 | - unset($this->_subsections[ $input_to_exclude_name ]); |
|
| 1205 | + unset($this->_subsections[$input_to_exclude_name]); |
|
| 1206 | 1206 | } |
| 1207 | 1207 | } |
| 1208 | 1208 | |
@@ -1245,7 +1245,7 @@ discard block |
||
| 1245 | 1245 | public function add_subsections($new_subsections, $subsection_name_to_target = null, $add_before = true) |
| 1246 | 1246 | { |
| 1247 | 1247 | foreach ($new_subsections as $subsection_name => $subsection) { |
| 1248 | - if (! $subsection instanceof EE_Form_Section_Base) { |
|
| 1248 | + if ( ! $subsection instanceof EE_Form_Section_Base) { |
|
| 1249 | 1249 | EE_Error::add_error( |
| 1250 | 1250 | sprintf( |
| 1251 | 1251 | esc_html__( |
@@ -1257,7 +1257,7 @@ discard block |
||
| 1257 | 1257 | $this->name() |
| 1258 | 1258 | ) |
| 1259 | 1259 | ); |
| 1260 | - unset($new_subsections[ $subsection_name ]); |
|
| 1260 | + unset($new_subsections[$subsection_name]); |
|
| 1261 | 1261 | } |
| 1262 | 1262 | } |
| 1263 | 1263 | $this->_subsections = EEH_Array::insert_into_array( |
@@ -1372,7 +1372,7 @@ discard block |
||
| 1372 | 1372 | public function html_name_prefix() |
| 1373 | 1373 | { |
| 1374 | 1374 | if ($this->parent_section() instanceof EE_Form_Section_Proper) { |
| 1375 | - return $this->parent_section()->html_name_prefix() . '[' . $this->name() . ']'; |
|
| 1375 | + return $this->parent_section()->html_name_prefix().'['.$this->name().']'; |
|
| 1376 | 1376 | } |
| 1377 | 1377 | return $this->name(); |
| 1378 | 1378 | } |
@@ -1412,7 +1412,7 @@ discard block |
||
| 1412 | 1412 | */ |
| 1413 | 1413 | public function ensure_construct_finalized_called() |
| 1414 | 1414 | { |
| 1415 | - if (! $this->_construction_finalized) { |
|
| 1415 | + if ( ! $this->_construction_finalized) { |
|
| 1416 | 1416 | $this->_construct_finalize($this->_parent_section, $this->_name); |
| 1417 | 1417 | } |
| 1418 | 1418 | } |
@@ -17,559 +17,559 @@ |
||
| 17 | 17 | class EE_Payment_Method_Manager implements ResettableInterface |
| 18 | 18 | { |
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * prefix added to all payment method capabilities names |
|
| 22 | - */ |
|
| 23 | - const CAPABILITIES_PREFIX = 'ee_payment_method_'; |
|
| 24 | - |
|
| 25 | - /** |
|
| 26 | - * @var EE_Payment_Method_Manager $_instance |
|
| 27 | - */ |
|
| 28 | - private static $_instance; |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * @var boolean |
|
| 32 | - */ |
|
| 33 | - protected $payment_method_caps_initialized = false; |
|
| 34 | - |
|
| 35 | - /** |
|
| 36 | - * @var array keys are class names without 'EE_PMT_', values are their filepaths |
|
| 37 | - */ |
|
| 38 | - protected $_payment_method_types = array(); |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * @var EE_PMT_Base[] |
|
| 42 | - */ |
|
| 43 | - protected $payment_method_objects = array(); |
|
| 44 | - |
|
| 45 | - |
|
| 46 | - /** |
|
| 47 | - * EE_Payment_Method_Manager constructor. |
|
| 48 | - * |
|
| 49 | - * @throws EE_Error |
|
| 50 | - * @throws DomainException |
|
| 51 | - */ |
|
| 52 | - public function __construct() |
|
| 53 | - { |
|
| 54 | - // if in admin lets ensure caps are set. |
|
| 55 | - if (is_admin()) { |
|
| 56 | - $this->_register_payment_methods(); |
|
| 57 | - // set them immediately |
|
| 58 | - $this->initializePaymentMethodCaps(); |
|
| 59 | - // plus any time they get reset |
|
| 60 | - add_filter( |
|
| 61 | - 'FHEE__EE_Capabilities__addCaps__capabilities_to_add', |
|
| 62 | - array($this, 'addPaymentMethodCapsDuringReset') |
|
| 63 | - ); |
|
| 64 | - } |
|
| 65 | - } |
|
| 66 | - |
|
| 67 | - |
|
| 68 | - /** |
|
| 69 | - * @singleton method used to instantiate class object |
|
| 70 | - * @return EE_Payment_Method_Manager instance |
|
| 71 | - * @throws DomainException |
|
| 72 | - * @throws EE_Error |
|
| 73 | - */ |
|
| 74 | - public static function instance() |
|
| 75 | - { |
|
| 76 | - // check if class object is instantiated, and instantiated properly |
|
| 77 | - if (! self::$_instance instanceof EE_Payment_Method_Manager) { |
|
| 78 | - EE_Registry::instance()->load_lib('PMT_Base'); |
|
| 79 | - self::$_instance = new self(); |
|
| 80 | - } |
|
| 81 | - return self::$_instance; |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * Resets the instance and returns a new one |
|
| 87 | - * |
|
| 88 | - * @return EE_Payment_Method_Manager |
|
| 89 | - * @throws DomainException |
|
| 90 | - * @throws EE_Error |
|
| 91 | - */ |
|
| 92 | - public static function reset() |
|
| 93 | - { |
|
| 94 | - self::$_instance = null; |
|
| 95 | - return self::instance(); |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - |
|
| 99 | - /** |
|
| 100 | - * If necessary, re-register payment methods |
|
| 101 | - * |
|
| 102 | - * @param boolean $force_recheck whether to recheck for payment method types, |
|
| 103 | - * or just re-use the PMTs we found last time we checked during this request (if |
|
| 104 | - * we have not yet checked during this request, then we need to check anyways) |
|
| 105 | - */ |
|
| 106 | - public function maybe_register_payment_methods($force_recheck = false) |
|
| 107 | - { |
|
| 108 | - if (! $this->_payment_method_types || $force_recheck) { |
|
| 109 | - $this->_register_payment_methods(); |
|
| 110 | - } |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * register_payment_methods |
|
| 116 | - * |
|
| 117 | - * @return array |
|
| 118 | - */ |
|
| 119 | - protected function _register_payment_methods() |
|
| 120 | - { |
|
| 121 | - // grab list of installed modules |
|
| 122 | - $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR); |
|
| 123 | - // filter list of modules to register |
|
| 124 | - $pm_to_register = apply_filters( |
|
| 125 | - 'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register', |
|
| 126 | - $pm_to_register |
|
| 127 | - ); |
|
| 128 | - // remove any duplicates if that should happen for some reason |
|
| 129 | - $pm_to_register = array_unique($pm_to_register); |
|
| 130 | - // loop through folders |
|
| 131 | - foreach ($pm_to_register as $pm_path) { |
|
| 132 | - $this->register_payment_method($pm_path); |
|
| 133 | - } |
|
| 134 | - do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods'); |
|
| 135 | - // filter list of installed modules |
|
| 136 | - // keep them organized alphabetically by the payment method type's name |
|
| 137 | - ksort($this->_payment_method_types); |
|
| 138 | - return apply_filters( |
|
| 139 | - 'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods', |
|
| 140 | - $this->_payment_method_types |
|
| 141 | - ); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * register_payment_method- makes core aware of this payment method |
|
| 147 | - * |
|
| 148 | - * @param string $payment_method_path - full path up to and including payment method folder |
|
| 149 | - * @return boolean |
|
| 150 | - */ |
|
| 151 | - public function register_payment_method($payment_method_path = '') |
|
| 152 | - { |
|
| 153 | - do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path); |
|
| 154 | - $module_ext = '.pm.php'; |
|
| 155 | - // make all separators match |
|
| 156 | - $payment_method_path = rtrim(str_replace('/\\', '/', $payment_method_path), '/'); |
|
| 157 | - // grab and sanitize module name |
|
| 158 | - $module_dir = basename($payment_method_path); |
|
| 159 | - // create class name from module directory name |
|
| 160 | - $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir); |
|
| 161 | - // add class prefix |
|
| 162 | - $module_class = 'EE_PMT_' . $module; |
|
| 163 | - // does the module exist ? |
|
| 164 | - if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) { |
|
| 165 | - $msg = sprintf( |
|
| 166 | - esc_html__( |
|
| 167 | - 'The requested %s payment method file could not be found or is not readable due to file permissions.', |
|
| 168 | - 'event_espresso' |
|
| 169 | - ), |
|
| 170 | - $module |
|
| 171 | - ); |
|
| 172 | - EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 173 | - return false; |
|
| 174 | - } |
|
| 175 | - // load the module class file |
|
| 176 | - require_once($payment_method_path . '/' . $module_class . $module_ext); |
|
| 177 | - // verify that class exists |
|
| 178 | - if (! class_exists($module_class)) { |
|
| 179 | - $msg = sprintf( |
|
| 180 | - esc_html__('The requested %s module class does not exist.', 'event_espresso'), |
|
| 181 | - $module_class |
|
| 182 | - ); |
|
| 183 | - EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 184 | - return false; |
|
| 185 | - } |
|
| 186 | - // add to array of registered modules |
|
| 187 | - $this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext; |
|
| 188 | - ksort($this->_payment_method_types); |
|
| 189 | - return true; |
|
| 190 | - } |
|
| 191 | - |
|
| 192 | - |
|
| 193 | - /** |
|
| 194 | - * Checks if a payment method has been registered, and if so includes it |
|
| 195 | - * |
|
| 196 | - * @param string $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_') |
|
| 197 | - * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 198 | - * @return boolean |
|
| 199 | - */ |
|
| 200 | - public function payment_method_type_exists($payment_method_name, $force_recheck = false) |
|
| 201 | - { |
|
| 202 | - if ($force_recheck |
|
| 203 | - || ! is_array($this->_payment_method_types) |
|
| 204 | - || ! isset($this->_payment_method_types[ $payment_method_name ]) |
|
| 205 | - ) { |
|
| 206 | - $this->maybe_register_payment_methods($force_recheck); |
|
| 207 | - } |
|
| 208 | - if (isset($this->_payment_method_types[ $payment_method_name ])) { |
|
| 209 | - require_once($this->_payment_method_types[ $payment_method_name ]); |
|
| 210 | - return true; |
|
| 211 | - } |
|
| 212 | - return false; |
|
| 213 | - } |
|
| 214 | - |
|
| 215 | - |
|
| 216 | - /** |
|
| 217 | - * Returns all the class names of the various payment method types |
|
| 218 | - * |
|
| 219 | - * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names' |
|
| 220 | - * (what you'd find in wp_esp_payment_method.PMD_type) |
|
| 221 | - * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 222 | - * @return array |
|
| 223 | - */ |
|
| 224 | - public function payment_method_type_names($with_prefixes = false, $force_recheck = false) |
|
| 225 | - { |
|
| 226 | - $this->maybe_register_payment_methods($force_recheck); |
|
| 227 | - if ($with_prefixes) { |
|
| 228 | - $classnames = array_keys($this->_payment_method_types); |
|
| 229 | - $payment_methods = array(); |
|
| 230 | - foreach ($classnames as $classname) { |
|
| 231 | - $payment_methods[] = $this->payment_method_class_from_type($classname); |
|
| 232 | - } |
|
| 233 | - return $payment_methods; |
|
| 234 | - } |
|
| 235 | - return array_keys($this->_payment_method_types); |
|
| 236 | - } |
|
| 237 | - |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * Gets an object of each payment method type, none of which are bound to a |
|
| 241 | - * payment method instance |
|
| 242 | - * |
|
| 243 | - * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 244 | - * @return EE_PMT_Base[] |
|
| 245 | - */ |
|
| 246 | - public function payment_method_types($force_recheck = false) |
|
| 247 | - { |
|
| 248 | - if ($force_recheck || empty($this->payment_method_objects)) { |
|
| 249 | - $this->maybe_register_payment_methods($force_recheck); |
|
| 250 | - foreach ($this->payment_method_type_names(true) as $classname) { |
|
| 251 | - if (! isset($this->payment_method_objects[ $classname ])) { |
|
| 252 | - $this->payment_method_objects[ $classname ] = new $classname; |
|
| 253 | - } |
|
| 254 | - } |
|
| 255 | - } |
|
| 256 | - return $this->payment_method_objects; |
|
| 257 | - } |
|
| 258 | - |
|
| 259 | - |
|
| 260 | - /** |
|
| 261 | - * Changes the payment method's class name into the payment method type's name |
|
| 262 | - * (as used on the payment method's table's PMD_type field) |
|
| 263 | - * |
|
| 264 | - * @param string $classname |
|
| 265 | - * @return string |
|
| 266 | - */ |
|
| 267 | - public function payment_method_type_sans_class_prefix($classname) |
|
| 268 | - { |
|
| 269 | - return str_replace('EE_PMT_', '', $classname); |
|
| 270 | - } |
|
| 271 | - |
|
| 272 | - |
|
| 273 | - /** |
|
| 274 | - * Does the opposite of payment-method_type_sans_prefix |
|
| 275 | - * |
|
| 276 | - * @param string $type |
|
| 277 | - * @return string |
|
| 278 | - */ |
|
| 279 | - public function payment_method_class_from_type($type) |
|
| 280 | - { |
|
| 281 | - return 'EE_PMT_' . $type; |
|
| 282 | - } |
|
| 283 | - |
|
| 284 | - |
|
| 285 | - /** |
|
| 286 | - * Activates a payment method of the given type. |
|
| 287 | - * |
|
| 288 | - * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice' |
|
| 289 | - * @return EE_Payment_Method |
|
| 290 | - * @throws InvalidDataTypeException |
|
| 291 | - * @throws EE_Error |
|
| 292 | - */ |
|
| 293 | - public function activate_a_payment_method_of_type($payment_method_type) |
|
| 294 | - { |
|
| 295 | - $this->maybe_register_payment_methods(); |
|
| 296 | - $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type); |
|
| 297 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
| 298 | - $pm_type_class = $this->payment_method_class_from_type($payment_method_type); |
|
| 299 | - if (class_exists($pm_type_class)) { |
|
| 300 | - /** @var $pm_type_obj EE_PMT_Base */ |
|
| 301 | - $pm_type_obj = new $pm_type_class; |
|
| 302 | - $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name()); |
|
| 303 | - if (! $payment_method) { |
|
| 304 | - $payment_method = $this->create_payment_method_of_type($pm_type_obj); |
|
| 305 | - } |
|
| 306 | - $payment_method->set_type($payment_method_type); |
|
| 307 | - $this->initialize_payment_method($payment_method); |
|
| 308 | - } else { |
|
| 309 | - throw new EE_Error( |
|
| 310 | - sprintf( |
|
| 311 | - esc_html__( |
|
| 312 | - 'There is no payment method of type %1$s, so it could not be activated', |
|
| 313 | - 'event_espresso' |
|
| 314 | - ), |
|
| 315 | - $pm_type_class |
|
| 316 | - ) |
|
| 317 | - ); |
|
| 318 | - } |
|
| 319 | - } |
|
| 320 | - $payment_method->set_active(); |
|
| 321 | - $payment_method->save(); |
|
| 322 | - /** @type EE_Message_Resource_Manager $message_resource_manager */ |
|
| 323 | - // if this was the invoice message type, make sure users can view their invoices |
|
| 324 | - if ($payment_method->type() === 'Invoice' |
|
| 325 | - && ( |
|
| 326 | - ! EEH_MSG_Template::is_mt_active('invoice') |
|
| 327 | - ) |
|
| 328 | - ) { |
|
| 329 | - $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager'); |
|
| 330 | - /** @type EE_Message_Resource_Manager $message_resource_manager */ |
|
| 331 | - $message_resource_manager->ensure_message_type_is_active('invoice', 'html'); |
|
| 332 | - new PersistentAdminNotice( |
|
| 333 | - 'invoice_pm_requirements_notice', |
|
| 334 | - sprintf( |
|
| 335 | - esc_html__( |
|
| 336 | - 'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.', |
|
| 337 | - 'event_espresso' |
|
| 338 | - ), |
|
| 339 | - '<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">', |
|
| 340 | - '</a>' |
|
| 341 | - ), |
|
| 342 | - true |
|
| 343 | - ); |
|
| 344 | - } |
|
| 345 | - return $payment_method; |
|
| 346 | - } |
|
| 347 | - |
|
| 348 | - |
|
| 349 | - /** |
|
| 350 | - * Creates a payment method of the specified type. Does not save it. |
|
| 351 | - * |
|
| 352 | - * @global WP_User $current_user |
|
| 353 | - * @param EE_PMT_Base $pm_type_obj |
|
| 354 | - * @return EE_Payment_Method |
|
| 355 | - * @throws EE_Error |
|
| 356 | - */ |
|
| 357 | - public function create_payment_method_of_type($pm_type_obj) |
|
| 358 | - { |
|
| 359 | - global $current_user; |
|
| 360 | - $payment_method = EE_Payment_Method::new_instance( |
|
| 361 | - array( |
|
| 362 | - 'PMD_type' => $pm_type_obj->system_name(), |
|
| 363 | - 'PMD_name' => $pm_type_obj->defaultFrontendName(), |
|
| 364 | - 'PMD_admin_name' => $pm_type_obj->pretty_name(), |
|
| 365 | - 'PMD_slug' => $pm_type_obj->system_name(),// automatically converted to slug |
|
| 366 | - 'PMD_wp_user' => $current_user->ID, |
|
| 367 | - 'PMD_order' => EEM_Payment_Method::instance()->count( |
|
| 368 | - array(array('PMD_type' => array('!=', 'Admin_Only'))) |
|
| 369 | - ) * 10, |
|
| 370 | - ) |
|
| 371 | - ); |
|
| 372 | - return $payment_method; |
|
| 373 | - } |
|
| 374 | - |
|
| 375 | - |
|
| 376 | - /** |
|
| 377 | - * Sets the initial payment method properties (including extra meta) |
|
| 378 | - * |
|
| 379 | - * @param EE_Payment_Method $payment_method |
|
| 380 | - * @return EE_Payment_Method |
|
| 381 | - * @throws EE_Error |
|
| 382 | - */ |
|
| 383 | - public function initialize_payment_method($payment_method) |
|
| 384 | - { |
|
| 385 | - $pm_type_obj = $payment_method->type_obj(); |
|
| 386 | - $payment_method->set_description($pm_type_obj->default_description()); |
|
| 387 | - if (! $payment_method->button_url()) { |
|
| 388 | - $payment_method->set_button_url($pm_type_obj->default_button_url()); |
|
| 389 | - } |
|
| 390 | - // now add setup its default extra meta properties |
|
| 391 | - $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs(); |
|
| 392 | - if (! empty($extra_metas)) { |
|
| 393 | - // verify the payment method has an ID before adding extra meta |
|
| 394 | - if (! $payment_method->ID()) { |
|
| 395 | - $payment_method->save(); |
|
| 396 | - } |
|
| 397 | - foreach ($extra_metas as $meta_name => $input) { |
|
| 398 | - $payment_method->update_extra_meta($meta_name, $input->raw_value()); |
|
| 399 | - } |
|
| 400 | - } |
|
| 401 | - return $payment_method; |
|
| 402 | - } |
|
| 403 | - |
|
| 404 | - |
|
| 405 | - /** |
|
| 406 | - * Makes sure the payment method is related to the specified payment method |
|
| 407 | - * |
|
| 408 | - * @deprecated in 4.9.40 because the currency payment method table is being deprecated |
|
| 409 | - * @param EE_Payment_Method $payment_method |
|
| 410 | - * @return EE_Payment_Method |
|
| 411 | - * @throws EE_Error |
|
| 412 | - */ |
|
| 413 | - public function set_usable_currencies_on_payment_method($payment_method) |
|
| 414 | - { |
|
| 415 | - EE_Error::doing_it_wrong( |
|
| 416 | - 'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method', |
|
| 417 | - esc_html__( |
|
| 418 | - 'We no longer define what currencies are usable by payment methods. Its not used nor efficient.', |
|
| 419 | - 'event_espresso' |
|
| 420 | - ), |
|
| 421 | - '4.9.40' |
|
| 422 | - ); |
|
| 423 | - return $payment_method; |
|
| 424 | - } |
|
| 425 | - |
|
| 426 | - |
|
| 427 | - /** |
|
| 428 | - * Deactivates a payment method of the given payment method slug. |
|
| 429 | - * |
|
| 430 | - * @param string $payment_method_slug The slug for the payment method to deactivate. |
|
| 431 | - * @return int count of rows updated. |
|
| 432 | - * @throws EE_Error |
|
| 433 | - */ |
|
| 434 | - public function deactivate_payment_method($payment_method_slug) |
|
| 435 | - { |
|
| 436 | - EE_Log::instance()->log( |
|
| 437 | - __FILE__, |
|
| 438 | - __FUNCTION__, |
|
| 439 | - sprintf( |
|
| 440 | - esc_html__( |
|
| 441 | - 'Payment method with slug %1$s is being deactivated by site admin', |
|
| 442 | - 'event_espresso' |
|
| 443 | - ), |
|
| 444 | - $payment_method_slug |
|
| 445 | - ), |
|
| 446 | - 'payment_method_change' |
|
| 447 | - ); |
|
| 448 | - $count_updated = EEM_Payment_Method::instance()->update( |
|
| 449 | - array('PMD_scope' => array()), |
|
| 450 | - array(array('PMD_slug' => $payment_method_slug)) |
|
| 451 | - ); |
|
| 452 | - do_action( |
|
| 453 | - 'AHEE__EE_Payment_Method_Manager__deactivate_payment_method__after_deactivating_payment_method', |
|
| 454 | - $payment_method_slug, |
|
| 455 | - $count_updated |
|
| 456 | - ); |
|
| 457 | - return $count_updated; |
|
| 458 | - } |
|
| 459 | - |
|
| 460 | - |
|
| 461 | - /** |
|
| 462 | - * initializes payment method access caps via EE_Capabilities::init_role_caps() |
|
| 463 | - * upon EE_Payment_Method_Manager construction |
|
| 464 | - * |
|
| 465 | - * @throws EE_Error |
|
| 466 | - * @throws DomainException |
|
| 467 | - */ |
|
| 468 | - protected function initializePaymentMethodCaps() |
|
| 469 | - { |
|
| 470 | - // don't do this twice |
|
| 471 | - if ($this->payment_method_caps_initialized) { |
|
| 472 | - return; |
|
| 473 | - } |
|
| 474 | - EE_Capabilities::instance()->addCaps( |
|
| 475 | - $this->getPaymentMethodCaps() |
|
| 476 | - ); |
|
| 477 | - $this->payment_method_caps_initialized = true; |
|
| 478 | - } |
|
| 479 | - |
|
| 480 | - |
|
| 481 | - /** |
|
| 482 | - * array of dynamic payment method access caps. |
|
| 483 | - * at the time of writing, october 20 2014, these are the caps added: |
|
| 484 | - * ee_payment_method_admin_only |
|
| 485 | - * ee_payment_method_aim |
|
| 486 | - * ee_payment_method_bank |
|
| 487 | - * ee_payment_method_check |
|
| 488 | - * ee_payment_method_invoice |
|
| 489 | - * ee_payment_method_mijireh |
|
| 490 | - * ee_payment_method_paypal_pro |
|
| 491 | - * ee_payment_method_paypal_standard |
|
| 492 | - * Any other payment methods added to core or via addons will also get |
|
| 493 | - * their related capability automatically added too, so long as they are |
|
| 494 | - * registered properly using EE_Register_Payment_Method::register() |
|
| 495 | - * |
|
| 496 | - * @return array |
|
| 497 | - * @throws DomainException |
|
| 498 | - */ |
|
| 499 | - protected function getPaymentMethodCaps() |
|
| 500 | - { |
|
| 501 | - $caps = array(); |
|
| 502 | - foreach ($this->payment_method_type_names() as $payment_method_name) { |
|
| 503 | - $caps = $this->addPaymentMethodCap($payment_method_name, $caps); |
|
| 504 | - } |
|
| 505 | - return $caps; |
|
| 506 | - } |
|
| 507 | - |
|
| 508 | - |
|
| 509 | - /** |
|
| 510 | - * @param string $payment_method_name |
|
| 511 | - * @param array $payment_method_caps |
|
| 512 | - * @param string $role |
|
| 513 | - * @return array |
|
| 514 | - * @throws DomainException |
|
| 515 | - */ |
|
| 516 | - public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator') |
|
| 517 | - { |
|
| 518 | - if (empty($payment_method_name)) { |
|
| 519 | - throw new DomainException( |
|
| 520 | - esc_html__( |
|
| 521 | - 'The name of a payment method must be specified to add capabilities.', |
|
| 522 | - 'event_espresso' |
|
| 523 | - ) |
|
| 524 | - ); |
|
| 525 | - } |
|
| 526 | - if (empty($role)) { |
|
| 527 | - throw new DomainException( |
|
| 528 | - sprintf( |
|
| 529 | - esc_html__( |
|
| 530 | - 'No role was supplied while trying to add capabilities for the %1$s payment method.', |
|
| 531 | - 'event_espresso' |
|
| 532 | - ), |
|
| 533 | - $payment_method_name |
|
| 534 | - ) |
|
| 535 | - ); |
|
| 536 | - } |
|
| 537 | - if (! isset($payment_method_caps[ $role ])) { |
|
| 538 | - $payment_method_caps[ $role ] = array(); |
|
| 539 | - } |
|
| 540 | - $payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX |
|
| 541 | - . strtolower($payment_method_name); |
|
| 542 | - return $payment_method_caps; |
|
| 543 | - } |
|
| 544 | - |
|
| 545 | - |
|
| 546 | - /** |
|
| 547 | - * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter |
|
| 548 | - * to add dynamic payment method access caps when capabilities are reset |
|
| 549 | - * (or if that filter is called and PM caps are not already set) |
|
| 550 | - * |
|
| 551 | - * @param array $caps capabilities being filtered |
|
| 552 | - * @param bool $reset |
|
| 553 | - * @return array |
|
| 554 | - * @throws DomainException |
|
| 555 | - */ |
|
| 556 | - public function addPaymentMethodCapsDuringReset(array $caps, $reset = false) |
|
| 557 | - { |
|
| 558 | - if ($reset || ! $this->payment_method_caps_initialized) { |
|
| 559 | - $this->payment_method_caps_initialized = true; |
|
| 560 | - $caps = array_merge_recursive($caps, $this->getPaymentMethodCaps()); |
|
| 561 | - } |
|
| 562 | - return $caps; |
|
| 563 | - } |
|
| 564 | - |
|
| 565 | - |
|
| 566 | - /** |
|
| 567 | - * @deprecated 4.9.42 |
|
| 568 | - * @param $caps |
|
| 569 | - * @return mixed |
|
| 570 | - */ |
|
| 571 | - public function add_payment_method_caps($caps) |
|
| 572 | - { |
|
| 573 | - return $caps; |
|
| 574 | - } |
|
| 20 | + /** |
|
| 21 | + * prefix added to all payment method capabilities names |
|
| 22 | + */ |
|
| 23 | + const CAPABILITIES_PREFIX = 'ee_payment_method_'; |
|
| 24 | + |
|
| 25 | + /** |
|
| 26 | + * @var EE_Payment_Method_Manager $_instance |
|
| 27 | + */ |
|
| 28 | + private static $_instance; |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * @var boolean |
|
| 32 | + */ |
|
| 33 | + protected $payment_method_caps_initialized = false; |
|
| 34 | + |
|
| 35 | + /** |
|
| 36 | + * @var array keys are class names without 'EE_PMT_', values are their filepaths |
|
| 37 | + */ |
|
| 38 | + protected $_payment_method_types = array(); |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * @var EE_PMT_Base[] |
|
| 42 | + */ |
|
| 43 | + protected $payment_method_objects = array(); |
|
| 44 | + |
|
| 45 | + |
|
| 46 | + /** |
|
| 47 | + * EE_Payment_Method_Manager constructor. |
|
| 48 | + * |
|
| 49 | + * @throws EE_Error |
|
| 50 | + * @throws DomainException |
|
| 51 | + */ |
|
| 52 | + public function __construct() |
|
| 53 | + { |
|
| 54 | + // if in admin lets ensure caps are set. |
|
| 55 | + if (is_admin()) { |
|
| 56 | + $this->_register_payment_methods(); |
|
| 57 | + // set them immediately |
|
| 58 | + $this->initializePaymentMethodCaps(); |
|
| 59 | + // plus any time they get reset |
|
| 60 | + add_filter( |
|
| 61 | + 'FHEE__EE_Capabilities__addCaps__capabilities_to_add', |
|
| 62 | + array($this, 'addPaymentMethodCapsDuringReset') |
|
| 63 | + ); |
|
| 64 | + } |
|
| 65 | + } |
|
| 66 | + |
|
| 67 | + |
|
| 68 | + /** |
|
| 69 | + * @singleton method used to instantiate class object |
|
| 70 | + * @return EE_Payment_Method_Manager instance |
|
| 71 | + * @throws DomainException |
|
| 72 | + * @throws EE_Error |
|
| 73 | + */ |
|
| 74 | + public static function instance() |
|
| 75 | + { |
|
| 76 | + // check if class object is instantiated, and instantiated properly |
|
| 77 | + if (! self::$_instance instanceof EE_Payment_Method_Manager) { |
|
| 78 | + EE_Registry::instance()->load_lib('PMT_Base'); |
|
| 79 | + self::$_instance = new self(); |
|
| 80 | + } |
|
| 81 | + return self::$_instance; |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * Resets the instance and returns a new one |
|
| 87 | + * |
|
| 88 | + * @return EE_Payment_Method_Manager |
|
| 89 | + * @throws DomainException |
|
| 90 | + * @throws EE_Error |
|
| 91 | + */ |
|
| 92 | + public static function reset() |
|
| 93 | + { |
|
| 94 | + self::$_instance = null; |
|
| 95 | + return self::instance(); |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + |
|
| 99 | + /** |
|
| 100 | + * If necessary, re-register payment methods |
|
| 101 | + * |
|
| 102 | + * @param boolean $force_recheck whether to recheck for payment method types, |
|
| 103 | + * or just re-use the PMTs we found last time we checked during this request (if |
|
| 104 | + * we have not yet checked during this request, then we need to check anyways) |
|
| 105 | + */ |
|
| 106 | + public function maybe_register_payment_methods($force_recheck = false) |
|
| 107 | + { |
|
| 108 | + if (! $this->_payment_method_types || $force_recheck) { |
|
| 109 | + $this->_register_payment_methods(); |
|
| 110 | + } |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * register_payment_methods |
|
| 116 | + * |
|
| 117 | + * @return array |
|
| 118 | + */ |
|
| 119 | + protected function _register_payment_methods() |
|
| 120 | + { |
|
| 121 | + // grab list of installed modules |
|
| 122 | + $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR); |
|
| 123 | + // filter list of modules to register |
|
| 124 | + $pm_to_register = apply_filters( |
|
| 125 | + 'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register', |
|
| 126 | + $pm_to_register |
|
| 127 | + ); |
|
| 128 | + // remove any duplicates if that should happen for some reason |
|
| 129 | + $pm_to_register = array_unique($pm_to_register); |
|
| 130 | + // loop through folders |
|
| 131 | + foreach ($pm_to_register as $pm_path) { |
|
| 132 | + $this->register_payment_method($pm_path); |
|
| 133 | + } |
|
| 134 | + do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods'); |
|
| 135 | + // filter list of installed modules |
|
| 136 | + // keep them organized alphabetically by the payment method type's name |
|
| 137 | + ksort($this->_payment_method_types); |
|
| 138 | + return apply_filters( |
|
| 139 | + 'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods', |
|
| 140 | + $this->_payment_method_types |
|
| 141 | + ); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * register_payment_method- makes core aware of this payment method |
|
| 147 | + * |
|
| 148 | + * @param string $payment_method_path - full path up to and including payment method folder |
|
| 149 | + * @return boolean |
|
| 150 | + */ |
|
| 151 | + public function register_payment_method($payment_method_path = '') |
|
| 152 | + { |
|
| 153 | + do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path); |
|
| 154 | + $module_ext = '.pm.php'; |
|
| 155 | + // make all separators match |
|
| 156 | + $payment_method_path = rtrim(str_replace('/\\', '/', $payment_method_path), '/'); |
|
| 157 | + // grab and sanitize module name |
|
| 158 | + $module_dir = basename($payment_method_path); |
|
| 159 | + // create class name from module directory name |
|
| 160 | + $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir); |
|
| 161 | + // add class prefix |
|
| 162 | + $module_class = 'EE_PMT_' . $module; |
|
| 163 | + // does the module exist ? |
|
| 164 | + if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) { |
|
| 165 | + $msg = sprintf( |
|
| 166 | + esc_html__( |
|
| 167 | + 'The requested %s payment method file could not be found or is not readable due to file permissions.', |
|
| 168 | + 'event_espresso' |
|
| 169 | + ), |
|
| 170 | + $module |
|
| 171 | + ); |
|
| 172 | + EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 173 | + return false; |
|
| 174 | + } |
|
| 175 | + // load the module class file |
|
| 176 | + require_once($payment_method_path . '/' . $module_class . $module_ext); |
|
| 177 | + // verify that class exists |
|
| 178 | + if (! class_exists($module_class)) { |
|
| 179 | + $msg = sprintf( |
|
| 180 | + esc_html__('The requested %s module class does not exist.', 'event_espresso'), |
|
| 181 | + $module_class |
|
| 182 | + ); |
|
| 183 | + EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 184 | + return false; |
|
| 185 | + } |
|
| 186 | + // add to array of registered modules |
|
| 187 | + $this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext; |
|
| 188 | + ksort($this->_payment_method_types); |
|
| 189 | + return true; |
|
| 190 | + } |
|
| 191 | + |
|
| 192 | + |
|
| 193 | + /** |
|
| 194 | + * Checks if a payment method has been registered, and if so includes it |
|
| 195 | + * |
|
| 196 | + * @param string $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_') |
|
| 197 | + * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 198 | + * @return boolean |
|
| 199 | + */ |
|
| 200 | + public function payment_method_type_exists($payment_method_name, $force_recheck = false) |
|
| 201 | + { |
|
| 202 | + if ($force_recheck |
|
| 203 | + || ! is_array($this->_payment_method_types) |
|
| 204 | + || ! isset($this->_payment_method_types[ $payment_method_name ]) |
|
| 205 | + ) { |
|
| 206 | + $this->maybe_register_payment_methods($force_recheck); |
|
| 207 | + } |
|
| 208 | + if (isset($this->_payment_method_types[ $payment_method_name ])) { |
|
| 209 | + require_once($this->_payment_method_types[ $payment_method_name ]); |
|
| 210 | + return true; |
|
| 211 | + } |
|
| 212 | + return false; |
|
| 213 | + } |
|
| 214 | + |
|
| 215 | + |
|
| 216 | + /** |
|
| 217 | + * Returns all the class names of the various payment method types |
|
| 218 | + * |
|
| 219 | + * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names' |
|
| 220 | + * (what you'd find in wp_esp_payment_method.PMD_type) |
|
| 221 | + * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 222 | + * @return array |
|
| 223 | + */ |
|
| 224 | + public function payment_method_type_names($with_prefixes = false, $force_recheck = false) |
|
| 225 | + { |
|
| 226 | + $this->maybe_register_payment_methods($force_recheck); |
|
| 227 | + if ($with_prefixes) { |
|
| 228 | + $classnames = array_keys($this->_payment_method_types); |
|
| 229 | + $payment_methods = array(); |
|
| 230 | + foreach ($classnames as $classname) { |
|
| 231 | + $payment_methods[] = $this->payment_method_class_from_type($classname); |
|
| 232 | + } |
|
| 233 | + return $payment_methods; |
|
| 234 | + } |
|
| 235 | + return array_keys($this->_payment_method_types); |
|
| 236 | + } |
|
| 237 | + |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * Gets an object of each payment method type, none of which are bound to a |
|
| 241 | + * payment method instance |
|
| 242 | + * |
|
| 243 | + * @param boolean $force_recheck whether to force re-checking for new payment method types |
|
| 244 | + * @return EE_PMT_Base[] |
|
| 245 | + */ |
|
| 246 | + public function payment_method_types($force_recheck = false) |
|
| 247 | + { |
|
| 248 | + if ($force_recheck || empty($this->payment_method_objects)) { |
|
| 249 | + $this->maybe_register_payment_methods($force_recheck); |
|
| 250 | + foreach ($this->payment_method_type_names(true) as $classname) { |
|
| 251 | + if (! isset($this->payment_method_objects[ $classname ])) { |
|
| 252 | + $this->payment_method_objects[ $classname ] = new $classname; |
|
| 253 | + } |
|
| 254 | + } |
|
| 255 | + } |
|
| 256 | + return $this->payment_method_objects; |
|
| 257 | + } |
|
| 258 | + |
|
| 259 | + |
|
| 260 | + /** |
|
| 261 | + * Changes the payment method's class name into the payment method type's name |
|
| 262 | + * (as used on the payment method's table's PMD_type field) |
|
| 263 | + * |
|
| 264 | + * @param string $classname |
|
| 265 | + * @return string |
|
| 266 | + */ |
|
| 267 | + public function payment_method_type_sans_class_prefix($classname) |
|
| 268 | + { |
|
| 269 | + return str_replace('EE_PMT_', '', $classname); |
|
| 270 | + } |
|
| 271 | + |
|
| 272 | + |
|
| 273 | + /** |
|
| 274 | + * Does the opposite of payment-method_type_sans_prefix |
|
| 275 | + * |
|
| 276 | + * @param string $type |
|
| 277 | + * @return string |
|
| 278 | + */ |
|
| 279 | + public function payment_method_class_from_type($type) |
|
| 280 | + { |
|
| 281 | + return 'EE_PMT_' . $type; |
|
| 282 | + } |
|
| 283 | + |
|
| 284 | + |
|
| 285 | + /** |
|
| 286 | + * Activates a payment method of the given type. |
|
| 287 | + * |
|
| 288 | + * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice' |
|
| 289 | + * @return EE_Payment_Method |
|
| 290 | + * @throws InvalidDataTypeException |
|
| 291 | + * @throws EE_Error |
|
| 292 | + */ |
|
| 293 | + public function activate_a_payment_method_of_type($payment_method_type) |
|
| 294 | + { |
|
| 295 | + $this->maybe_register_payment_methods(); |
|
| 296 | + $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type); |
|
| 297 | + if (! $payment_method instanceof EE_Payment_Method) { |
|
| 298 | + $pm_type_class = $this->payment_method_class_from_type($payment_method_type); |
|
| 299 | + if (class_exists($pm_type_class)) { |
|
| 300 | + /** @var $pm_type_obj EE_PMT_Base */ |
|
| 301 | + $pm_type_obj = new $pm_type_class; |
|
| 302 | + $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name()); |
|
| 303 | + if (! $payment_method) { |
|
| 304 | + $payment_method = $this->create_payment_method_of_type($pm_type_obj); |
|
| 305 | + } |
|
| 306 | + $payment_method->set_type($payment_method_type); |
|
| 307 | + $this->initialize_payment_method($payment_method); |
|
| 308 | + } else { |
|
| 309 | + throw new EE_Error( |
|
| 310 | + sprintf( |
|
| 311 | + esc_html__( |
|
| 312 | + 'There is no payment method of type %1$s, so it could not be activated', |
|
| 313 | + 'event_espresso' |
|
| 314 | + ), |
|
| 315 | + $pm_type_class |
|
| 316 | + ) |
|
| 317 | + ); |
|
| 318 | + } |
|
| 319 | + } |
|
| 320 | + $payment_method->set_active(); |
|
| 321 | + $payment_method->save(); |
|
| 322 | + /** @type EE_Message_Resource_Manager $message_resource_manager */ |
|
| 323 | + // if this was the invoice message type, make sure users can view their invoices |
|
| 324 | + if ($payment_method->type() === 'Invoice' |
|
| 325 | + && ( |
|
| 326 | + ! EEH_MSG_Template::is_mt_active('invoice') |
|
| 327 | + ) |
|
| 328 | + ) { |
|
| 329 | + $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager'); |
|
| 330 | + /** @type EE_Message_Resource_Manager $message_resource_manager */ |
|
| 331 | + $message_resource_manager->ensure_message_type_is_active('invoice', 'html'); |
|
| 332 | + new PersistentAdminNotice( |
|
| 333 | + 'invoice_pm_requirements_notice', |
|
| 334 | + sprintf( |
|
| 335 | + esc_html__( |
|
| 336 | + 'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.', |
|
| 337 | + 'event_espresso' |
|
| 338 | + ), |
|
| 339 | + '<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">', |
|
| 340 | + '</a>' |
|
| 341 | + ), |
|
| 342 | + true |
|
| 343 | + ); |
|
| 344 | + } |
|
| 345 | + return $payment_method; |
|
| 346 | + } |
|
| 347 | + |
|
| 348 | + |
|
| 349 | + /** |
|
| 350 | + * Creates a payment method of the specified type. Does not save it. |
|
| 351 | + * |
|
| 352 | + * @global WP_User $current_user |
|
| 353 | + * @param EE_PMT_Base $pm_type_obj |
|
| 354 | + * @return EE_Payment_Method |
|
| 355 | + * @throws EE_Error |
|
| 356 | + */ |
|
| 357 | + public function create_payment_method_of_type($pm_type_obj) |
|
| 358 | + { |
|
| 359 | + global $current_user; |
|
| 360 | + $payment_method = EE_Payment_Method::new_instance( |
|
| 361 | + array( |
|
| 362 | + 'PMD_type' => $pm_type_obj->system_name(), |
|
| 363 | + 'PMD_name' => $pm_type_obj->defaultFrontendName(), |
|
| 364 | + 'PMD_admin_name' => $pm_type_obj->pretty_name(), |
|
| 365 | + 'PMD_slug' => $pm_type_obj->system_name(),// automatically converted to slug |
|
| 366 | + 'PMD_wp_user' => $current_user->ID, |
|
| 367 | + 'PMD_order' => EEM_Payment_Method::instance()->count( |
|
| 368 | + array(array('PMD_type' => array('!=', 'Admin_Only'))) |
|
| 369 | + ) * 10, |
|
| 370 | + ) |
|
| 371 | + ); |
|
| 372 | + return $payment_method; |
|
| 373 | + } |
|
| 374 | + |
|
| 375 | + |
|
| 376 | + /** |
|
| 377 | + * Sets the initial payment method properties (including extra meta) |
|
| 378 | + * |
|
| 379 | + * @param EE_Payment_Method $payment_method |
|
| 380 | + * @return EE_Payment_Method |
|
| 381 | + * @throws EE_Error |
|
| 382 | + */ |
|
| 383 | + public function initialize_payment_method($payment_method) |
|
| 384 | + { |
|
| 385 | + $pm_type_obj = $payment_method->type_obj(); |
|
| 386 | + $payment_method->set_description($pm_type_obj->default_description()); |
|
| 387 | + if (! $payment_method->button_url()) { |
|
| 388 | + $payment_method->set_button_url($pm_type_obj->default_button_url()); |
|
| 389 | + } |
|
| 390 | + // now add setup its default extra meta properties |
|
| 391 | + $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs(); |
|
| 392 | + if (! empty($extra_metas)) { |
|
| 393 | + // verify the payment method has an ID before adding extra meta |
|
| 394 | + if (! $payment_method->ID()) { |
|
| 395 | + $payment_method->save(); |
|
| 396 | + } |
|
| 397 | + foreach ($extra_metas as $meta_name => $input) { |
|
| 398 | + $payment_method->update_extra_meta($meta_name, $input->raw_value()); |
|
| 399 | + } |
|
| 400 | + } |
|
| 401 | + return $payment_method; |
|
| 402 | + } |
|
| 403 | + |
|
| 404 | + |
|
| 405 | + /** |
|
| 406 | + * Makes sure the payment method is related to the specified payment method |
|
| 407 | + * |
|
| 408 | + * @deprecated in 4.9.40 because the currency payment method table is being deprecated |
|
| 409 | + * @param EE_Payment_Method $payment_method |
|
| 410 | + * @return EE_Payment_Method |
|
| 411 | + * @throws EE_Error |
|
| 412 | + */ |
|
| 413 | + public function set_usable_currencies_on_payment_method($payment_method) |
|
| 414 | + { |
|
| 415 | + EE_Error::doing_it_wrong( |
|
| 416 | + 'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method', |
|
| 417 | + esc_html__( |
|
| 418 | + 'We no longer define what currencies are usable by payment methods. Its not used nor efficient.', |
|
| 419 | + 'event_espresso' |
|
| 420 | + ), |
|
| 421 | + '4.9.40' |
|
| 422 | + ); |
|
| 423 | + return $payment_method; |
|
| 424 | + } |
|
| 425 | + |
|
| 426 | + |
|
| 427 | + /** |
|
| 428 | + * Deactivates a payment method of the given payment method slug. |
|
| 429 | + * |
|
| 430 | + * @param string $payment_method_slug The slug for the payment method to deactivate. |
|
| 431 | + * @return int count of rows updated. |
|
| 432 | + * @throws EE_Error |
|
| 433 | + */ |
|
| 434 | + public function deactivate_payment_method($payment_method_slug) |
|
| 435 | + { |
|
| 436 | + EE_Log::instance()->log( |
|
| 437 | + __FILE__, |
|
| 438 | + __FUNCTION__, |
|
| 439 | + sprintf( |
|
| 440 | + esc_html__( |
|
| 441 | + 'Payment method with slug %1$s is being deactivated by site admin', |
|
| 442 | + 'event_espresso' |
|
| 443 | + ), |
|
| 444 | + $payment_method_slug |
|
| 445 | + ), |
|
| 446 | + 'payment_method_change' |
|
| 447 | + ); |
|
| 448 | + $count_updated = EEM_Payment_Method::instance()->update( |
|
| 449 | + array('PMD_scope' => array()), |
|
| 450 | + array(array('PMD_slug' => $payment_method_slug)) |
|
| 451 | + ); |
|
| 452 | + do_action( |
|
| 453 | + 'AHEE__EE_Payment_Method_Manager__deactivate_payment_method__after_deactivating_payment_method', |
|
| 454 | + $payment_method_slug, |
|
| 455 | + $count_updated |
|
| 456 | + ); |
|
| 457 | + return $count_updated; |
|
| 458 | + } |
|
| 459 | + |
|
| 460 | + |
|
| 461 | + /** |
|
| 462 | + * initializes payment method access caps via EE_Capabilities::init_role_caps() |
|
| 463 | + * upon EE_Payment_Method_Manager construction |
|
| 464 | + * |
|
| 465 | + * @throws EE_Error |
|
| 466 | + * @throws DomainException |
|
| 467 | + */ |
|
| 468 | + protected function initializePaymentMethodCaps() |
|
| 469 | + { |
|
| 470 | + // don't do this twice |
|
| 471 | + if ($this->payment_method_caps_initialized) { |
|
| 472 | + return; |
|
| 473 | + } |
|
| 474 | + EE_Capabilities::instance()->addCaps( |
|
| 475 | + $this->getPaymentMethodCaps() |
|
| 476 | + ); |
|
| 477 | + $this->payment_method_caps_initialized = true; |
|
| 478 | + } |
|
| 479 | + |
|
| 480 | + |
|
| 481 | + /** |
|
| 482 | + * array of dynamic payment method access caps. |
|
| 483 | + * at the time of writing, october 20 2014, these are the caps added: |
|
| 484 | + * ee_payment_method_admin_only |
|
| 485 | + * ee_payment_method_aim |
|
| 486 | + * ee_payment_method_bank |
|
| 487 | + * ee_payment_method_check |
|
| 488 | + * ee_payment_method_invoice |
|
| 489 | + * ee_payment_method_mijireh |
|
| 490 | + * ee_payment_method_paypal_pro |
|
| 491 | + * ee_payment_method_paypal_standard |
|
| 492 | + * Any other payment methods added to core or via addons will also get |
|
| 493 | + * their related capability automatically added too, so long as they are |
|
| 494 | + * registered properly using EE_Register_Payment_Method::register() |
|
| 495 | + * |
|
| 496 | + * @return array |
|
| 497 | + * @throws DomainException |
|
| 498 | + */ |
|
| 499 | + protected function getPaymentMethodCaps() |
|
| 500 | + { |
|
| 501 | + $caps = array(); |
|
| 502 | + foreach ($this->payment_method_type_names() as $payment_method_name) { |
|
| 503 | + $caps = $this->addPaymentMethodCap($payment_method_name, $caps); |
|
| 504 | + } |
|
| 505 | + return $caps; |
|
| 506 | + } |
|
| 507 | + |
|
| 508 | + |
|
| 509 | + /** |
|
| 510 | + * @param string $payment_method_name |
|
| 511 | + * @param array $payment_method_caps |
|
| 512 | + * @param string $role |
|
| 513 | + * @return array |
|
| 514 | + * @throws DomainException |
|
| 515 | + */ |
|
| 516 | + public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator') |
|
| 517 | + { |
|
| 518 | + if (empty($payment_method_name)) { |
|
| 519 | + throw new DomainException( |
|
| 520 | + esc_html__( |
|
| 521 | + 'The name of a payment method must be specified to add capabilities.', |
|
| 522 | + 'event_espresso' |
|
| 523 | + ) |
|
| 524 | + ); |
|
| 525 | + } |
|
| 526 | + if (empty($role)) { |
|
| 527 | + throw new DomainException( |
|
| 528 | + sprintf( |
|
| 529 | + esc_html__( |
|
| 530 | + 'No role was supplied while trying to add capabilities for the %1$s payment method.', |
|
| 531 | + 'event_espresso' |
|
| 532 | + ), |
|
| 533 | + $payment_method_name |
|
| 534 | + ) |
|
| 535 | + ); |
|
| 536 | + } |
|
| 537 | + if (! isset($payment_method_caps[ $role ])) { |
|
| 538 | + $payment_method_caps[ $role ] = array(); |
|
| 539 | + } |
|
| 540 | + $payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX |
|
| 541 | + . strtolower($payment_method_name); |
|
| 542 | + return $payment_method_caps; |
|
| 543 | + } |
|
| 544 | + |
|
| 545 | + |
|
| 546 | + /** |
|
| 547 | + * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter |
|
| 548 | + * to add dynamic payment method access caps when capabilities are reset |
|
| 549 | + * (or if that filter is called and PM caps are not already set) |
|
| 550 | + * |
|
| 551 | + * @param array $caps capabilities being filtered |
|
| 552 | + * @param bool $reset |
|
| 553 | + * @return array |
|
| 554 | + * @throws DomainException |
|
| 555 | + */ |
|
| 556 | + public function addPaymentMethodCapsDuringReset(array $caps, $reset = false) |
|
| 557 | + { |
|
| 558 | + if ($reset || ! $this->payment_method_caps_initialized) { |
|
| 559 | + $this->payment_method_caps_initialized = true; |
|
| 560 | + $caps = array_merge_recursive($caps, $this->getPaymentMethodCaps()); |
|
| 561 | + } |
|
| 562 | + return $caps; |
|
| 563 | + } |
|
| 564 | + |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * @deprecated 4.9.42 |
|
| 568 | + * @param $caps |
|
| 569 | + * @return mixed |
|
| 570 | + */ |
|
| 571 | + public function add_payment_method_caps($caps) |
|
| 572 | + { |
|
| 573 | + return $caps; |
|
| 574 | + } |
|
| 575 | 575 | } |
@@ -74,7 +74,7 @@ discard block |
||
| 74 | 74 | public static function instance() |
| 75 | 75 | { |
| 76 | 76 | // check if class object is instantiated, and instantiated properly |
| 77 | - if (! self::$_instance instanceof EE_Payment_Method_Manager) { |
|
| 77 | + if ( ! self::$_instance instanceof EE_Payment_Method_Manager) { |
|
| 78 | 78 | EE_Registry::instance()->load_lib('PMT_Base'); |
| 79 | 79 | self::$_instance = new self(); |
| 80 | 80 | } |
@@ -105,7 +105,7 @@ discard block |
||
| 105 | 105 | */ |
| 106 | 106 | public function maybe_register_payment_methods($force_recheck = false) |
| 107 | 107 | { |
| 108 | - if (! $this->_payment_method_types || $force_recheck) { |
|
| 108 | + if ( ! $this->_payment_method_types || $force_recheck) { |
|
| 109 | 109 | $this->_register_payment_methods(); |
| 110 | 110 | } |
| 111 | 111 | } |
@@ -119,7 +119,7 @@ discard block |
||
| 119 | 119 | protected function _register_payment_methods() |
| 120 | 120 | { |
| 121 | 121 | // grab list of installed modules |
| 122 | - $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR); |
|
| 122 | + $pm_to_register = glob(EE_PAYMENT_METHODS.'*', GLOB_ONLYDIR); |
|
| 123 | 123 | // filter list of modules to register |
| 124 | 124 | $pm_to_register = apply_filters( |
| 125 | 125 | 'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register', |
@@ -159,9 +159,9 @@ discard block |
||
| 159 | 159 | // create class name from module directory name |
| 160 | 160 | $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir); |
| 161 | 161 | // add class prefix |
| 162 | - $module_class = 'EE_PMT_' . $module; |
|
| 162 | + $module_class = 'EE_PMT_'.$module; |
|
| 163 | 163 | // does the module exist ? |
| 164 | - if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) { |
|
| 164 | + if ( ! is_readable($payment_method_path.'/'.$module_class.$module_ext)) { |
|
| 165 | 165 | $msg = sprintf( |
| 166 | 166 | esc_html__( |
| 167 | 167 | 'The requested %s payment method file could not be found or is not readable due to file permissions.', |
@@ -169,22 +169,22 @@ discard block |
||
| 169 | 169 | ), |
| 170 | 170 | $module |
| 171 | 171 | ); |
| 172 | - EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 172 | + EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 173 | 173 | return false; |
| 174 | 174 | } |
| 175 | 175 | // load the module class file |
| 176 | - require_once($payment_method_path . '/' . $module_class . $module_ext); |
|
| 176 | + require_once($payment_method_path.'/'.$module_class.$module_ext); |
|
| 177 | 177 | // verify that class exists |
| 178 | - if (! class_exists($module_class)) { |
|
| 178 | + if ( ! class_exists($module_class)) { |
|
| 179 | 179 | $msg = sprintf( |
| 180 | 180 | esc_html__('The requested %s module class does not exist.', 'event_espresso'), |
| 181 | 181 | $module_class |
| 182 | 182 | ); |
| 183 | - EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 183 | + EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__); |
|
| 184 | 184 | return false; |
| 185 | 185 | } |
| 186 | 186 | // add to array of registered modules |
| 187 | - $this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext; |
|
| 187 | + $this->_payment_method_types[$module] = $payment_method_path.'/'.$module_class.$module_ext; |
|
| 188 | 188 | ksort($this->_payment_method_types); |
| 189 | 189 | return true; |
| 190 | 190 | } |
@@ -201,12 +201,12 @@ discard block |
||
| 201 | 201 | { |
| 202 | 202 | if ($force_recheck |
| 203 | 203 | || ! is_array($this->_payment_method_types) |
| 204 | - || ! isset($this->_payment_method_types[ $payment_method_name ]) |
|
| 204 | + || ! isset($this->_payment_method_types[$payment_method_name]) |
|
| 205 | 205 | ) { |
| 206 | 206 | $this->maybe_register_payment_methods($force_recheck); |
| 207 | 207 | } |
| 208 | - if (isset($this->_payment_method_types[ $payment_method_name ])) { |
|
| 209 | - require_once($this->_payment_method_types[ $payment_method_name ]); |
|
| 208 | + if (isset($this->_payment_method_types[$payment_method_name])) { |
|
| 209 | + require_once($this->_payment_method_types[$payment_method_name]); |
|
| 210 | 210 | return true; |
| 211 | 211 | } |
| 212 | 212 | return false; |
@@ -248,8 +248,8 @@ discard block |
||
| 248 | 248 | if ($force_recheck || empty($this->payment_method_objects)) { |
| 249 | 249 | $this->maybe_register_payment_methods($force_recheck); |
| 250 | 250 | foreach ($this->payment_method_type_names(true) as $classname) { |
| 251 | - if (! isset($this->payment_method_objects[ $classname ])) { |
|
| 252 | - $this->payment_method_objects[ $classname ] = new $classname; |
|
| 251 | + if ( ! isset($this->payment_method_objects[$classname])) { |
|
| 252 | + $this->payment_method_objects[$classname] = new $classname; |
|
| 253 | 253 | } |
| 254 | 254 | } |
| 255 | 255 | } |
@@ -278,7 +278,7 @@ discard block |
||
| 278 | 278 | */ |
| 279 | 279 | public function payment_method_class_from_type($type) |
| 280 | 280 | { |
| 281 | - return 'EE_PMT_' . $type; |
|
| 281 | + return 'EE_PMT_'.$type; |
|
| 282 | 282 | } |
| 283 | 283 | |
| 284 | 284 | |
@@ -294,13 +294,13 @@ discard block |
||
| 294 | 294 | { |
| 295 | 295 | $this->maybe_register_payment_methods(); |
| 296 | 296 | $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type); |
| 297 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
| 297 | + if ( ! $payment_method instanceof EE_Payment_Method) { |
|
| 298 | 298 | $pm_type_class = $this->payment_method_class_from_type($payment_method_type); |
| 299 | 299 | if (class_exists($pm_type_class)) { |
| 300 | 300 | /** @var $pm_type_obj EE_PMT_Base */ |
| 301 | 301 | $pm_type_obj = new $pm_type_class; |
| 302 | 302 | $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name()); |
| 303 | - if (! $payment_method) { |
|
| 303 | + if ( ! $payment_method) { |
|
| 304 | 304 | $payment_method = $this->create_payment_method_of_type($pm_type_obj); |
| 305 | 305 | } |
| 306 | 306 | $payment_method->set_type($payment_method_type); |
@@ -336,7 +336,7 @@ discard block |
||
| 336 | 336 | 'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.', |
| 337 | 337 | 'event_espresso' |
| 338 | 338 | ), |
| 339 | - '<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">', |
|
| 339 | + '<a href="'.admin_url('admin.php?page=espresso_messages&action=settings').'">', |
|
| 340 | 340 | '</a>' |
| 341 | 341 | ), |
| 342 | 342 | true |
@@ -362,7 +362,7 @@ discard block |
||
| 362 | 362 | 'PMD_type' => $pm_type_obj->system_name(), |
| 363 | 363 | 'PMD_name' => $pm_type_obj->defaultFrontendName(), |
| 364 | 364 | 'PMD_admin_name' => $pm_type_obj->pretty_name(), |
| 365 | - 'PMD_slug' => $pm_type_obj->system_name(),// automatically converted to slug |
|
| 365 | + 'PMD_slug' => $pm_type_obj->system_name(), // automatically converted to slug |
|
| 366 | 366 | 'PMD_wp_user' => $current_user->ID, |
| 367 | 367 | 'PMD_order' => EEM_Payment_Method::instance()->count( |
| 368 | 368 | array(array('PMD_type' => array('!=', 'Admin_Only'))) |
@@ -384,14 +384,14 @@ discard block |
||
| 384 | 384 | { |
| 385 | 385 | $pm_type_obj = $payment_method->type_obj(); |
| 386 | 386 | $payment_method->set_description($pm_type_obj->default_description()); |
| 387 | - if (! $payment_method->button_url()) { |
|
| 387 | + if ( ! $payment_method->button_url()) { |
|
| 388 | 388 | $payment_method->set_button_url($pm_type_obj->default_button_url()); |
| 389 | 389 | } |
| 390 | 390 | // now add setup its default extra meta properties |
| 391 | 391 | $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs(); |
| 392 | - if (! empty($extra_metas)) { |
|
| 392 | + if ( ! empty($extra_metas)) { |
|
| 393 | 393 | // verify the payment method has an ID before adding extra meta |
| 394 | - if (! $payment_method->ID()) { |
|
| 394 | + if ( ! $payment_method->ID()) { |
|
| 395 | 395 | $payment_method->save(); |
| 396 | 396 | } |
| 397 | 397 | foreach ($extra_metas as $meta_name => $input) { |
@@ -534,10 +534,10 @@ discard block |
||
| 534 | 534 | ) |
| 535 | 535 | ); |
| 536 | 536 | } |
| 537 | - if (! isset($payment_method_caps[ $role ])) { |
|
| 538 | - $payment_method_caps[ $role ] = array(); |
|
| 537 | + if ( ! isset($payment_method_caps[$role])) { |
|
| 538 | + $payment_method_caps[$role] = array(); |
|
| 539 | 539 | } |
| 540 | - $payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX |
|
| 540 | + $payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX |
|
| 541 | 541 | . strtolower($payment_method_name); |
| 542 | 542 | return $payment_method_caps; |
| 543 | 543 | } |
@@ -16,127 +16,127 @@ |
||
| 16 | 16 | |
| 17 | 17 | |
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * @type EE_Messenger_Collection $_messenger_collection |
|
| 21 | - */ |
|
| 22 | - protected $_messenger_collection = null; |
|
| 23 | - |
|
| 24 | - |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * EE_Messenger_Collection_Loader constructor. |
|
| 28 | - * |
|
| 29 | - * @param EE_Messenger_Collection $messengers |
|
| 30 | - */ |
|
| 31 | - public function __construct(EE_Messenger_Collection $messengers) |
|
| 32 | - { |
|
| 33 | - $this->set_messenger_collection($messengers); |
|
| 34 | - } |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * @return EE_Messenger_Collection |
|
| 40 | - */ |
|
| 41 | - public function messenger_collection() |
|
| 42 | - { |
|
| 43 | - return $this->_messenger_collection; |
|
| 44 | - } |
|
| 45 | - |
|
| 46 | - |
|
| 47 | - |
|
| 48 | - /** |
|
| 49 | - * @param mixed $messengers |
|
| 50 | - */ |
|
| 51 | - public function set_messenger_collection(EE_Messenger_Collection $messengers) |
|
| 52 | - { |
|
| 53 | - $this->_messenger_collection = $messengers; |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * load_messengers |
|
| 60 | - * globs the supplied filepath and adds any found |
|
| 61 | - * |
|
| 62 | - * @param string $folder |
|
| 63 | - * @throws \EE_Error |
|
| 64 | - */ |
|
| 65 | - public function load_messengers_from_folder($folder = '') |
|
| 66 | - { |
|
| 67 | - // make sure autoloaders are set (fail-safe) |
|
| 68 | - EED_Messages::set_autoloaders(); |
|
| 69 | - $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/messenger'; |
|
| 70 | - $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 71 | - // get all the files in that folder that end in ".class.php |
|
| 72 | - $filepaths = apply_filters( |
|
| 73 | - 'FHEE__EE_messages__get_installed__messenger_files', |
|
| 74 | - glob($folder . '*.class.php') |
|
| 75 | - ); |
|
| 76 | - if (empty($filepaths)) { |
|
| 77 | - return; |
|
| 78 | - } |
|
| 79 | - foreach ((array) $filepaths as $file_path) { |
|
| 80 | - // extract filename from path |
|
| 81 | - $file_path = basename($file_path); |
|
| 82 | - // now remove any file extensions |
|
| 83 | - $messenger_class_name = substr($file_path, 0, strpos($file_path, '.')); |
|
| 84 | - |
|
| 85 | - // first check to see if the class name represents an actual messenger class. |
|
| 86 | - if (strpos(strtolower($messenger_class_name), 'messenger') === false) { |
|
| 87 | - continue; |
|
| 88 | - } |
|
| 89 | - |
|
| 90 | - if (! class_exists($messenger_class_name)) { |
|
| 91 | - throw new EE_Error( |
|
| 92 | - sprintf( |
|
| 93 | - __('The "%1$s" messenger class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |
|
| 94 | - $messenger_class_name, |
|
| 95 | - $file_path |
|
| 96 | - ) |
|
| 97 | - ); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - $this->_load_messenger(new $messenger_class_name()); |
|
| 101 | - } |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - |
|
| 105 | - /** |
|
| 106 | - * load_messengers |
|
| 107 | - * globs the supplied filepath and adds any found |
|
| 108 | - * |
|
| 109 | - * @return array |
|
| 110 | - */ |
|
| 111 | - public function load_active_messengers_from_db() |
|
| 112 | - { |
|
| 113 | - // make sure autoloaders are set (fail-safe) |
|
| 114 | - EED_Messages::set_autoloaders(); |
|
| 115 | - $active_messengers = apply_filters( |
|
| 116 | - 'FHEE__EEH_MSG_Template__get_active_messengers_in_db', |
|
| 117 | - get_option('ee_active_messengers', array()) |
|
| 118 | - ); |
|
| 119 | - foreach ((array) $active_messengers as $active_messenger_classname => $active_messenger) { |
|
| 120 | - $this->_load_messenger($active_messenger); |
|
| 121 | - } |
|
| 122 | - } |
|
| 123 | - |
|
| 124 | - |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * load_messenger |
|
| 128 | - * |
|
| 129 | - * @param \EE_messenger $messenger |
|
| 130 | - * @return bool |
|
| 131 | - */ |
|
| 132 | - protected function _load_messenger(EE_messenger $messenger) |
|
| 133 | - { |
|
| 134 | - if ($this->messenger_collection()->has_by_name($messenger->name)) { |
|
| 135 | - return true; |
|
| 136 | - } |
|
| 137 | - return $this->messenger_collection()->add( |
|
| 138 | - $messenger, |
|
| 139 | - $messenger->name |
|
| 140 | - ); |
|
| 141 | - } |
|
| 19 | + /** |
|
| 20 | + * @type EE_Messenger_Collection $_messenger_collection |
|
| 21 | + */ |
|
| 22 | + protected $_messenger_collection = null; |
|
| 23 | + |
|
| 24 | + |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * EE_Messenger_Collection_Loader constructor. |
|
| 28 | + * |
|
| 29 | + * @param EE_Messenger_Collection $messengers |
|
| 30 | + */ |
|
| 31 | + public function __construct(EE_Messenger_Collection $messengers) |
|
| 32 | + { |
|
| 33 | + $this->set_messenger_collection($messengers); |
|
| 34 | + } |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * @return EE_Messenger_Collection |
|
| 40 | + */ |
|
| 41 | + public function messenger_collection() |
|
| 42 | + { |
|
| 43 | + return $this->_messenger_collection; |
|
| 44 | + } |
|
| 45 | + |
|
| 46 | + |
|
| 47 | + |
|
| 48 | + /** |
|
| 49 | + * @param mixed $messengers |
|
| 50 | + */ |
|
| 51 | + public function set_messenger_collection(EE_Messenger_Collection $messengers) |
|
| 52 | + { |
|
| 53 | + $this->_messenger_collection = $messengers; |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * load_messengers |
|
| 60 | + * globs the supplied filepath and adds any found |
|
| 61 | + * |
|
| 62 | + * @param string $folder |
|
| 63 | + * @throws \EE_Error |
|
| 64 | + */ |
|
| 65 | + public function load_messengers_from_folder($folder = '') |
|
| 66 | + { |
|
| 67 | + // make sure autoloaders are set (fail-safe) |
|
| 68 | + EED_Messages::set_autoloaders(); |
|
| 69 | + $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/messenger'; |
|
| 70 | + $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 71 | + // get all the files in that folder that end in ".class.php |
|
| 72 | + $filepaths = apply_filters( |
|
| 73 | + 'FHEE__EE_messages__get_installed__messenger_files', |
|
| 74 | + glob($folder . '*.class.php') |
|
| 75 | + ); |
|
| 76 | + if (empty($filepaths)) { |
|
| 77 | + return; |
|
| 78 | + } |
|
| 79 | + foreach ((array) $filepaths as $file_path) { |
|
| 80 | + // extract filename from path |
|
| 81 | + $file_path = basename($file_path); |
|
| 82 | + // now remove any file extensions |
|
| 83 | + $messenger_class_name = substr($file_path, 0, strpos($file_path, '.')); |
|
| 84 | + |
|
| 85 | + // first check to see if the class name represents an actual messenger class. |
|
| 86 | + if (strpos(strtolower($messenger_class_name), 'messenger') === false) { |
|
| 87 | + continue; |
|
| 88 | + } |
|
| 89 | + |
|
| 90 | + if (! class_exists($messenger_class_name)) { |
|
| 91 | + throw new EE_Error( |
|
| 92 | + sprintf( |
|
| 93 | + __('The "%1$s" messenger class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |
|
| 94 | + $messenger_class_name, |
|
| 95 | + $file_path |
|
| 96 | + ) |
|
| 97 | + ); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + $this->_load_messenger(new $messenger_class_name()); |
|
| 101 | + } |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + |
|
| 105 | + /** |
|
| 106 | + * load_messengers |
|
| 107 | + * globs the supplied filepath and adds any found |
|
| 108 | + * |
|
| 109 | + * @return array |
|
| 110 | + */ |
|
| 111 | + public function load_active_messengers_from_db() |
|
| 112 | + { |
|
| 113 | + // make sure autoloaders are set (fail-safe) |
|
| 114 | + EED_Messages::set_autoloaders(); |
|
| 115 | + $active_messengers = apply_filters( |
|
| 116 | + 'FHEE__EEH_MSG_Template__get_active_messengers_in_db', |
|
| 117 | + get_option('ee_active_messengers', array()) |
|
| 118 | + ); |
|
| 119 | + foreach ((array) $active_messengers as $active_messenger_classname => $active_messenger) { |
|
| 120 | + $this->_load_messenger($active_messenger); |
|
| 121 | + } |
|
| 122 | + } |
|
| 123 | + |
|
| 124 | + |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * load_messenger |
|
| 128 | + * |
|
| 129 | + * @param \EE_messenger $messenger |
|
| 130 | + * @return bool |
|
| 131 | + */ |
|
| 132 | + protected function _load_messenger(EE_messenger $messenger) |
|
| 133 | + { |
|
| 134 | + if ($this->messenger_collection()->has_by_name($messenger->name)) { |
|
| 135 | + return true; |
|
| 136 | + } |
|
| 137 | + return $this->messenger_collection()->add( |
|
| 138 | + $messenger, |
|
| 139 | + $messenger->name |
|
| 140 | + ); |
|
| 141 | + } |
|
| 142 | 142 | } |
@@ -66,12 +66,12 @@ discard block |
||
| 66 | 66 | { |
| 67 | 67 | // make sure autoloaders are set (fail-safe) |
| 68 | 68 | EED_Messages::set_autoloaders(); |
| 69 | - $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/messenger'; |
|
| 70 | - $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 69 | + $folder = ! empty($folder) ? $folder : EE_LIBRARIES.'messages/messenger'; |
|
| 70 | + $folder .= $folder[strlen($folder) - 1] != '/' ? '/' : ''; |
|
| 71 | 71 | // get all the files in that folder that end in ".class.php |
| 72 | 72 | $filepaths = apply_filters( |
| 73 | 73 | 'FHEE__EE_messages__get_installed__messenger_files', |
| 74 | - glob($folder . '*.class.php') |
|
| 74 | + glob($folder.'*.class.php') |
|
| 75 | 75 | ); |
| 76 | 76 | if (empty($filepaths)) { |
| 77 | 77 | return; |
@@ -87,7 +87,7 @@ discard block |
||
| 87 | 87 | continue; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | - if (! class_exists($messenger_class_name)) { |
|
| 90 | + if ( ! class_exists($messenger_class_name)) { |
|
| 91 | 91 | throw new EE_Error( |
| 92 | 92 | sprintf( |
| 93 | 93 | __('The "%1$s" messenger class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |
@@ -15,105 +15,105 @@ |
||
| 15 | 15 | { |
| 16 | 16 | |
| 17 | 17 | |
| 18 | - /** |
|
| 19 | - * @type EE_Message_Type_Collection $_message_type_collection |
|
| 20 | - */ |
|
| 21 | - protected $_message_type_collection = null; |
|
| 22 | - |
|
| 23 | - |
|
| 24 | - |
|
| 25 | - /** |
|
| 26 | - * EE_Message_Type_Collection_Loader constructor. |
|
| 27 | - * |
|
| 28 | - * @param EE_Message_Type_Collection $message_types |
|
| 29 | - */ |
|
| 30 | - public function __construct(EE_Message_Type_Collection $message_types) |
|
| 31 | - { |
|
| 32 | - $this->set_message_type_collection($message_types); |
|
| 33 | - } |
|
| 34 | - |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * @return EE_Message_Type_Collection |
|
| 39 | - */ |
|
| 40 | - public function message_type_collection() |
|
| 41 | - { |
|
| 42 | - return $this->_message_type_collection; |
|
| 43 | - } |
|
| 44 | - |
|
| 45 | - |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * @param mixed $message_types |
|
| 49 | - */ |
|
| 50 | - public function set_message_type_collection(EE_Message_Type_Collection $message_types) |
|
| 51 | - { |
|
| 52 | - $this->_message_type_collection = $message_types; |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - |
|
| 56 | - |
|
| 57 | - /** |
|
| 58 | - * load_message_types |
|
| 59 | - * globs the supplied filepath and adds any found |
|
| 60 | - * |
|
| 61 | - * @param string $folder |
|
| 62 | - * @throws \EE_Error |
|
| 63 | - */ |
|
| 64 | - public function load_message_types_from_folder($folder = '') |
|
| 65 | - { |
|
| 66 | - // make sure autoloaders are set (fail-safe) |
|
| 67 | - EED_Messages::set_autoloaders(); |
|
| 68 | - $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/message_type'; |
|
| 69 | - $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 70 | - // get all the files in that folder that end in ".class.php |
|
| 71 | - $filepaths = apply_filters( |
|
| 72 | - 'FHEE__EE_messages__get_installed__messagetype_files', |
|
| 73 | - glob($folder . '*.class.php') |
|
| 74 | - ); |
|
| 75 | - if (empty($filepaths)) { |
|
| 76 | - return; |
|
| 77 | - } |
|
| 78 | - foreach ((array) $filepaths as $file_path) { |
|
| 79 | - // extract filename from path |
|
| 80 | - $file_path = basename($file_path); |
|
| 81 | - // now remove any file extensions |
|
| 82 | - $message_type_class_name = substr($file_path, 0, strpos($file_path, '.')); |
|
| 83 | - |
|
| 84 | - // if this class name doesn't represent a message type class, then we just skip. |
|
| 85 | - if (strpos(strtolower($message_type_class_name), 'message_type') === false) { |
|
| 86 | - continue; |
|
| 87 | - } |
|
| 88 | - |
|
| 89 | - if (! class_exists($message_type_class_name)) { |
|
| 90 | - throw new EE_Error( |
|
| 91 | - sprintf( |
|
| 92 | - __('The "%1$s" message type class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |
|
| 93 | - $message_type_class_name, |
|
| 94 | - $file_path |
|
| 95 | - ) |
|
| 96 | - ); |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - $this->_load_message_type(new $message_type_class_name); |
|
| 100 | - } |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - |
|
| 104 | - /** |
|
| 105 | - * Loads the given message type into the message type collection if it doesn't already exist. |
|
| 106 | - * @param EE_message_type $message_type |
|
| 107 | - * @return bool |
|
| 108 | - */ |
|
| 109 | - protected function _load_message_type(EE_message_type $message_type) |
|
| 110 | - { |
|
| 111 | - if ($this->message_type_collection()->has_by_name($message_type->name)) { |
|
| 112 | - return true; |
|
| 113 | - } |
|
| 114 | - return $this->message_type_collection()->add( |
|
| 115 | - $message_type, |
|
| 116 | - $message_type->name |
|
| 117 | - ); |
|
| 118 | - } |
|
| 18 | + /** |
|
| 19 | + * @type EE_Message_Type_Collection $_message_type_collection |
|
| 20 | + */ |
|
| 21 | + protected $_message_type_collection = null; |
|
| 22 | + |
|
| 23 | + |
|
| 24 | + |
|
| 25 | + /** |
|
| 26 | + * EE_Message_Type_Collection_Loader constructor. |
|
| 27 | + * |
|
| 28 | + * @param EE_Message_Type_Collection $message_types |
|
| 29 | + */ |
|
| 30 | + public function __construct(EE_Message_Type_Collection $message_types) |
|
| 31 | + { |
|
| 32 | + $this->set_message_type_collection($message_types); |
|
| 33 | + } |
|
| 34 | + |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * @return EE_Message_Type_Collection |
|
| 39 | + */ |
|
| 40 | + public function message_type_collection() |
|
| 41 | + { |
|
| 42 | + return $this->_message_type_collection; |
|
| 43 | + } |
|
| 44 | + |
|
| 45 | + |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * @param mixed $message_types |
|
| 49 | + */ |
|
| 50 | + public function set_message_type_collection(EE_Message_Type_Collection $message_types) |
|
| 51 | + { |
|
| 52 | + $this->_message_type_collection = $message_types; |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + |
|
| 56 | + |
|
| 57 | + /** |
|
| 58 | + * load_message_types |
|
| 59 | + * globs the supplied filepath and adds any found |
|
| 60 | + * |
|
| 61 | + * @param string $folder |
|
| 62 | + * @throws \EE_Error |
|
| 63 | + */ |
|
| 64 | + public function load_message_types_from_folder($folder = '') |
|
| 65 | + { |
|
| 66 | + // make sure autoloaders are set (fail-safe) |
|
| 67 | + EED_Messages::set_autoloaders(); |
|
| 68 | + $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/message_type'; |
|
| 69 | + $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 70 | + // get all the files in that folder that end in ".class.php |
|
| 71 | + $filepaths = apply_filters( |
|
| 72 | + 'FHEE__EE_messages__get_installed__messagetype_files', |
|
| 73 | + glob($folder . '*.class.php') |
|
| 74 | + ); |
|
| 75 | + if (empty($filepaths)) { |
|
| 76 | + return; |
|
| 77 | + } |
|
| 78 | + foreach ((array) $filepaths as $file_path) { |
|
| 79 | + // extract filename from path |
|
| 80 | + $file_path = basename($file_path); |
|
| 81 | + // now remove any file extensions |
|
| 82 | + $message_type_class_name = substr($file_path, 0, strpos($file_path, '.')); |
|
| 83 | + |
|
| 84 | + // if this class name doesn't represent a message type class, then we just skip. |
|
| 85 | + if (strpos(strtolower($message_type_class_name), 'message_type') === false) { |
|
| 86 | + continue; |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + if (! class_exists($message_type_class_name)) { |
|
| 90 | + throw new EE_Error( |
|
| 91 | + sprintf( |
|
| 92 | + __('The "%1$s" message type class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |
|
| 93 | + $message_type_class_name, |
|
| 94 | + $file_path |
|
| 95 | + ) |
|
| 96 | + ); |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + $this->_load_message_type(new $message_type_class_name); |
|
| 100 | + } |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + |
|
| 104 | + /** |
|
| 105 | + * Loads the given message type into the message type collection if it doesn't already exist. |
|
| 106 | + * @param EE_message_type $message_type |
|
| 107 | + * @return bool |
|
| 108 | + */ |
|
| 109 | + protected function _load_message_type(EE_message_type $message_type) |
|
| 110 | + { |
|
| 111 | + if ($this->message_type_collection()->has_by_name($message_type->name)) { |
|
| 112 | + return true; |
|
| 113 | + } |
|
| 114 | + return $this->message_type_collection()->add( |
|
| 115 | + $message_type, |
|
| 116 | + $message_type->name |
|
| 117 | + ); |
|
| 118 | + } |
|
| 119 | 119 | } |
@@ -65,12 +65,12 @@ discard block |
||
| 65 | 65 | { |
| 66 | 66 | // make sure autoloaders are set (fail-safe) |
| 67 | 67 | EED_Messages::set_autoloaders(); |
| 68 | - $folder = ! empty($folder) ? $folder : EE_LIBRARIES . 'messages/message_type'; |
|
| 69 | - $folder .= $folder[ strlen($folder) - 1 ] != '/' ? '/' : ''; |
|
| 68 | + $folder = ! empty($folder) ? $folder : EE_LIBRARIES.'messages/message_type'; |
|
| 69 | + $folder .= $folder[strlen($folder) - 1] != '/' ? '/' : ''; |
|
| 70 | 70 | // get all the files in that folder that end in ".class.php |
| 71 | 71 | $filepaths = apply_filters( |
| 72 | 72 | 'FHEE__EE_messages__get_installed__messagetype_files', |
| 73 | - glob($folder . '*.class.php') |
|
| 73 | + glob($folder.'*.class.php') |
|
| 74 | 74 | ); |
| 75 | 75 | if (empty($filepaths)) { |
| 76 | 76 | return; |
@@ -86,7 +86,7 @@ discard block |
||
| 86 | 86 | continue; |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | - if (! class_exists($message_type_class_name)) { |
|
| 89 | + if ( ! class_exists($message_type_class_name)) { |
|
| 90 | 90 | throw new EE_Error( |
| 91 | 91 | sprintf( |
| 92 | 92 | __('The "%1$s" message type class can\'t be loaded from %2$s. Likely there is a typo in the class name or the file name.', 'event_espresso'), |