/**
  * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
  *
  * @param string 	$filepath
  * @param array 	$data 2D array, 		first numerically-indexed,
  *                    						and next-level-down preferably indexed by string
  * @param boolean 	$write_column_headers 	whether or not we should add the keys in the bottom-most array
  * 											as a row for headers in the CSV.
  *                                            Eg, if $data looked like:
  *                                            array(
  *                                              	0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...),
  * 													1=>array(...,...)
  *                                            )
  *
  * @return boolean 		if we successfully wrote to the CSV or not. If there's no $data,
  * 						we consider that a success (because we wrote everything there was...nothing)
  * @throws EE_Error
  */
 public static function write_data_array_to_csv($filepath, $data, $write_column_headers = true)
 {
     $new_file_contents = '';
     //determine if $data is actually a 2d array
     if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
         //make sure top level is numerically indexed,
         if (EEH_Array::is_associative_array($data)) {
             throw new EE_Error(sprintf(__("top-level array must be numerically indexed. Does these look like numbers to you? %s", "event_espresso"), implode(",", array_keys($data))));
         }
         $item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
         //now, is the last item in the top-level array of $data an associative or numeric array?
         if ($write_column_headers && EEH_Array::is_associative_array($item_in_top_level_array)) {
             //its associative, so we want to output its keys as column headers
             $keys = array_keys($item_in_top_level_array);
             $new_file_contents .= EEH_Export::get_csv_row($keys);
         }
         //start writing data
         foreach ($data as $data_row) {
             $new_file_contents .= EEH_Export::get_csv_row($data_row);
         }
         return EEH_File::write_to_file($filepath, EEH_File::get_file_contents($filepath) . $new_file_contents);
     } else {
         //no data TO write... so we can assume that's a success
         return true;
     }
 }
 /**
  * Creates a file
  *
  * @param string $job_id
  * @param string $filename
  * @param string $filetype
  * @return string
  * @throws \EventEspressoBatchRequest\Helpers\BatchRequestException
  */
 public function create_file_from_job_with_name($job_id, $filename, $filetype = 'application/ms-excel')
 {
     $filepath = '';
     try {
         $base_folder = $this->get_base_folder();
         $success = $this->_file_helper->ensure_folder_exists_and_is_writable($base_folder . JobHandlerFile::temp_folder_name);
         if ($success) {
             $success = $this->_file_helper->ensure_folder_exists_and_is_writable($base_folder . JobHandlerFile::temp_folder_name . DS . $job_id);
         }
         if ($success) {
             $filepath = $base_folder . JobHandlerFile::temp_folder_name . DS . $job_id . DS . $filename;
             $success = $this->_file_helper->ensure_file_exists_and_is_writable($filepath);
         }
         //let's add the .htaccess file so safari will open the file properly
         if ($success) {
             $extension = \EEH_File::get_file_extension($filepath);
             \EEH_File::write_to_file($base_folder . JobHandlerFile::temp_folder_name . DS . $job_id . DS . '.htaccess', 'AddType ' . $filetype . ' ' . $extension, '.htaccess');
         }
         //those methods normally fail with an exception, but if not, let's do it
         if (!$success) {
             throw new \EE_Error(__('Could not create temporary file, an unknown error occurred', 'event_espresso'));
         }
     } catch (\EE_Error $e) {
         throw new BatchRequestException(sprintf(__('Could not create temporary file for job %1$s, because: %2$s ', 'event_espresso'), $job_id, $e->getMessage()), 500, $e);
     }
     return $filepath;
 }
 /**
  * register method for setting up model extensions
  *
  * @param string $model_id unique id for the extensions being setup
  * @param array   $config   {
  *               @throws EE_Error
  *               @type  array $ model_extension_paths array of folders containing DB model extensions, where each file follows the models naming convention, which is: EEME_{your_plugin_slug}_model_name_extended}.model_ext.php. Where your_plugin_slug} is really anything you want (but something having to do with your addon, like 'Calendar' or '3D_View') and model_name_extended} is the model extended. The class contained in teh file should extend EEME_Base_{model_name_extended}.model_ext.php. Where {your_plugin_slug} is really anything you want (but something having to do with your addon, like 'Calendar' or '3D_View') and {model_name_extended} is the model extended. The class contained in teh file should extend EEME_Base
  *               @type array $ class_extension_paths array of folders containing DB class extensions, where each file follows the model class extension naming convention, which is: EEE_{your_plugin_slug}_model_name_extended}.class_ext.php. Where your_plugin_slug} is something like 'Calendar','MailChimp',etc, and model_name_extended} is the name of the model extended, eg 'Attendee','Event',etc. The class contained in the file should extend EEE_Base_Class._{model_name_extended}.class_ext.php. Where {your_plugin_slug} is something like 'Calendar','MailChimp',etc, and {model_name_extended} is the name of the model extended, eg 'Attendee','Event',etc. The class contained in the file should extend EEE_Base_Class.
  * }
  *
  * @return void
  */
 public static function register($model_id = NULL, $config = array())
 {
     //required fields MUST be present, so let's make sure they are.
     if (empty($model_id) || !is_array($config) || empty($config['model_extension_paths']) && empty($config['class_extension_paths'])) {
         throw new EE_Error(__('In order to register Model extensions with EE_Register_Model_Extensions::register(), you must include a "model_id" (a unique identifier for this set of models), and an array containing the following keys: "model_extension_paths" (an array of full server paths to folders that contain model extensions), and "class_extension_paths" (an array of full server paths to folders that contain class extensions)', 'event_espresso'));
     }
     //check correct loading
     if (!did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_Admin__loaded')) {
         EE_Error::doing_it_wrong(__METHOD__, sprintf(__('An attempt was made to register "%s" as a group models has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register models.', 'event_espresso'), $model_id), '4.3');
     }
     self::$_registry[$model_id] = $config;
     EE_Registry::instance()->load_helper('File');
     if (isset($config['model_extension_paths'])) {
         require_once EE_LIBRARIES . 'plugin_api/db/EEME_Base.lib.php';
         $class_to_filepath_map = EEH_File::get_contents_of_folders($config['model_extension_paths']);
         EEH_Autoloader::register_autoloader($class_to_filepath_map);
         foreach (array_keys($class_to_filepath_map) as $classname) {
             new $classname();
         }
         unset($config['model_extension_paths']);
     }
     if (isset($config['class_extension_paths'])) {
         require_once EE_LIBRARIES . 'plugin_api/db/EEE_Base_Class.lib.php';
         $class_to_filepath_map = EEH_File::get_contents_of_folders($config['class_extension_paths']);
         EEH_Autoloader::register_autoloader($class_to_filepath_map);
         foreach (array_keys($class_to_filepath_map) as $classname) {
             new $classname();
         }
         unset($config['class_extension_paths']);
     }
     foreach ($config as $unknown_key => $unknown_config) {
         throw new EE_Error(sprintf(__("The key '%s' is not a known key for registering a model", "event_espresso"), $unknown_key));
     }
 }
 /**
  * @param string $model_id unique id for it
  * @param array  $config   {
  *		@type array $model_paths array of folders containing DB models, where each file follows the models naming convention,
  *                         which is: EEM_{model_name}.model.php which contains a single class called EEM_{model_name}. Eg. you could pass
  *                         "public_html/wp-content/plugins/my_addon/db_models" (with or without trailing slash) and in that folder put
  *                         each of your model files, like "EEM_Food.model.php" which contains the class "EEM_Food" and
  *                         "EEM_Monkey.model.php" which contains the class "EEM_Monkey". These will be autoloaded and added to
  *                         the EE registry so they can be used like ordinary models. The class contained in each file should extend EEM_Base.
  *		@type array $class_paths array of folders containing DB classes, where each file follows the model class naming convention,
  *                         which is EE_{model_name}.class.php. The class contained in each file should extend EE_Base_Class
  *
  * }
  * @throws EE_Error
  */
 public static function register($model_id = NULL, $config = array())
 {
     //required fields MUST be present, so let's make sure they are.
     if (empty($model_id) || !is_array($config) || empty($config['model_paths'])) {
         throw new EE_Error(__('In order to register Models with EE_Register_Model::register(), you must include a "model_id" (a unique identifier for this set of models), and an array containing the following keys: "model_paths" (an array of full server paths to folders that contain models)', 'event_espresso'));
     }
     //make sure we don't register twice
     if (isset(self::$_model_registry[$model_id])) {
         return;
     }
     if (!did_action('AHEE__EE_System__load_espresso_addons') || did_action('FHEE__EE_System__parse_model_names') || did_action('FHEE__EE_System__parse_implemented_model_names')) {
         EE_Error::doing_it_wrong(__METHOD__, sprintf(__('An attempt was made to register "%s" as a group models has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__load_espresso_addons" hook to register models.', 'event_espresso'), $model_id), '4.5');
     }
     self::$_model_registry[$model_id] = $config;
     EE_Registry::instance()->load_helper('File');
     if (isset($config['model_paths']) && !isset($config['class_paths']) || !isset($config['model_paths']) && isset($config['class_paths'])) {
         throw new EE_Error(sprintf(__('You must register both "model_paths" AND "class_paths", not just one or the other You provided %s', 'event_espresso'), implode(", ", array_keys($config))));
     }
     if (isset($config['model_paths'])) {
         //make sure they passed in an array
         if (!is_array($config['model_paths'])) {
             $config['model_paths'] = array($config['model_paths']);
         }
         //we want to add this as a model folder
         //and autoload them all
         $class_to_filepath_map = EEH_File::get_contents_of_folders($config['model_paths']);
         EEH_Autoloader::register_autoloader($class_to_filepath_map);
         $model_name_to_classname_map = array();
         foreach (array_keys($class_to_filepath_map) as $classname) {
             $model_name_to_classname_map[str_replace("EEM_", "", $classname)] = $classname;
         }
         self::$_model_name_to_classname_map[$model_id] = $model_name_to_classname_map;
         add_filter('FHEE__EE_System__parse_model_names', array('EE_Register_Model', 'add_addon_models'));
         add_filter('FHEE__EE_System__parse_implemented_model_names', array('EE_Register_Model', 'add_addon_models'));
         add_filter('FHEE__EE_Registry__load_model__paths', array('EE_Register_Model', 'add_model_folders'));
         unset($config['model_paths']);
     }
     if (isset($config['class_paths'])) {
         //make sure they passed in an array
         if (!is_array($config['class_paths'])) {
             $config['class_paths'] = array($config['class_paths']);
         }
         $class_to_filepath_map = EEH_File::get_contents_of_folders($config['class_paths']);
         EEH_Autoloader::register_autoloader($class_to_filepath_map);
         add_filter('FHEE__EE_Registry__load_class__paths', array('EE_Register_Model', 'add_class_folders'));
         unset($config['class_paths']);
     }
     foreach ($config as $unknown_key => $unknown_config) {
         self::deregister($model_id);
         throw new EE_Error(sprintf(__("The key '%s' is not a known key for registering a model", "event_espresso"), $unknown_key));
     }
 }
 protected static function _set_hooks_for_changes()
 {
     $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
     foreach ($folder_contents as $classname_in_namespace => $filepath) {
         //ignore the base parent class
         if ($classname_in_namespace === 'Changes_In_Base') {
             continue;
         }
         $full_classname = 'EventEspresso\\core\\libraries\\rest_api\\changes\\' . $classname_in_namespace;
         if (class_exists($full_classname)) {
             $instance_of_class = new $full_classname();
             if ($instance_of_class instanceof EventEspresso\core\libraries\rest_api\changes\Changes_In_Base) {
                 $instance_of_class->set_hooks();
             }
         }
     }
 }
 /**
  * 	_get_scopes
  * @return array
  */
 private function _get_scopes()
 {
     static $scopes = array();
     $scopes_to_register = apply_filters('FHEE__EE_Promotions_Config___get_scopes__scopes_to_register', glob(EE_PROMOTIONS_PATH . 'lib/scopes/*.lib.php'));
     foreach ($scopes_to_register as $scope) {
         $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($scope);
         // if parent let's skip - it's already been required.
         if ($class_name == 'EE_Promotion_Scope') {
             continue;
         }
         $loaded = (require_once $scope);
         // avoid instantiating classes twice by checking whether file has already been loaded
         // ( first load returns (int)1, subsequent loads return (bool)true )
         if ($loaded === 1) {
             if (class_exists($class_name)) {
                 $reflector = new ReflectionClass($class_name);
                 $sp = $reflector->newInstance();
                 $scopes[$sp->slug] = $sp;
             }
         }
     }
     return $scopes;
 }
 /**
  * 	captures plugin activation errors for debugging
  *
  * 	@return void
  */
 public static function ee_plugin_activation_errors()
 {
     if (defined('WP_DEBUG') && WP_DEBUG) {
         $activation_errors = ob_get_contents();
         if (class_exists('EE_Registry')) {
             EE_Registry::instance()->load_helper('File');
         } else {
             include_once EE_HELPERS . 'EEH_File.helper.php';
         }
         if (class_exists('EEH_File')) {
             try {
                 EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS);
                 EEH_File::ensure_file_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html');
                 EEH_File::write_to_file(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors);
             } catch (EE_Error $e) {
                 EE_Error::add_error(sprintf(__('The Event Espresso activation errors file could not be setup because: %s', 'event_espresso'), $e->getMessage()));
             }
         } else {
             // old school attempt
             file_put_contents(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors);
         }
         $activation_errors = get_option('ee_plugin_activation_errors', '') . $activation_errors;
         update_option('ee_plugin_activation_errors', $activation_errors);
     }
 }
 /**
  * Assumes all the files in this folder have the normal naming scheme (namely that their classname
  * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
  * If that's not the case, you'll need to improve this function or just use EEH_File::get_classname_from_filepath_with_standard_filename() directly.
  * Yes this has to scan the directory for files, but it only does it once -- not on EACH
  * time the autoloader is used
  * @param string $folder name, with or without trailing /, doesn't matter
  * @return void
  */
 public static function register_autoloaders_for_each_file_in_folder($folder)
 {
     // make sure last char is a /
     $folder .= $folder[strlen($folder) - 1] != DS ? DS : '';
     $class_to_filepath_map = array();
     $exclude = array('index');
     //get all the files in that folder that end in php
     $filepaths = glob($folder . '*.php');
     foreach ($filepaths as $filepath) {
         $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
         if (!in_array($class_name, $exclude)) {
             $class_to_filepath_map[$class_name] = str_replace(array('\\/', '/'), DS, $filepath);
         }
     }
     self::register_autoloader($class_to_filepath_map);
 }
 /**
  * cycles through all of the models/*.model.php files, and assembles an array of model names
  *
  * @return void
  */
 private function _parse_model_names()
 {
     //get all the files in the EE_MODELS folder that end in .model.php
     $models = glob(EE_MODELS . '*.model.php');
     $model_names = array();
     $non_abstract_db_models = array();
     foreach ($models as $model) {
         // get model classname
         $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
         $short_name = str_replace('EEM_', '', $classname);
         $reflectionClass = new ReflectionClass($classname);
         if ($reflectionClass->isSubclassOf('EEM_Base') && !$reflectionClass->isAbstract()) {
             $non_abstract_db_models[$short_name] = $classname;
         }
         $model_names[$short_name] = $classname;
     }
     $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
     $this->registry->non_abstract_db_models = apply_filters('FHEE__EE_System__parse_implemented_model_names', $non_abstract_db_models);
 }
 public function test_get_contents_of_folders()
 {
     global $wp_filesystem;
     $wp_filesystem->mkdir('/test/');
     $wp_filesystem->touch('/test/EE_Thingy.um.php');
     $wp_filesystem->touch('/test/EEX_YEP.fe.ss');
     $wp_filesystem->mkdir('/test/other/');
     $classname_to_filepath_map = EEH_File::get_contents_of_folders(array('/test/'));
     $this->assertEquals(array('EE_Thingy' => '/test/EE_Thingy.um.php', 'EEX_YEP' => '/test/EEX_YEP.fe.ss'), $classname_to_filepath_map);
 }
 /**
  * add_htaccess_deny_from_all
  * @param string $folder
  * @return bool
  */
 public static function add_htaccess_deny_from_all($folder = '')
 {
     $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
     if (!EEH_File::exists($folder . '.htaccess')) {
         if (!EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
             return FALSE;
         }
     }
     return TRUE;
 }
 /**
  *    locate_template
  *
  *    locate a template file by looking in the following places, in the following order:
  *        <server path up to>/wp-content/themes/<current active WordPress theme>/
  *        <assumed full absolute server path>
  *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
  *        <server path up to>/wp-content/uploads/espresso/templates/
  *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
  *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
  *        <server path up to>/wp-content/plugins/<EE4 folder>/
  *    as soon as the template is found in one of these locations, it will be returned or loaded
  *
  * 		Example:
  * 		  You are using the WordPress Twenty Sixteen theme,
  *        and you want to customize the "some-event.template.php" template,
  * 		  which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
  * 		  Assuming WP is installed on your server in the "/home/public_html/" folder,
  *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
  *
  *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
  *        /relative/path/to/some-event.template.php
  *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
  *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
  *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
  *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
  *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
  *
  * 		  Had you passed an absolute path to your template that was in some other location,
  *        ie: "/absolute/path/to/some-event.template.php"
  * 		  then the search would have been :
  *
  *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
  *        /absolute/path/to/some-event.template.php
  *
  * 		  and stopped there upon finding it in the second location
  *
  * @param array|string $templates array of template file names including extension (or just a single string)
  * @param  array   $template_args an array of arguments to be extracted for use in the template
  * @param  boolean $load          whether to pass the located template path on to the EEH_Template::display_template() method or simply return it
  * @param  boolean $return_string whether to send output immediately to screen, or capture and return as a string
  * @param boolean $check_if_custom If TRUE, this flags this method to return boolean for whether this will generate a custom template or not.
  * 				Used in places where you don't actually load the template, you just want to know if there's a custom version of it.
  * @return mixed
  */
 public static function locate_template($templates = array(), $template_args = array(), $load = TRUE, $return_string = TRUE, $check_if_custom = FALSE)
 {
     // first use WP locate_template to check for template in the current theme folder
     $template_path = locate_template($templates);
     if ($check_if_custom && !empty($template_path)) {
         return TRUE;
     }
     // not in the theme
     if (empty($template_path)) {
         // not even a template to look for ?
         if (empty($templates)) {
             // get post_type
             $post_type = EE_Registry::instance()->REQ->get('post_type');
             // get array of EE Custom Post Types
             $EE_CPTs = EE_Register_CPTs::get_CPTs();
             // build template name based on request
             if (isset($EE_CPTs[$post_type])) {
                 $archive_or_single = is_archive() ? 'archive' : '';
                 $archive_or_single = is_single() ? 'single' : $archive_or_single;
                 $templates = $archive_or_single . '-' . $post_type . '.php';
             }
         }
         // currently active EE template theme
         $current_theme = EE_Config::get_current_theme();
         // array of paths to folders that may contain templates
         $template_folder_paths = array(EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme, EVENT_ESPRESSO_TEMPLATE_DIR);
         //add core plugin folders for checking only if we're not $check_if_custom
         if (!$check_if_custom) {
             $core_paths = array(EE_PUBLIC . $current_theme, EE_TEMPLATES . $current_theme, EE_PLUGIN_DIR_PATH);
             $template_folder_paths = array_merge($template_folder_paths, $core_paths);
         }
         // now filter that array
         $template_folder_paths = apply_filters('FHEE__EEH_Template__locate_template__template_folder_paths', $template_folder_paths);
         $templates = is_array($templates) ? $templates : array($templates);
         $template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
         // array to hold all possible template paths
         $full_template_paths = array();
         EE_Registry::instance()->load_helper('File');
         // loop through $templates
         foreach ($templates as $template) {
             // normalize directory separators
             $template = EEH_File::standardise_directory_separators($template);
             $file_name = basename($template);
             $template_path_minus_file_name = substr($template, 0, strlen($file_name) * -1);
             // while looping through all template folder paths
             foreach ($template_folder_paths as $template_folder_path) {
                 // normalize directory separators
                 $template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
                 // determine if any common base path exists between the two paths
                 $common_base_path = EEH_Template::_find_common_base_path(array($template_folder_path, $template_path_minus_file_name));
                 if ($common_base_path !== '') {
                     // both paths have a common base, so just tack the filename onto our search path
                     $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
                 } else {
                     // no common base path, so let's just concatenate
                     $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
                 }
                 // build up our template locations array by adding our resolved paths
                 $full_template_paths[] = $resolved_path;
             }
             // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
             array_unshift($full_template_paths, $template);
             // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
             array_unshift($full_template_paths, get_stylesheet_directory() . DS . $file_name);
         }
         // filter final array of full template paths
         $full_template_paths = apply_filters('FHEE__EEH_Template__locate_template__full_template_paths', $full_template_paths, $file_name);
         // now loop through our final array of template location paths and check each location
         foreach ((array) $full_template_paths as $full_template_path) {
             if (is_readable($full_template_path)) {
                 $template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
                 break;
             }
         }
     }
     // if we got it and you want to see it...
     if ($template_path && $load && !$check_if_custom) {
         if ($return_string) {
             return EEH_Template::display_template($template_path, $template_args, TRUE);
         } else {
             EEH_Template::display_template($template_path, $template_args, FALSE);
         }
     }
     return $check_if_custom && !empty($template_path) ? TRUE : $template_path;
 }
 /**
  * create_upload_directories
  * Creates folders in the uploads directory to facilitate addons and templates
  *
  * 	@access public
  * 	@static
  * 	@return boolean success of verifying upload directories exist
  */
 public static function create_upload_directories()
 {
     EE_Registry::instance()->load_helper('File');
     // Create the required folders
     $folders = array(EVENT_ESPRESSO_UPLOAD_DIR, EVENT_ESPRESSO_TEMPLATE_DIR, EVENT_ESPRESSO_GATEWAY_DIR, EVENT_ESPRESSO_UPLOAD_DIR . '/logs/', EVENT_ESPRESSO_UPLOAD_DIR . '/css/', EVENT_ESPRESSO_UPLOAD_DIR . '/tickets/');
     foreach ($folders as $folder) {
         try {
             EEH_File::ensure_folder_exists_and_is_writable($folder);
             @chmod($folder, 0755);
         } catch (EE_Error $e) {
             EE_Error::add_error(sprintf(__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'), $folder, '<br />' . $e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
             return FALSE;
         }
     }
     return TRUE;
 }
 /**
  * 	captures plugin activation errors for debugging
  *
  * 	@return void
  */
 public function ee_plugin_activation_errors()
 {
     if (WP_DEBUG === TRUE) {
         $errors = ob_get_contents();
         if (include_once EE_HELPERS . 'EEH_File.helper.php') {
             try {
                 EEH_File::ensure_folder_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS);
                 EEH_File::ensure_file_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html');
                 EEH_File::write_to_file(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $errors);
             } catch (EE_Error $e) {
                 EE_Error::add_error(sprintf(__('The Event Espresso activation errors file could not be setup because: %s', 'event_espresso'), $e->getMessage()));
             }
         } else {
             // old school attempt
             file_put_contents(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $errors);
         }
         update_option('ee_plugin_activation_errors', $errors);
     }
 }
 /**
  * @group 9059
  */
 public function test_get_parent_folder__folder()
 {
     $this->assertEquals('/var/something/', EEH_File::get_parent_folder('/var/something/somewhere/'));
 }
 /**
  * 	captures plugin activation errors for debugging
  *
  * 	@return void
  */
 public static function ee_plugin_activation_errors()
 {
     if (WP_DEBUG) {
         $activation_errors = ob_get_contents();
         if (!empty($activation_errors)) {
             $activation_errors = date('Y-m-d H:i:s') . "\n" . $activation_errors;
         }
         espresso_load_required('EEH_File', EE_HELPERS . 'EEH_File.helper.php');
         if (class_exists('EEH_File')) {
             try {
                 EEH_File::ensure_file_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html');
                 EEH_File::write_to_file(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors);
             } catch (EE_Error $e) {
                 EE_Error::add_error(sprintf(__('The Event Espresso activation errors file could not be setup because: %s', 'event_espresso'), $e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
             }
         } else {
             // old school attempt
             file_put_contents(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors);
         }
         $activation_errors = get_option('ee_plugin_activation_errors', '') . $activation_errors;
         update_option('ee_plugin_activation_errors', $activation_errors);
     }
 }
 /**
  * Given a "local" filepath (what you probably thought was the only filepath),
  * converts it into a "remote" filepath (the filepath the currently-in-use 
  * $wp_filesystem needs to use access the folder or file).
  * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
  * @param WP_Filesystem_Base $wp_filesystem we aren't initially sure which one
  * is in use, so you need to provide it
  * @param string $local_filepath the filepath to the folder/file locally
  * @throws EE_Error if filesystem credentials are required
  * @return string the remote filepath (eg the filepath the filesystem method, eg 
  * ftp or ssh, will use to access the folder
  */
 public static function convert_local_filepath_to_remote_filepath($local_filepath)
 {
     $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
     return str_replace(WP_CONTENT_DIR . DS, $wp_filesystem->wp_content_dir(), $local_filepath);
 }
 /**
  *	write exception details to log file
  *
  *	@access public
  *	@ param timestamp $time
  *	@ param object $ex
  *	@ return void
  */
 public function write_to_error_log($time = FALSE, $ex = FALSE, $clear = FALSE)
 {
     if (!$ex) {
         return;
     }
     if (!$time) {
         $time = time();
     }
     $exception_log = '----------------------------------------------------------------------------------------' . PHP_EOL;
     $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
     $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
     $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
     $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
     $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
     $exception_log .= 'Stack trace: ' . PHP_EOL;
     $exception_log .= $ex['string'] . PHP_EOL;
     $exception_log .= '----------------------------------------------------------------------------------------' . PHP_EOL;
     EE_Registry::instance()->load_helper('File');
     try {
         EEH_File::ensure_file_exists_and_is_writable(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file);
         EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs');
         if (!$clear) {
             //get existing log file and append new log info
             $exception_log = EEH_File::get_file_contents(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file) . $exception_log;
         }
         EEH_File::write_to_file(EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . self::$_exception_log_file, $exception_log);
     } catch (EE_Error $e) {
         EE_Error::add_error(sprintf(__('Event Espresso error logging could not be setup because: %s', 'event_espresso'), $e->getMessage()));
         return;
     }
 }
 /**
  * write_debug
  * writes the contents of the current request's $_GET and $_POST arrays to a log file.
  * previous entries are overwritten
  */
 public function write_debug()
 {
     if (defined('WP_DEBUG') && WP_DEBUG) {
         $this->_debug_log = '';
         foreach ($_GET as $key => $value) {
             $this->_debug_log .= '$_GET["' . $key . '"] = "' . serialize($value) . '"' . PHP_EOL;
         }
         foreach ($_POST as $key => $value) {
             $this->_debug_log .= '$_POST["' . $key . '"] = "' . serialize($value) . '"' . PHP_EOL;
         }
         try {
             EEH_File::write_to_file($this->_logs_folder . $this->_debug_file, $this->_debug_log, 'Event Espresso Debug Log');
         } catch (EE_Error $e) {
             EE_Error::add_error(sprintf(__('Could not write to the Event Espresso debug log file because: %s', 'event_espresso'), ' &nbsp; &nbsp; ' . $e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
             return;
         }
     }
 }
 /**
  * Performs any clean-up logic when we know the job is completed.
  * In this case, we delete the temporary file
  * @param JobParameters $job_parameters
  * @return boolean
  */
 public function cleanup_job(JobParameters $job_parameters)
 {
     $this->_file_helper->delete(\EEH_File::remove_filename_from_filepath($job_parameters->extra_datum('filepath')), true, 'd');
     return new JobStepResponse($job_parameters, __('Cleaned up temporary file', 'event_espresso'));
 }
 /**
  * Assumes all the files in this folder have the normal naming scheme (namely that their classname
  * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
  * If that's not the case, you'll need to improve this function or just use EEH_File::get_classname_from_filepath_with_standard_filename() directly.
  * Yes this has to scan the directory for files, but it only does it once -- not on EACH
  * time the autoloader is used
  *
  * @param string $folder name, with or without trailing /, doesn't matter
  * @param bool   $recursive
  * @param bool   $debug - set to true to display autoloader class => path mappings
  * @return void
  * @throws \EE_Error
  */
 public static function register_autoloaders_for_each_file_in_folder($folder, $recursive = false, $debug = false)
 {
     // make sure last char is a /
     $folder .= $folder[strlen($folder) - 1] != DS ? DS : '';
     $class_to_filepath_map = array();
     $exclude = array('index');
     //get all the files in that folder that end in php
     $filepaths = glob($folder . '*');
     if (empty($filepaths)) {
         return;
     }
     foreach ($filepaths as $filepath) {
         if (substr($filepath, -4, 4) == '.php') {
             $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
             if (!in_array($class_name, $exclude)) {
                 $class_to_filepath_map[$class_name] = $filepath;
             }
         } else {
             if ($recursive) {
                 EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive);
             }
         }
     }
     // we remove the necessity to do a is_readable() check via the $read_check flag because glob by nature will not return non_readable files/directories.
     self::register_autoloader($class_to_filepath_map, false, $debug);
 }
 /**
  * create_upload_directories
  * Creates folders in the uploads directory to facilitate addons and templates
  *
  * 	@access public
  * 	@static
  * 	@return boolean success of verifying upload directories exist
  */
 public static function create_upload_directories()
 {
     EE_Registry::instance()->load_helper('File');
     // Create the required folders
     $folders = array(EVENT_ESPRESSO_TEMPLATE_DIR, EVENT_ESPRESSO_GATEWAY_DIR, EVENT_ESPRESSO_UPLOAD_DIR . 'logs/', EVENT_ESPRESSO_UPLOAD_DIR . 'css/', EVENT_ESPRESSO_UPLOAD_DIR . 'tickets/');
     foreach ($folders as $folder) {
         try {
             EEH_File::ensure_folder_exists_and_is_writable($folder);
             @chmod($folder, 0755);
         } catch (EE_Error $e) {
             EE_Error::add_error(sprintf(__('Could not create the folder at "%1$s" because: %2$s', 'event_espresso'), $folder, '<br />' . $e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
             //indicate we'll need to fix this later
             update_option(EEH_Activation::upload_directories_incomplete_option_name, true);
             return FALSE;
         }
     }
     //just add the .htaccess file to the logs directory to begin with. Even if logging
     //is disabled, there might be activation errors recorded in there
     EEH_File::add_htaccess_deny_from_all(EVENT_ESPRESSO_UPLOAD_DIR . 'logs/');
     //remember EE's folders are all good
     delete_option(EEH_Activation::upload_directories_incomplete_option_name);
     return TRUE;
 }
 /**
  * Loads a page for running a batch job that creates and downloads a file, 
  * and then sends the user back to wherever they were before
  */
 protected function batch_file_create()
 {
     //creates a job based on the request variable
     $job_handler_classname = str_replace('\\\\', '\\', $this->_req_data['job_handler']);
     $request_data = array_diff_key($this->_req_data, array_flip(array('action', 'page')));
     $batch_runner = new EventEspressoBatchRequest\BatchRequestProcessor();
     //eg 'EventEspressoBatchRequest\JobHandlers\RegistrationsReport'
     $job_response = $batch_runner->create_job($job_handler_classname, $request_data);
     wp_localize_script('support_batch_file_runner', 'ee_job_response', $job_response->to_array());
     wp_localize_script('support_batch_file_runner', 'ee_job_i18n', array('download_and_redirecting' => sprintf(__('File Generation complete. Downloading, and %1$sredirecting%2$s...', 'event_espresso'), '<a href="' . $this->_req_data['redirect_url'] . '">', '</a>'), 'redirect_url' => $this->_req_data['redirect_url']));
     echo EEH_Template::locate_template(EE_SUPPORT_ADMIN . 'templates' . DS . 'admin_batch_file_runner.template.html', array('filename' => EEH_File::get_filename_from_filepath($job_response->job_parameters()->extra_datum('filepath'))));
 }
 /**
  * 	wp_enqueue_scripts
  *
  *  @access 	public
  *  @return 	void
  */
 public function wp_enqueue_scripts()
 {
     // get some style
     if (apply_filters('FHEE_enable_default_espresso_css', FALSE)) {
         // first check uploads folder
         EE_Registry::instance()->load_helper('File');
         if (EEH_File::is_readable(get_stylesheet_directory() . $this->theme . DS . 'style.css')) {
             wp_register_style($this->theme, get_stylesheet_directory_uri() . $this->theme . DS . 'style.css', array('dashicons', 'espresso_default'));
         } else {
         }
         wp_enqueue_style($this->theme);
     }
 }
 /**
  * Copies a file. Mostly a wrapper of WP_Filesystem::copy
  * @param string $source_file
  * @param string $destination_file
  * @param boolean $overwrite
  * @return boolean success
  * @throws EE_Error
  */
 public static function copy($source_file, $destination_file, $overwrite = FALSE)
 {
     $full_source_path = EEH_File::standardise_directory_separators($source_file);
     if (!EEH_File::exists($full_source_path)) {
         if (defined('WP_DEBUG') && WP_DEBUG) {
             $msg = sprintf(__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'), $full_source_path);
             $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
             throw new EE_Error($msg);
         }
         return FALSE;
     }
     $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
     $folder = EEH_File::remove_filename_from_filepath($full_dest_path);
     if (!EEH_File::verify_is_writable($folder, 'folder')) {
         if (defined('WP_DEBUG') && WP_DEBUG) {
             $msg = sprintf(__('The file located at "%2$s" is not writable.', 'event_espresso'), $full_dest_path);
             $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
             throw new EE_Error($msg);
         }
         return FALSE;
     }
     // load WP_Filesystem and set file permissions
     $wp_filesystem = EEH_File::_get_wp_filesystem();
     // write the file
     if (!$wp_filesystem->copy($full_source_path, $full_dest_path, $overwrite)) {
         if (defined('WP_DEBUG') && WP_DEBUG) {
             $msg = sprintf(__('Attempted writing to file %1$s, but could not, probably because of permissions issues', 'event_espresso'), $full_source_path);
             $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path, 'f');
             throw new EE_Error($msg);
         }
         return FALSE;
     }
     return TRUE;
 }