function AdoDBRecord_AssociationProxy($client, $returns_many, $options) { $this->_client = $client; $this->_returns_many = $returns_many; $this->_options = $options; # build base data from options # TODO select source from polymorphic type $source = $this->_source = Singleton::instance($options["class_name"]); if (!is_subclass_of($this->_source, 'AdoDBRecord')) { die("AdoDBRecord_AssociationProxy: associated class isn't an ancestor of AdoDBRecord"); } # extract find options $find_options = array(); if (isset($options["order"])) { $find_options["order"] = $options["order"]; } # TODO if (isset($options["select"])) $find_options["select"] = $options["select"]; # parse conditions into string + parameters # FIXME make this DRY $parsed_conditions = array(); $parsed_params = array(); if (isset($options["conditions"])) { $arg = $options["conditions"]; if (!is_array($arg)) { $arg = array($arg); } $conditions = array_merge_recursive($conditions, $arg); AdoDBRecord_Tools::parse_conditions($conditions, $parsed_conditions, $parsed_params); } if (isset($options["primary_key"])) { $parsed_conditions[] = sprintf("%s = ?", $options["foreign_key"]); # FIXME PHP4 does not like $obj->$property indirection, fix this after dropping PHP4 support $parsed_params[] = $client->_attributes[$options["primary_key"]]; } else { $parsed_conditions[] = sprintf("%s = ?", 'id'); # FIXME PHP4 does not like $obj->$property indirection, fix this after dropping PHP4 support $parsed_params[] = $client->_attributes[$options["foreign_key"]]; } $find_conditions = sprintf("(%s)", join($parsed_conditions, ") AND (")); $find_conditions = strtr($find_conditions, array("%" => "%%", "?" => "'%s'")); # FIXME not database agnostic $find_conditions = vsprintf($find_conditions, $parsed_params); $find_options = array_merge($find_options, array("conditions" => $find_conditions)); if (isset($options["primary_key"])) { $this->_wrap_scope = array("find" => $find_options, "create" => array($options["foreign_key"] => $client->{$options}["primary_key"])); } else { $this->_wrap_scope = array("find" => $find_options); } }
function parse_conditions($conditions, &$parsed_conditions, &$parsed_params) { if (empty($conditions)) { return; } if (!is_array(reset($conditions))) { $parsed_conditions[] = array_shift($conditions); if (count($conditions) > 0) { $parsed_params = array_merge($parsed_params, $conditions); } return; } foreach ($conditions as $condition) { AdoDBRecord_Tools::parse_conditions($condition, $parsed_conditions, $parsed_params); } }
function &find($arguments) { $conditions = array(); # Be sure to have arguments in an array as needed below if (!is_array($arguments)) { $arguments = array($arguments); } # Instantiate model singleton to access scope $model =& Singleton::instance(); $scope = $model->_scope["find"]; $where = $order = $limit = $offset = NULL; $options = array(); # preset scoped options if (isset($scope["order"])) { $order = $scope["order"]; } # flatten all arguments if their key is numeric # this resolves e.g. array(1, 2, array("conditions" => "foo")) into array(1, 2, "conditions" => "foo") while (true) { $break = true; foreach ($arguments as $key => $value) { if (is_numeric($key) && is_array($value)) { unset($arguments[$key]); $arguments = array_merge_recursive($arguments, $value); $break = false; break; } } if ($break) { break; } } # parse arguments into query parameters foreach ($arguments as $key => $arg) { if (is_numeric($key)) { switch ($arg) { case "all": $limit = $offset = NULL; $options[] = $arg; continue 2; case "first": $limit = 1; $offset = NULL; $options[] = $arg; continue 2; default: $key = $this->_primary_key; } } switch ($key) { case "conditions": # FIXME make this DRY (see also AdoDBRecord_AssociationProxy) if (!is_array($arg)) { $arg = array($arg); } $conditions = array_merge_recursive($conditions, $arg); break; case "limit": case "offset": case "order": ${$key} = $arg; break; default: if (is_array($arg)) { $conditions[] = sprintf("{$key} IN (?)", $arg); } else { $conditions[] = array("{$key} = ?", $arg); } } } # parse conditions $parsed_conditions = array(); $parsed_params = array(); AdoDBRecord_Tools::parse_conditions($conditions, $parsed_conditions, $parsed_params); # join scoped conditions if (!empty($scope["conditions"])) { $parsed_conditions[] = $scope["conditions"]; } # convert parsed options to sql if ($order !== NULL) { $order = " ORDER BY {$order}"; } if (!empty($parsed_conditions)) { $where = sprintf(" WHERE (%s)", join($parsed_conditions, ") AND (")); AdoDBRecord_Tools::convert_sql_params($where, $parsed_params); } $objs = array(); $conn =& _adodb_conn(); # FIXME re-add table and column quotes again later if ($limit === NULL) { $limit = -1; } if ($offset === NULL) { $offset = -1; } if ($rs =& $conn->SelectLimit("SELECT * FROM {$this->_table_name}{$where}{$order}", $limit, $offset, $parsed_params)) { $rows =& $rs->GetRows(); foreach ($rows as $row) { $class = empty($row["type"]) ? get_class($this) : $row["type"]; $obj = new $class($row); $obj->_new_record = false; $objs[] = $obj; } if (in_array("all", $options)) { return $objs; } if (in_array("first", $options)) { return $objs[0]; } if (count($objs) == 1) { return $objs[0]; } return $objs; } $objs = NULL; return $objs; }