Skip to content

Commit

Permalink
Adding field properties to models.
Browse files Browse the repository at this point in the history
  • Loading branch information
KrisJordan committed Nov 8, 2008
1 parent 1920477 commit ee638e7
Show file tree
Hide file tree
Showing 20 changed files with 264 additions and 59 deletions.
9 changes: 9 additions & 0 deletions lib/recess/framework/ResponseData.class.php
@@ -0,0 +1,9 @@
<?php

Library::import('recess.lang.RecessClass');

class ResponseData extends RecessClass {

}

?>
31 changes: 22 additions & 9 deletions lib/recess/framework/controllers/AbstractController.class.php
Expand Up @@ -31,6 +31,17 @@ public function __construct() { }
* @return array(Routes)
*/
public function getRoutes() {
Library::import('recess.lang.RecessReflectionClass');
$reflectionClass = new RecessReflectionClass($this);
$methods = $reflectionClass->getMethods();
foreach($methods as $method) {
$annotations = $method->getAnnotations();
foreach($annotations as $annotation) {
if($annotation instanceof RouteAnnotation) {
$this->routes[] = new Route($this,$method->name,$annotation->methods,$annotation->path);
}
}
}
return $this->routes;
}

Expand Down Expand Up @@ -78,17 +89,19 @@ public function serve(Request $request) {
} else {
// Parameters are requested inbound
if(isset($request->meta['function_args']) && is_array($request->meta['function_args'])) {
if(count($request->meta['function_args']) == $parameterCount - 1) {
// Map function_args to expected parameters
$callArguments = array($request);
foreach($functionParameters as $parameter) {
if($parameter->getPosition() == 0) continue;
// Map function_args to expected parameters
$callArguments = array($request);
foreach($functionParameters as $parameter) {
if($parameter->getPosition() == 0) continue;
if(!isset($request->meta['function_args'][$parameter->getName()])) {
if(!$parameter->isOptional()) {
throw new RecessException('Controller method "' . $functionName . '" expects ' . $parameterCount . ' arguments, given ' . count($request->meta['function_args']) . ' and missing required parameter: ' . $parameter->name);
}
} else {
$callArguments[] = $request->meta['function_args'][$parameter->getName()];
}
$response = $function->invokeArgs($this, $callArguments);
} else {
throw new RecessException('Controller method "' . $functionName . '" expects ' . $parameterCount . ' arguments, given ' . count($request->meta['function_args']));
}
}
$response = $function->invokeArgs($this, $callArguments);
} else {
throw new RecessException('Controller method expects routed functions.', get_defined_vars());
}
Expand Down
10 changes: 10 additions & 0 deletions lib/recess/framework/conventions/DefaultConvention.class.php
Expand Up @@ -69,6 +69,16 @@ public function getViewFor(Response $response) {
}
}

if(isset($response->meta['viewClass'])) {
$className = $response->meta['viewClass'];
if(Library::classExists($this->applicationViewsPrefix . $className)) {
Library::import($this->applicationViewsPrefix . $className);
return new $className;
} else {
throw new RecessException('Cannot locate view, expecting: ' . $this->applicationViewsPrefix . $className, get_defined_vars());
}
}

if(isset($response->meta['resource'])) {
$className = Inflector::toProperCaps($response->meta['resource']) . 'View';
if(Library::classExists($this->applicationViewsPrefix . $className)) {
Expand Down
Expand Up @@ -54,14 +54,19 @@ protected function getHttpMethodFromPost(Request $request) {
}

protected function getFormatFromResourceString(Request $request) {
$lastDotPosition = strrpos($request->resource, Library::dotSeparator);
$lastPartIndex = count($request->resourceParts) - 1;
if($lastPartIndex < 0) return $request;

$lastPart = $request->resourceParts[$lastPartIndex];

$lastDotPosition = strrpos($lastPart, Library::dotSeparator);
if($lastDotPosition !== false) {
$substring = substr($request->resource, $lastDotPosition + 1);
$substring = substr($lastPart, $lastDotPosition + 1);
if(in_array($substring, Formats::$all)) {
$request->format = $substring;
$request->setResource(substr($request->resource, 0, $lastDotPosition));
$request->setResource(substr($request->resource, 0, strrpos($request->resource, Library::dotSeparator)));
} else {
$request->format = Formats::invalid;
$request->format = Formats::xhtml;
}
}
return $request;
Expand Down
13 changes: 6 additions & 7 deletions lib/recess/framework/views/SmartyView.class.php
Expand Up @@ -42,20 +42,19 @@ public function render(Response $response) {
default:
}

if($response->code == ResponseCodes::HTTP_CREATED) {
exit;
}
if($response->code == ResponseCodes::HTTP_CREATED) { exit; }

// TODO: Fill variables here
$this->smarty->assign('response', $response);
$this->smarty->assign('data', $response->data);
$this->smarty->assign('parameters', $response->meta['function_args']);

if(is_array($response->data)) {
foreach(array_keys($response->data) as $key) {
$this->smarty->assign($key, $response->data[$key]);
try {
foreach($response->data as $key => $value) {
$this->smarty->assign($key, $value);
}
}
} catch(Exception $e) {}

$this->smarty->display($this->templateLocationFor($response));
}

Expand Down
52 changes: 50 additions & 2 deletions lib/recess/lang/RecessClass.class.php
Expand Up @@ -20,7 +20,7 @@ abstract class RecessClass extends stdClass {
* @param string $providerMethodName
*/
static function attachMethod($attachOnClassName, $attachedMethodAlias, $providerInstance, $providerMethodName) {
$attachedMethod = new RecessClassAttachedMethod($providerInstance, $providerMethodName);
$attachedMethod = new RecessClassAttachedMethod($providerInstance, $providerMethodName, $attachedMethodAlias);
self::getClassDescriptor($attachOnClassName)->addAttachedMethod($attachedMethodAlias, $attachedMethod);
}

Expand Down Expand Up @@ -70,6 +70,17 @@ final static protected function getClassDescriptor($classNameOrInstance) {
}
}

/**
* Retrieve an array of the attached methods for a particular class.
*
* @param variant $classNameOrInstance - String class name or instance of a Recess Class
* @return array
*/
final static function getAttachedMethods($classNameOrInstance) {
$descriptor = self::getClassDescriptor($classNameOrInstance);
return $descriptor->getAttachedMethods();
}

/**
* Returns instance of RecessClassDescriptor which describes
* this class. Should be overridden in subclasses.
Expand Down Expand Up @@ -111,6 +122,15 @@ function getAttachedMethod($methodName) {
return false;
}

/**
* Return all attached methods.
*
* @return array(AttachedMethod)
*/
function getAttachedMethods() {
return $this->attachedMethods;
}

/**
* Add an attached method with given methodName alias.
*
Expand All @@ -132,11 +152,39 @@ function addAttachedMethod($methodName, RecessClassAttachedMethod $attachedMetho
class RecessClassAttachedMethod {
public $object;
public $method;
public $name;

function __construct($object, $method) {
function __construct($object, $method, $name) {
$this->object = $object;
$this->method = $method;
$this->name = $name;
}

function isFinal() { return true; }
function isAbstract() { return false; }
function isPublic() { return true; }
function isPrivate() { return false; }
function isProtected() { return false; }
function isStatic() { return false; }
function isConstructor() { return false; }
function isDestructor() { return false; }
function isAttached() { return true; }

function getName() { return $this->alias; }
function isInternal() { return false; }
function isUserDefined() { return true; }

function getFileName() { $reflection = new ReflectionClass($this->object); return $reflection->getMethod($this->method)->getFileName(); }
function getStartLine() { $reflection = new ReflectionClass($this->object); return $reflection->getMethod($this->method)->getStartLine(); }
function getEndLine() { $reflection = new ReflectionClass($this->object); return $reflection->getMethod($this->method)->getEndLine(); }
function getParameters() {
$reflection = new ReflectionClass($this->object);
$params = $reflection->getMethod($this->method)->getParameters();
array_shift($params);
return $params;
}
function getNumberOfParameters() { $reflection = new ReflectionClass($this->object); return $reflection->getMethod($this->method)->getNumberOfParameters() - 1; }
function getNumberOfRequiredParameters() { $reflection = new ReflectionClass($this->object); return $reflection->getMethod($this->method)->getNumberOfRequiredParameters() - 1; }
}

?>
12 changes: 9 additions & 3 deletions lib/recess/lang/RecessReflectionClass.class.php
@@ -1,5 +1,6 @@
<?php
Library::import('recess.lang.Annotation');
Library::import('recess.lang.RecessClass');
Library::import('recess.lang.RecessReflectionMethod');
Library::import('recess.lang.RecessReflectionProperty');

Expand All @@ -22,8 +23,8 @@
* @author Kris Jordan
*/
class RecessReflectionClass extends ReflectionClass {
function getProperties($filter) {
$rawProperties = parent::getProperties($filter);
function getProperties() {
$rawProperties = parent::getProperties();
$properties = array();
foreach($rawProperties as $rawProperty) {
$properties[] = new RecessReflectionProperty($this->name, $rawProperty->name);
Expand All @@ -34,7 +35,12 @@ function getMethods(){
$rawMethods = parent::getMethods();
$methods = array();
foreach($rawMethods as $rawMethod) {
$methods[] = new RecessReflectionMethod($this->name, $rawMethod->name);
$method = new RecessReflectionMethod($this->name, $rawMethod->name);
$methods[] = $method;
}
if($this->isSubclassOf('RecessClass')) {
// $attachedMethods = RecessClass::getAttachedMethods($this->name);
$methods = array_merge($methods, RecessClass::getAttachedMethods($this->name));
}
return $methods;
}
Expand Down
4 changes: 4 additions & 0 deletions lib/recess/lang/RecessReflectionMethod.class.php
Expand Up @@ -17,5 +17,9 @@ function getAnnotations() {
}
return $returns;
}

function isAttached() {
return false;
}
}
?>
59 changes: 48 additions & 11 deletions lib/recess/sources/db/orm/Model.class.php
Expand Up @@ -12,18 +12,15 @@
Library::import('recess.sources.db.orm.annotations.BelongsToAnnotation', true);
Library::import('recess.sources.db.orm.annotations.TableAnnotation', true);
Library::import('recess.sources.db.orm.annotations.PrimaryKeyAnnotation', true);
Library::import('recess.sources.db.orm.annotations.ForeignKeyAnnotation', true);
Library::import('recess.sources.db.orm.annotations.TypeAnnotation', true);
Library::import('recess.sources.db.orm.annotations.SourceAnnotation', true);

Library::import('recess.sources.db.orm.relationships.HasManyRelationship');
Library::import('recess.sources.db.orm.relationships.BelongsToRelationship');

abstract class Model extends RecessClass implements ISqlConditions {

function copy($keyValuePair) {
foreach($keyValuePair as $key => $value) {
$this->$key = $value;
}
}

static function sourceFor($class) {
return self::getClassDescriptor($class)->source;
}
Expand All @@ -41,14 +38,22 @@ static function primaryKeyName($class) {
return self::getClassDescriptor($class)->primaryKey;
}

static function getRelationship($class, $name) {
if(isset(self::getClassDescriptor($class)->relationships[$name])) {
return self::getClassDescriptor($class)->relationships[$name];
static function getRelationship($classOrInstance, $name) {
if(isset(self::getClassDescriptor($classOrInstance)->relationships[$name])) {
return self::getClassDescriptor($classOrInstance)->relationships[$name];
} else {
return false;
}
}

static function getRelationships($classOrInstance) {
return self::getClassDescriptor($classOrInstance)->relationships;
}

static function getColumns($classOrInstance) {
return self::getClassDescriptor($classOrInstance)->columns;
}

static protected function buildClassDescriptor($class) {
$descriptor = new ModelDescriptor($class);

Expand All @@ -65,6 +70,21 @@ static protected function buildClassDescriptor($class) {
}
}

$reflectedProperties = $reflection->getProperties();
$properties = array();
foreach($reflectedProperties as $reflectedProperty) {
$property = new ModelProperty();
$annotations = $reflectedProperty->getAnnotations();
foreach($annotations as $annotation) {
if($annotation instanceof ModelPropertyAnnotation) {
$annotation->massage($property);
}
if($annotation instanceof PrimaryKeyAnnotation) {
$descriptor->primaryKey = $reflectedProperty->name;
}
}
}

return $descriptor;
}

Expand All @@ -76,7 +96,7 @@ protected function getModelSet() {
$thisClassDescriptor = self::getClassDescriptor($this);
$result = $thisClassDescriptor->source->selectModelSet($thisClassDescriptor->table);
foreach($this as $column => $value) {
if(in_array($column,$thisClassDescriptor->columns)) {
if(isset($this->$column) && in_array($column,$thisClassDescriptor->columns)) {
$result = $result->assign($column, $value);
}
}
Expand Down Expand Up @@ -159,7 +179,7 @@ function primaryKeyIsSet() {
return false;
}
}

function find() { return $this->select(); }

function equal($lhs, $rhs){ return $this->select()->equal($lhs,$rhs); }
Expand All @@ -170,6 +190,21 @@ function greaterThanOrEqualTo($lhs, $rhs) { return $this->select()->greaterThanO
function lessThan($lhs, $rhs) { return $this->select()->lessThan($lhs,$rhs); }
function lessThanOrEqualTo($lhs, $rhs) { return $this->select()->lessThanOrEqualTo($lhs,$rhs); }
function like($lhs, $rhs) { return $this->select()->like($lhs,$rhs); }

function copy($keyValuePair) {
foreach($keyValuePair as $key => $value) {
$this->$key = $value;
}
}
}

class ModelProperty {
public $name;
public $type;
public $pkCallback;
public $autoincrement = false;
public $isPrimaryKey = false;
public $isForeignKey = false;
}

class ModelDescriptor extends RecessClassDescriptor {
Expand All @@ -178,7 +213,9 @@ class ModelDescriptor extends RecessClassDescriptor {

public $modelClass;
public $relationships;

public $columns;
public $properties;

// TODO: This will need to be refactored to reference the source_name verses the source
public $source_name;
Expand Down
@@ -0,0 +1,12 @@
<?php
Library::import('recess.sources.db.orm.annotations.ModelPropertyAnnotation');

class ForeignKeyAnnotation extends ModelPropertyAnnotation {
function init($array) { }

function massage(ModelProperty $property) {
$property->isForeignKey = true;
}
}

?>
@@ -0,0 +1,10 @@
<?php
Library::import('recess.lang.Annotation');

abstract class ModelPropertyAnnotation extends Annotation {

abstract function massage(ModelProperty $property);

}

?>

0 comments on commit ee638e7

Please sign in to comment.