/** * Overloading static method triggered when invoking special method. * * @param string * @param array * @return mixed */ public static function __callStatic($name, $arguments) { $gas = self::make(); $arguments = self::validate_method($name, $arguments); if ($name == 'with') { // Mark necessary entities foreach ($arguments as $index => $entity) { $gas->related->set('include.' . $index, $entity); } // Eager loaded entities has been marker return $gas; } elseif (class_exists('\\Gas\\Extension\\' . ucfirst($name))) { // We need to mark the extension property // Assign the extension $extension_name = '\\Gas\\Extension\\' . ucfirst($name); $gas->extension = new $extension_name(); // Return for further process return $gas; } return Core::compile($gas, $name, $arguments); }
/** * Execute the compilation command * * @param object Gas instance * @return object Finished Gas */ protected static function _execute($gas) { // Build the tasks tree $tasks = self::_play_record($gas->recorder); // Mark every compile process into our caching pool self::cache_start($tasks); // Prepare tasks bundle $engine = get_class(static::$db); $compiler = array('gas' => $gas); $executor = static::$dictionary['executor']; $write = array_slice($executor, 0, 6); $flag = array('condition', 'selector'); $bundle = array('engine' => $engine, 'compiler' => $compiler, 'write' => $write, 'flag' => $flag); // Assign the task to the right person self::$task_manager = $bundle; // Lets dance... array_walk($tasks, function ($task_list, $key) use(&$tasks) { // Only sort if there are valid task and the task manager hold its task list if (!empty($task_list) or !empty(\Gas\Core::$task_manager)) { array_walk($task_list, function ($arguments, $key, $task) use(&$task_list) { // Only do each task if the task manager hold its task list if (!empty(\Gas\Core::$task_manager)) { // Diagnose the task $action = key($arguments); $args = array_shift($arguments); $flag = in_array($task, \Gas\Core::$task_manager['flag']); $write = in_array($action, \Gas\Core::$task_manager['write']); $gas = \Gas\Core::$task_manager['compiler']['gas']; $table = $gas->table; if (!$flag) { // Find within cache resource collection if ($action == 'get' && \Gas\Core::validate_cache() && !\Gas\Core::changed_resource($table)) { $res = \Gas\Core::fetch_cache(); \Gas\Core::reset_query(); } else { $dbal_method = array(\Gas\Core::$db, $action); $res = call_user_func_array($dbal_method, $args); \Gas\Core::cache_end($res); } // Post-processing query if ($write) { // Track the resource for any write operations \Gas\Core::track_resource($table, $action); } elseif ($action == 'get') { // Hydrate the gas instance $instances = array(); $entities = array(); $ids = array(); $model = $gas->model(); $extension = $gas->extension; $includes = $gas->related->get('include', array()); $relation = $gas->meta->get('entities'); // Do we have entities to eagerly-loaded? if (count($includes)) { // Then generate new colleciton holder for it $tuples = new \Gas\Data(); } // Get the array of fetched rows $results = $res->result_array(); // Generate the entitiy records foreach ($results as $result) { // Passed the result as record $instance = new $model($result); $instance->empty = FALSE; foreach ($includes as $include) { if (array_key_exists($include, $relation)) { $table = $instance->table; $pk = $instance->primary_key; $identifier = $instance->record->get('data.' . $pk); $concenate = $table . ':' . $pk . ':' . $identifier; $tuple = $relation[$include]; $type = $tuple['type']; if ($tuples->get('entities.' . $include)) { // Retrieve this entity $assoc_entities = $tuples->get('entities.' . $include); } else { $assoc_entities = \Gas\Core::generate_entity($gas, $tuple, $results); $tuples->set('entities.' . $include, $assoc_entities); } // Assign the included entity, respectively $entity = array_values(array_filter($assoc_entities->get('data.' . $identifier, array()))); $related_entity = $type == 'has_many' ? $entity : current($entity); $instance->related->set('entities.' . $include, $related_entity); } } // Pool to instance holder and unset the instance $instances[] = $instance; unset($instance); } // Determine whether to return an instance or a collection of instance(s) $res = count($instances) > 1 ? $instances : array_shift($instances); // Do we need to return the result, or passed into some extension? if (!empty($extension) && $extension instanceof Extension) { $res = $extension->__init($res); } } // Tell task manager to take a break, and fill the resource holder \Gas\Core::$task_manager = array(); \Gas\Core::$thread_resource = $res; } else { // Return the native DB driver method execution return call_user_func_array(array(\Gas\Core::$db, $action), $args); } } }, $key); } }); // Get the result and immediately flush the temporary resource holder $resource = self::$thread_resource and self::$thread_resource = NULL; // The compilation is done, send the song to listen return $resource; }