/** * Run the instance of a given hook * * @param string $namespace The namespace (addon/aspect) calling the hook * @param string $hook Name of hook * @param string $type Cumulative/replace/call * @param mixed $return Pass-through values * @param mixed $data Data to pass to hooked method * @return mixed */ public static function run($namespace, $hook, $type = NULL, $return = NULL, $data = NULL) { // @Todo: Clean this up globally $addons_path = BASE_PATH . Config::getAddOnsPath(); if (Folder::exists($addons_path) && Folder::exists(APP_PATH . '/core/tags')) { $finder = new Finder(); $files = $finder->files()->in($addons_path)->in(APP_PATH . '/core/tags')->name("hooks.*.php"); foreach ($files as $file) { require_once $file->getRealPath(); $class_name = 'Hooks_' . $file->getRelativePath(); $hook_class = new $class_name(); $method = $namespace . '__' . $hook; if (!method_exists($hook_class, $method)) { continue; } if ($type == 'cumulative') { $response = $hook_class->{$method}($data); if (is_array($response)) { $return = is_array($return) ? $return + $response : $response; } else { $return .= $response; } } elseif ($type == 'replace') { $return = $hook_class->{$method}($data); } else { $hook_class->{$method}($data); } } } else { Log::error('Add-ons path not found', 'hooks'); } return $return; }
/** * One tick of the timer, probably one minute from the last * * @return void */ public function tasks__tick() { $now = time(); $ticks = $this->cache->getYAML('ticks.yaml', array('last-tick' => 0)); // only about once per minute if ($now - $ticks['last-tick'] < 52) { $this->log->debug("Tick skipped, interval happening too frequently."); return; } // mark that a tick happened $this->log->debug("Tick."); // grab all task files $finder = new Finder(); $task_files = $finder->files()->in(Config::getAddOnsPath())->name("tasks.*.php"); // mark this tick as having happened $this->cache->putYAML('ticks.yaml', array("last-tick" => $now)); // if no task files were found, we're all set if (!$task_files->count()) { return; } // loop through task files foreach ($task_files as $task_file) { require_once $task_file->getRealPath(); $object_name = $task_file->getRelativePath(); $class_name = "Tasks_" . $object_name; $last_fired = $this->cache->getYAML('last-fired/' . $object_name . ".yaml", array()); $task_object = new $class_name(); // make sure that this is a Task-extending object if (!$task_object instanceof Tasks) { return; } // set up the task object $task_object->define(); $tasks = $task_object->get(); // loop through defined tasks, calling them if their age is too old foreach ($tasks as $task => $interval) { // could not run task, warn and move on if (!method_exists($task_object, $task)) { $this->log->warn("Could not run task `" . $task . "` from `Tasks_" . $object_name . "`."); continue; } // check for age in the last-fired list if (isset($last_fired[$task]) && is_numeric($last_fired[$task]) && floor(($now - $last_fired[$task]) / 60) < $interval) { $this->log->debug("Not firing task `" . $task . "`, interval has not fully passed yet."); continue; } // attempt to run the task, if FALSE is returned, don't count this run if (!(bool) $task_object->{$task}()) { $this->log->warn("Task `" . $task . "` ran but failed."); continue; } // update the time in which tasks fired $last_fired[$task] = $now; } // store the last-fired list back to cache $this->cache->putYAML('last-fired/' . $object_name . ".yaml", $last_fired); } }
/** * Run the instance of a given hook * * @param string $namespace The namespace (addon/aspect) calling the hook * @param string $hook Name of hook * @param string $type Cumulative/replace/call * @param mixed $return Pass-through values * @param mixed $data Data to pass to hooked method * @return mixed */ public static function run($namespace, $hook, $type = NULL, $return = NULL, $data = NULL) { $mark_as_init = !self::$hooks_found; if (!self::$hooks_found) { $hash = Debug::markStart('hooks', 'finding'); // we went finding self::$hooks_found = true; // set paths $addons_path = BASE_PATH . Config::getAddOnsPath(); $bundles_path = APP_PATH . '/core/bundles'; $pattern = '/*/hooks.*.php'; // globbing with a brace doesn't seem to work on some system, // it's not just Windows-based servers, seems to affect some // linux-based ones too $bundles = glob($bundles_path . $pattern); $addons = glob($addons_path . $pattern); $bundles = empty($bundles) ? array() : $bundles; $addons = empty($addons) ? array() : $addons; self::$hook_files = array_merge($bundles, $addons); Debug::markEnd($hash); } $hash = Debug::markStart('hooks', 'running'); if (self::$hook_files) { foreach (self::$hook_files as $file) { $name = substr($file, strrpos($file, '/') + 7); $name = substr($name, 0, strlen($name) - 4); $class_name = 'Hooks_' . $name; if (!is_callable(array($class_name, $namespace . '__' . $hook), false)) { continue; } try { $hook_class = Resource::loadHooks($name); $method = $namespace . '__' . $hook; if ($type == 'cumulative') { $response = $hook_class->{$method}($data); if (is_array($response)) { $return = is_array($return) ? $return + $response : $response; } else { $return .= $response; } } elseif ($type == 'replace') { $return = $hook_class->{$method}($data); } else { $hook_class->{$method}($data); } } catch (Exception $e) { continue; } } } if ($mark_as_init) { Debug::markMilestone('hooks initialized'); } Debug::markEnd($hash); return $return; }
/** * Run the instance of a given hook * * @param string $namespace The namespace (addon/aspect) calling the hook * @param string $hook Name of hook * @param string $type Cumulative/replace/call * @param mixed $return Pass-through values * @param mixed $data Data to pass to hooked method * @return mixed */ public static function run($namespace, $hook, $type = NULL, $return = NULL, $data = NULL) { $mark_as_init = !self::$hooks_found; if (!self::$hooks_found) { $hash = Debug::markStart('hooks', 'finding'); // we went finding self::$hooks_found = true; // set paths $addons_path = BASE_PATH . Config::getAddOnsPath(); $bundles_path = APP_PATH . '/core/bundles'; $pattern = '/*/hooks.*.php'; // muuulllllti-gloooobbb self::$hook_files = glob('{' . $bundles_path . $pattern . ',' . $addons_path . $pattern . '}', GLOB_BRACE); Debug::markEnd($hash); } $hash = Debug::markStart('hooks', 'running'); if (self::$hook_files) { foreach (self::$hook_files as $file) { $name = substr($file, strrpos($file, '/') + 7); $name = substr($name, 0, strlen($name) - 4); $class_name = 'Hooks_' . $name; if (!is_callable(array($class_name, $namespace . '__' . $hook), false)) { continue; } try { $hook_class = Resource::loadHooks($name); $method = $namespace . '__' . $hook; if ($type == 'cumulative') { $response = $hook_class->{$method}($data); if (is_array($response)) { $return = is_array($return) ? $return + $response : $response; } else { $return .= $response; } } elseif ($type == 'replace') { $return = $hook_class->{$method}($data); } else { $hook_class->{$method}($data); } } catch (Exception $e) { continue; } } } if ($mark_as_init) { Debug::markMilestone('hooks initialized'); } Debug::markEnd($hash); return $return; }