/** * Handles all method calls for columns, related records and hook callbacks * * Dynamically handles `get`, `set`, `prepare`, `encode` and `inspect` * methods for each column in this record. Method names are in the form * `verbColumName()`. * * This method also handles `associate`, `build`, `count`, `has`, and `link` * verbs for records in many-to-many relationships; `build`, `count`, `has` * and `populate` verbs for all related records in one-to-many relationships * and `create`, `has` and `populate` verbs for all related records in * one-to-one relationships, and the `create` verb for all related records * in many-to-one relationships. * * Method callbacks registered through fORM::registerActiveRecordMethod() * will be delegated via this method. * * @param string $method_name The name of the method called * @param array $parameters The parameters passed * @return mixed The value returned by the method called */ public function __call($method_name, $parameters) { $class = get_class($this); if (!isset(self::$callback_cache[$class][$method_name])) { if (!isset(self::$callback_cache[$class])) { self::$callback_cache[$class] = array(); } $callback = fORM::getActiveRecordMethod($class, $method_name); self::$callback_cache[$class][$method_name] = $callback ? $callback : FALSE; } if ($callback = self::$callback_cache[$class][$method_name]) { return call_user_func_array($callback, array($this, &$this->values, &$this->old_values, &$this->related_records, &$this->cache, $method_name, $parameters)); } if (!isset(self::$method_name_cache[$method_name])) { list($action, $subject) = fORM::parseMethod($method_name); if (in_array($action, array('get', 'encode', 'prepare', 'inspect', 'set'))) { $subject = fGrammar::underscorize($subject); } else { if (in_array($action, array('build', 'count', 'inject', 'link', 'list', 'tally'))) { $subject = fGrammar::singularize($subject); } $subject = fORM::getRelatedClass($class, $subject); } self::$method_name_cache[$method_name] = array('action' => $action, 'subject' => $subject); } else { $action = self::$method_name_cache[$method_name]['action']; $subject = self::$method_name_cache[$method_name]['subject']; } switch ($action) { // Value methods case 'get': return $this->get($subject); case 'encode': if (isset($parameters[0])) { return $this->encode($subject, $parameters[0]); } return $this->encode($subject); case 'prepare': if (isset($parameters[0])) { return $this->prepare($subject, $parameters[0]); } return $this->prepare($subject); case 'inspect': if (isset($parameters[0])) { return $this->inspect($subject, $parameters[0]); } return $this->inspect($subject); case 'set': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } return $this->set($subject, $parameters[0]); // Related data methods // Related data methods case 'associate': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } $records = $parameters[0]; $route = isset($parameters[1]) ? $parameters[1] : NULL; list($subject, $route, $plural) = self::determineSubject($class, $subject, $route); if ($plural) { fORMRelated::associateRecords($class, $this->related_records, $subject, $records, $route); } else { fORMRelated::associateRecord($class, $this->related_records, $subject, $records, $route); } return $this; case 'build': if (isset($parameters[0])) { return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject); case 'count': if (isset($parameters[0])) { return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject); case 'create': if (isset($parameters[0])) { return fORMRelated::createRecord($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::createRecord($class, $this->values, $this->related_records, $subject); case 'has': $route = isset($parameters[0]) ? $parameters[0] : NULL; list($subject, $route, ) = self::determineSubject($class, $subject, $route); return fORMRelated::hasRecords($class, $this->values, $this->related_records, $subject, $route); case 'inject': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } if (isset($parameters[1])) { return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0], $parameters[1]); } return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0]); case 'link': if (isset($parameters[0])) { fORMRelated::linkRecords($class, $this->related_records, $subject, $parameters[0]); } else { fORMRelated::linkRecords($class, $this->related_records, $subject); } return $this; case 'list': if (isset($parameters[0])) { return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject); case 'populate': $route = isset($parameters[0]) ? $parameters[0] : NULL; list($subject, $route, ) = self::determineSubject($class, $subject, $route); fORMRelated::populateRecords($class, $this->related_records, $subject, $route); return $this; case 'tally': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } if (isset($parameters[1])) { return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0], $parameters[1]); } return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0]); // Error handler // Error handler default: throw new fProgrammerException('Unknown method, %s(), called', $method_name); } }
/** * Handles all method calls for columns, related records and hook callbacks * * Dynamically handles `get`, `set`, `prepare`, `encode` and `inspect` * methods for each column in this record. Method names are in the form * `verbColumName()`. * * This method also handles `associate`, `build`, `count` and `link` verbs * for records in many-to-many relationships; `build`, `count` and * `populate` verbs for all related records in one-to-many relationships * and the `create` verb for all related records in *-to-one relationships. * * Method callbacks registered through fORM::registerActiveRecordMethod() * will be delegated via this method. * * @param string $method_name The name of the method called * @param array $parameters The parameters passed * @return mixed The value returned by the method called */ public function __call($method_name, $parameters) { $class = get_class($this); if (!isset(self::$callback_cache[$class][$method_name])) { if (!isset(self::$callback_cache[$class])) { self::$callback_cache[$class] = array(); } $callback = fORM::getActiveRecordMethod($class, $method_name); self::$callback_cache[$class][$method_name] = $callback ? $callback : FALSE; } if ($callback = self::$callback_cache[$class][$method_name]) { return call_user_func_array($callback, array($this, &$this->values, &$this->old_values, &$this->related_records, &$this->cache, $method_name, $parameters)); } if (!isset(self::$method_name_cache[$method_name])) { list($action, $subject) = fORM::parseMethod($method_name); self::$method_name_cache[$method_name] = array('action' => $action, 'subject' => $subject); } else { $action = self::$method_name_cache[$method_name]['action']; $subject = self::$method_name_cache[$method_name]['subject']; } switch ($action) { // Value methods case 'get': return $this->get($subject); case 'encode': if (isset($parameters[0])) { return $this->encode($subject, $parameters[0]); } return $this->encode($subject); case 'prepare': if (isset($parameters[0])) { return $this->prepare($subject, $parameters[0]); } return $this->prepare($subject); case 'inspect': if (isset($parameters[0])) { return $this->inspect($subject, $parameters[0]); } return $this->inspect($subject); case 'set': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } return $this->set($subject, $parameters[0]); // Related data methods // Related data methods case 'associate': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } $table = fORM::tablize($class); $records = $parameters[0]; $route = isset($parameters[1]) ? $parameters[1] : NULL; $plural = FALSE; // one-to-many relationships need to use plural forms if (in_array($subject, fORMSchema::retrieve()->getTables())) { if (fORMSchema::isOneToOne($table, $subject, $route)) { throw new fProgrammerException('The table %1$s is not in a %2$srelationship with the table %3$s', $table, '*-to-many ', $subject); } $subject = fGrammar::singularize($subject); $plural = TRUE; } $subject = fGrammar::camelize($subject, TRUE); // This handles one-to-many and many-to-many relationships if ($plural) { return fORMRelated::associateRecords($class, $this->related_records, $subject, $records, $route); } // This handles one-to-one relationships return fORMRelated::associateRecord($class, $this->related_records, $subject, $records, $route); case 'build': $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[0])) { return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject); case 'count': $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[0])) { return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject); case 'create': $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[0])) { return fORMRelated::createRecord($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::createRecord($class, $this->values, $this->related_records, $subject); case 'inject': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[1])) { return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0], $parameters[1]); } return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0]); case 'link': $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[0])) { return fORMRelated::linkRecords($class, $this->related_records, $subject, $parameters[0]); } return fORMRelated::linkRecords($class, $this->related_records, $subject); case 'list': $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[0])) { return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject, $parameters[0]); } return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject); case 'populate': $table = fORM::tablize($class); $route = isset($parameters[0]) ? $parameters[0] : NULL; // one-to-many relationships need to use plural forms if (in_array($subject, fORMSchema::retrieve()->getTables())) { if (fORMSchema::isOneToOne($table, $subject, $route)) { throw new fProgrammerException('The table %1$s is not in a%2$srelationship with the table %3$s', $table, ' one-to-many ', $subject); } $subject = fGrammar::singularize($subject); } $subject = fGrammar::camelize($subject, TRUE); return fORMRelated::populateRecords($class, $this->related_records, $subject, $route); case 'tally': if (sizeof($parameters) < 1) { throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name); } $subject = fGrammar::singularize($subject); $subject = fGrammar::camelize($subject, TRUE); if (isset($parameters[1])) { return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0], $parameters[1]); } return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0]); // Error handler // Error handler default: throw new fProgrammerException('Unknown method, %s(), called', $method_name); } }