summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
Diffstat (limited to 'framework')
-rw-r--r--framework/Data/ActiveRecord/Exceptions/messages.txt3
-rw-r--r--framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php18
-rw-r--r--framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php55
-rw-r--r--framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php6
-rw-r--r--framework/Web/Javascripts/source/prado/activecontrols/ajax3.js4
-rw-r--r--framework/Web/Javascripts/source/prado/colorpicker/colorpicker.js8
-rw-r--r--framework/Web/Javascripts/source/prado/datepicker/datepicker.js2
-rw-r--r--framework/Web/Javascripts/source/prado/logger/logger.js24
-rw-r--r--framework/Web/Javascripts/source/prado/scriptaculous-adapter.js10
9 files changed, 96 insertions, 34 deletions
diff --git a/framework/Data/ActiveRecord/Exceptions/messages.txt b/framework/Data/ActiveRecord/Exceptions/messages.txt
index f9979e12..6c13450d 100644
--- a/framework/Data/ActiveRecord/Exceptions/messages.txt
+++ b/framework/Data/ActiveRecord/Exceptions/messages.txt
@@ -19,4 +19,5 @@ ar_invalid_table = Missing, invalid or no permission for table/view '{0}'.
ar_invalid_finder_class_name = Class name for finder($className) method must not be 'TActiveRecord', you should override the finder() method in your record class or pass in a valid record class name.
ar_invalid_criteria = Invalid criteria object, must be a string or instance of TSqlCriteria.
ar_relations_undefined = Unable to determine Active Record relationships because static array property {0}::${1} is not defined.
-ar_undefined_relation_prop = Unable to find {1}::${2}['{0}'], Active Record relationship definition for property "{0}" not found in entries of {1}::${2}. \ No newline at end of file
+ar_undefined_relation_prop = Unable to find {1}::${2}['{0}'], Active Record relationship definition for property "{0}" not found in entries of {1}::${2}.
+ar_invalid_relationship = Invalid active record relationship. \ No newline at end of file
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php b/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php
index a86fdffd..bb2cc583 100644
--- a/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php
+++ b/framework/Data/ActiveRecord/Relations/TActiveRecordHasManyAssociation.php
@@ -1,4 +1,4 @@
-<?php
+<?php
/**
* Loads base active record relations class.
@@ -75,18 +75,28 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation
$finder = $this->getContext()->getForeignRecordFinder();
$command = $this->createCommand($criteria, $foreignKeys,$indexValues,$sourceKeys);
$srcProps = array_keys($sourceKeys);
- $type = get_class($finder);
$collections=array();
foreach($command->query() as $row)
{
$hash = $this->getObjectHash($row, $srcProps);
foreach($srcProps as $column)
unset($row[$column]);
- $collections[$hash][] = $finder->populateObject($type,$row);
+ $collections[$hash][] = $this->populateObject($finder, $row);
}
$this->setResultCollection($results, $collections, array_values($sourceKeys));
}
+
+ protected function populateObject($finder, $data)
+ {
+ $registry = $finder->getRecordManager()->getObjectStateRegistry();
+ if(!is_null($obj = $registry->getCachedInstance($data, false)))
+ return $obj;
+ $gateway = $finder->getRecordManager()->getRecordGateway();
+ $type = get_class($finder);
+ $obj = new $type($data);
+ return $registry->addCachedInstance($data,$obj);
+ }
/**
* @param TSqlCriteria
@@ -145,5 +155,5 @@ class TActiveRecordHasManyAssociation extends TActiveRecordRelation
return "INNER JOIN {$refTable} ON ({$joinCondition}) AND {$index}";
}
-}
+}
?> \ No newline at end of file
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php b/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php
index e8c2ccee..4286254b 100644
--- a/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php
+++ b/framework/Data/ActiveRecord/Relations/TActiveRecordHasOne.php
@@ -18,10 +18,63 @@ Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordRelation');
/**
* TActiveRecordHasOne models the object relationship that a record (the source object)
* property is an instance of foreign record object having a foreign key
- * related to the source object.
+ * related to the source object. The HAS_ONE relation is very similar to the
+ * HAS_MANY relationship (in fact, it is equivalent in the entities relationship point of view).
*
+ * The difference of HAS_ONE from HAS_MANY is that the foreign object is singular.
+ * That is, HAS_MANY will return a collection of records while HAS_ONE returns the
+ * corresponding record.
*
+ * Consider the <b>entity</b> relationship between a Car and a Engine.
+ * <code>
+ * +-----+ +--------+
+ * | Car | 1 <----- 1 | Engine |
+ * +-----+ +--------+
+ * </code>
+ * Where each engine belongs to only one car, that is, the Engine entity has
+ * a foreign key to the Car's primary key. We may model
+ * Engine-Car <b>object</b> relationship as active record as follows.
+ * <code>
+ * class CarRecord extends TActiveRecord
+ * {
+ * const TABLE='car';
+ * public $car_id; //primary key
+ * public $colour;
+ *
+ * public $engine; //engine foreign object
+ *
+ * protected static $RELATIONS=array(
+ * 'engine' => array(self::HAS_ONE, 'EngineRecord'));
+ *
+ * public static function finder($className=__CLASS__)
+ * {
+ * return parent::finder($className);
+ * }
+ * }
+ * class EngineRecord extends TActiveRecord
+ * {
+ * const TABLE='engine';
+ * public $engine_id;
+ * public $capacity;
+ * public $car_id; //foreign key to cars
*
+ * public static function finder($className=__CLASS__)
+ * {
+ * return parent::finder($className);
+ * }
+ * }
+ * </code>
+ * The <tt>$RELATIONS</tt> static property of CarRecord defines that the
+ * property <tt>$engine</tt> that will reference an <tt>EngineRecord</tt> instance.
+ *
+ * The car record with engine property list may be fetched as follows.
+ * <code>
+ * $cars = CarRecord::finder()->with_engine()->findAll();
+ * </code>
+ * The method <tt>with_xxx()</tt> (where <tt>xxx</tt> is the relationship property
+ * name, in this case, <tt>engine</tt>) fetchs the corresponding EngineRecords using
+ * a second query (not by using a join). The <tt>with_xxx()</tt> accepts the same
+ * arguments as other finder methods of TActiveRecord, e.g. <tt>with_engine('capacity < ?', 3.8)</tt>.
*
* @author Wei Zhuo <weizho[at]gmail[dot]com>
* @version $Id$
diff --git a/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php b/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php
index a33e105e..033d7638 100644
--- a/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php
+++ b/framework/Data/ActiveRecord/Relations/TActiveRecordRelationContext.php
@@ -1,4 +1,4 @@
-<?php
+<?php
/**
* TActiveRecordRelationContext class.
*
@@ -156,9 +156,9 @@ class TActiveRecordRelationContext
Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordBelongsTo');
return new TActiveRecordBelongsTo($this);
default:
- throw new TException('Not done yet');
+ throw new TActiveRecordException('ar_invalid_relationship');
}
}
}
-
+
?> \ No newline at end of file
diff --git a/framework/Web/Javascripts/source/prado/activecontrols/ajax3.js b/framework/Web/Javascripts/source/prado/activecontrols/ajax3.js
index dbf768a6..27537e8b 100644
--- a/framework/Web/Javascripts/source/prado/activecontrols/ajax3.js
+++ b/framework/Web/Javascripts/source/prado/activecontrols/ajax3.js
@@ -424,7 +424,7 @@ Object.extend(Prado.CallbackRequest,
}
self.tryNextRequest();
}
-})
+});
/**
* Automatically aborts the current request when a priority request has returned.
@@ -664,4 +664,4 @@ Prado.Callback = function(UniqueID, parameter, onSuccess, options)
request = new Prado.CallbackRequest(UniqueID, callback);
request.dispatch();
return false;
-}
+};
diff --git a/framework/Web/Javascripts/source/prado/colorpicker/colorpicker.js b/framework/Web/Javascripts/source/prado/colorpicker/colorpicker.js
index 423338e0..746a0caf 100644
--- a/framework/Web/Javascripts/source/prado/colorpicker/colorpicker.js
+++ b/framework/Web/Javascripts/source/prado/colorpicker/colorpicker.js
@@ -114,7 +114,7 @@ Rico.Color.createFromHex = function(hexCode) {
blue = b+b;
}
return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
-}
+};
/**
* Factory method for creating a color from the background of
@@ -142,7 +142,7 @@ Rico.Color.createColorFromBackground = function(elem) {
}
else
return new Rico.Color(255,255,255);
-}
+};
Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
@@ -197,7 +197,7 @@ Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
}
return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
-}
+};
Rico.Color.RGBtoHSB = function(r, g, b) {
@@ -239,7 +239,7 @@ Rico.Color.RGBtoHSB = function(r, g, b) {
}
return { h : hue, s : saturation, b : brightness };
-}
+};
Prado.WebUI.TColorPicker = Class.create();
diff --git a/framework/Web/Javascripts/source/prado/datepicker/datepicker.js b/framework/Web/Javascripts/source/prado/datepicker/datepicker.js
index 2f1e8261..262e0c1c 100644
--- a/framework/Web/Javascripts/source/prado/datepicker/datepicker.js
+++ b/framework/Web/Javascripts/source/prado/datepicker/datepicker.js
@@ -691,6 +691,4 @@ Prado.WebUI.TDatePicker.prototype =
}
}
-
-
}; \ No newline at end of file
diff --git a/framework/Web/Javascripts/source/prado/logger/logger.js b/framework/Web/Javascripts/source/prado/logger/logger.js
index b21df1ae..a3b7be1f 100644
--- a/framework/Web/Javascripts/source/prado/logger/logger.js
+++ b/framework/Web/Javascripts/source/prado/logger/logger.js
@@ -13,7 +13,7 @@ Use it all you want. Just remember to give me some credit :)
// Custom Event
// ------------
-CustomEvent = Class.create()
+CustomEvent = Class.create();
CustomEvent.prototype = {
initialize : function() {
this.listeners = []
@@ -54,7 +54,7 @@ CustomEvent.prototype = {
return indexes
}
-}
+};
// ------
// Cookie
@@ -128,7 +128,7 @@ var Cookie = {
}
}
-}
+};
// ------
// Logger
@@ -177,7 +177,7 @@ Logger = {
this.logEntries = []
this.onclear.dispatch()
}
-}
+};
LogEntry = Class.create()
LogEntry.prototype = {
@@ -185,9 +185,9 @@ LogEntry.prototype = {
this.message = message
this.tag = tag
}
-}
+};
-LogConsole = Class.create()
+LogConsole = Class.create();
LogConsole.prototype = {
// Properties
@@ -285,7 +285,7 @@ LogConsole.prototype = {
}
var self=this;
Event.observe(document, 'keydown', function(e)
- {
+ {
if((e.altKey==true) && Event.keyCode(e) == toggleKey ) //Alt+J | Ctrl+J
self.toggle();
});
@@ -456,7 +456,7 @@ LogConsole.prototype = {
this.commandIndex = 0
}
}
-}
+};
// -------------------------
@@ -552,7 +552,7 @@ function inspect(o)
res.push(useKey + ":" + val);
}
return "{" + res.join(", ") + "}";
-}
+};
Array.prototype.contains = function(object) {
for(var i = 0; i < this.length; i++) {
@@ -560,10 +560,10 @@ Array.prototype.contains = function(object) {
}
return false
-}
+};
// Helper Alias for simple logging
-var puts = function() {return Logger.log(arguments[0], arguments[1])}
+var puts = function() {return Logger.log(arguments[0], arguments[1])};
/*************************************
@@ -740,7 +740,7 @@ Prado.Inspector =
"#so_mContainer .topLevel { margin:0; padding:0; } " +
"#so_mContainer .credits { float:left; width:200px; font:6.5pt verdana; color:#000; padding:2px; margin-left:5px; text-align:left; border-top:1px solid #000; margin-top:15px; width:75%; } " +
"#so_mContainer .credits a { font:9px verdana; font-weight:bold; color:#004465; text-decoration:none; background-color:transparent; }"
-}
+};
//similar function to var_dump in PHP, brings up the javascript object tree UI.
function var_dump(obj)
diff --git a/framework/Web/Javascripts/source/prado/scriptaculous-adapter.js b/framework/Web/Javascripts/source/prado/scriptaculous-adapter.js
index 5ace2598..96fc220a 100644
--- a/framework/Web/Javascripts/source/prado/scriptaculous-adapter.js
+++ b/framework/Web/Javascripts/source/prado/scriptaculous-adapter.js
@@ -9,7 +9,7 @@ Function.prototype.bindEvent = function()
{
return __method.apply(object, [event || window.event].concat(args));
}
-}
+};
/**
* Creates a new function by copying function definition from
@@ -26,7 +26,7 @@ Class.extend = function(base, definition)
if(definition)
Object.extend(component.prototype, definition);
return component;
-}
+};
/*
Base, version 1.0.2
@@ -175,7 +175,7 @@ Prado.PostBack = function(event,options)
/*if(options['StopEvent']) */
Event.stop(event);
Event.fireEvent(form,"submit");
-}
+};
Prado.Element =
{
@@ -346,7 +346,7 @@ Prado.Element =
{
content.evalScripts();
}
-}
+};
Prado.Element.Selection =
{
@@ -559,7 +559,7 @@ Prado.Element.Insert =
{
new Insertion.Before(element, content);
}
-}
+};
/**