Solar

Website
http://solarphp.com/
SVN
http://svn.solarphp.com/core/trunk/
Short description from authors website
Solar is a PHP 5 framework for web application development. It is fully name-spaced and uses enterprise application design patterns, with built-in support for localization and configuration at all levels.
Distributed size:
618KB tgz (1.0.0alpha2)
Graphs

Changelog (only since Jan 1, 2009)

RevisionMessageDateAuthor
3898merge from branches/hash to trunk so we have a baseline to branch from again

$ svn merge -r3884:HEAD branches/hash trunk



New Classes
-----------

* Solar_View_Helper_Number: [NEW] View helper for number display.

* Solar_View_Helper_FormLabel: Creates a label tag for a form element.

* Solar_View_Helper_FormInvalid: Creates a list of "invalid" messages for a
form element.


Solar_Class_Stack
-----------------

* [ADD] Method addByParents() to add a class and its parents to the stack.

* [ADD] Method setByParents() to set the stack to a class and its parents.


Solar_Filter
------------

* [ADD] Add the ability to configure the class stack for Solar_Filter.

* [CHG] Method setFilterClass() now uses Solar_Class_Stack::setByParents() and
includes the 'classes' config value.


Solar_Form
----------

* [FIX] Add 'request' config key and use a dependency injection for
Solar_Request, instead of using only the registered object.

* [REF] Move configuration logic from constructor to _postConfig().

* [ADD] Method getElements() to get several elements from the form at once.

* [CHG] Method addInvalid(), when the element does not exist, now adds the
message to the form feedback (instead of doing nothing).

* [CHG] Method validate() now sets the form status and feedback message using
setStatus(), instead setting directly via $this->_status and
$this->_feedback.

* [FIX] Method reset() now resets $this->_feedback to array() (vice null).

* [FIX] Method setStatus() now only resets feedback when the new status is
different from the current status. This helps where you have multiple
calls to setStatus() that all set the status to the same value (and thus
retains feedback messages between all calls).

* [REF] Add method _load() to actually load the elements discovered by the
load() method.


Solar_Form_Load_Model
---------------------

* [REF] Refactored monolithic method fetch() into series of sub-methods.
Thanks, Jeff Moore, for the significant work on this.


Solar/Locale/en_US.php
----------------------

* [ADD] Format keys for numbers.


Solar_Sql_Model
---------------

* [ADD] Methods _preSetup() and _postSetup() to remove logic from constructor.

* [CHG] Move _fixModelName sooner in the series of post setup items. This
makes the model name available to more methods. _fixModelName has only a
dependency on _fixTableName().

* [CHG] Use status constants.

* [CHG] We must use init with a STATUS_NEW parameter to generate new records
to prevent unwanted status transitions.

* [CHG] Don't pre-populate related values for new records. Allow the
fetchRelated to fetch chain to return empty values lazily. This allows new
records, after they are saved, to properly fetch their relationships. This
relies on the new improved tracking of new record status.

* [REF] Method _fixStack() now uses Solar_Class_Stack::setByParents().


Solar_Sql_Model_Record
----------------------

* introduce a new property for tracking the invalid status of a record. This
allows us to retain the information that the record is "New" after its been
validated. Otherwise, unwanted status transitions can occur, such as
new->invalid->dirty at which point save() will attempt an update instead of
an insert. Login in setStatus, getStatus and isInvalid emulate prior
behavior.

* Prevent invalid status changes to and from the status of new.

* Add a function to determine if a record is considered new.

* We don't need special logic in __set to keep a new record from becoming
dirty. That logic is handled in setStatus().

* Now that we are correctly remembering when we are a new record, we can
prevent operations on new records that don't make sense. We may be able to
perform this operations successfully in some way, but the current
implementation is not correct, so we simply throw an exception for now.

* Route more status setting through setStatus().

* Since we not longer attempt to propigate status across relationship, we
don't need to save and restore the status. Thus, we can eliminate the
inappropriate touching of the $_status property.

* Fix a bug causing incorrect values to be placed in autoinc columns. The bug
is caused when a value is set to an autoincrement column before inserting.
This causes that value to be used, rather than the sequence number and the
insert() method returns true instead of an id. This might happen, for
example if an auto increment column was also set as a sequence column.

* [FIX] In setStatus(), don't use 'new'.

* Make sure we don't turn invalid forms into valid forms, erasing feedback.

* Prevent infinite recursion in the getInvalid chain.

* Make sure we chain invalid messages from related records that fail
validation into a top level form feedback.

* We have to look at the relationship object to know that its a belongsTo.

* [CHG] In method form(), now that Solar_Form::addInvalids() will retain
non-element messages as form-level feedback, no longer has separate logic
to add form-level feedback on elements not in the form.


Solar_Sql_Model_Related
-----------------------

* Switch from testing against isNew() to supress relationship loading to
testing against the native column. If that column is undefined or is null,
we will presume that there is no relationship and return the appropriate
empty value. If the value is defined, then we will go ahead and issue a
query to make that determination. This serves too roles. This is an
optimization that can prevent certain queries from making it to the DB. This
is also a feature enhancement that allows relations to be traversed (most
likely belongs To) before a new record is saved. It opens up the opportunity
to do more advanced validation during the save process.

* Fix a (serious) bug where queries would be built that would return
unexpectedly incorrect results.

* Fix a bug where client side joins could not be executed because the keys
were not being properly collected.

* Fix a bug in building queries with eager and bound values.


Solar_Sql_Model_Related_ToMany
------------------------------

* Don't pre-populate related values for new records. Allow the fetchRelated to
fetch chain to return empty values lazily. This allows new records, after
they are saved, to properly fetch their relationships. This relies on the
new improved tracking of new record status.

* Switch from testing against isNew() to supress relationship loading to
testing against the native column. If that column is undefined or is null,
we will presume that there is no relationship and return the appropriate
empty value. If the value is defined, then we will go ahead and issue a
query to make that determination. This serves too roles. This is an
optimization that can prevent certain queries from making it to the DB. This
is also a feature enhancement that allows relations to be traversed (most
likely belongs To) before a new record is saved. It opens up the opportunity
to do more advanced validation during the save process.

* Fix a (serious) bug where queries would be built that would return
unexpectedly incorrect results.

* Fix a bug where client side joins could not be executed because the keys
were not being properly collected.


Solar_Sql_Model_Related_ToOne
-----------------------------

* Don't pre-populate related values for new records. Allow the fetchRelated to
fetch chain to return empty values lazily. This allows new records, after
they are saved, to properly fetch their relationships. This relies on the
new improved tracking of new record status.

* Switch from testing against isNew() to supress relationship loading to
testing against the native column. If that column is undefined or is null,
we will presume that there is no relationship and return the appropriate
empty value. If the value is defined, then we will go ahead and issue a
query to make that determination. This serves too roles. This is an
optimization that can prevent certain queries from making it to the DB. This
is also a feature enhancement that allows relations to be traversed (most
likely belongs To) before a new record is saved. It opens up the opportunity
to do more advanced validation during the save process.

* Fix a (serious) bug where queries would be built that would return
unexpectedly incorrect results.

* Fix a bug where client side joins could not be executed because the keys
were not being properly collected.


Solar_Sql_Model_Related_HasManyThrough
--------------------------------------

* Fix a (serious) bug where queries would be built that would return
unexpectedly incorrect results.

* Fix a bug where client side joins could not be executed because the keys
were not being properly collected.

* Fix a bug in building queries with eager and bound values.

* Change the through table join from a left join to an inner join. The inner
join produces a better query plan and does not change the results of the
query.


Solar_Sql_Model_Select
----------------------

* [ADD] Method _validateEager() to change merging strategies as needed.


Solar_Sql_Select
----------------

* [FIX] Fix a bug in fromSelect when using bound queries.

* [FIX] Stop putting junk in the list of values to bind if the key is empty.

* [ADD] Method innerJoinSelect().

* [ADD] Method _prepareSubSelect() to reduce repetition.

* [REF] Method fromSelect() now uses _prepareSubSelect().

* [REF] Method innerJoinSelect() now uses _prepareSubSelect().

* [ADD] Method leftJoinSelect().


Solar_Struct
------------

* [ADD] Method isDirty() for checking status.


Solar_View_Helper_Anchor
------------------------

* [BRK] Change the behavior of anchor view helper to always return an anchor.
If no text parameter is passed or if the text parameter is empty, then the
href will be used as the anchor text.


Solar_View_Helper_Form
----------------------

* [REF] Move config setup out of constructor and into _postConfig().

* [CHG] Building of feedback and hidden elements now occurs in _buildStack(),
not fetch().

* [BRK] Changed several config elements: removed 'descr_elem', 'descr_label',
and 'descr_value' in favor of new 'descr_part'. Removed 'descr_tag' in favor
of new decorator key 'descr'. Removed 'descr_class' and 'invalid_class' in
favor of $_css_class keys 'descr' and 'invalid', respectively. Added
'decorators' to allow custom decorator tags, 'css_classes' to override the
default CSS classes, and 'label_suffix'.

* [BRK] Removed properties $_descr_tag, $_descr_class, $_descr_elem,
$_label_tag, $_value_tag, $_element_tag, $_element_list_tag, $_begin_tag,
$_invalid_class, $_show_label, $_show_value.

* [ADD] Property $_decorator to note decorator tags around parts of the form.
Replace all use of previous decorator properties ($_label_tag, $_value_tag,
et al.) with with use of appropriate $_decorator keys and values.

* [ADD] Method setLabelSuffix() and property $_label_suffix to set a suffix
string (e.g., ": ") on all labels.

* [ADD] Method setDescrPart() and property $_descr_part to note in which part
the element description goes ('label' or 'value').

* [ADD] Methods setCssClass() and setCssClasses() to set $_css_class values.

* [ADD] Methods setDecorator() and setDecorators() to set $_decorators values.

* [ADD] Methods decorateAsDlList(), decorateAsTable(), and decorateAsPlain()
to set decorators.

* [CHG] Method _buildBegin() and _buildEnd() always show the form tag.

* [REF] Add methods _buildElementBegin() and _buildElementEnd() to reduce
repetition.

* [CHG] Method _buildElementLabelInfo() now prepares attributes for the label
helper, including CSS classes for 'require' and 'invalid'.

* [CHG] Instead of building labels internally, use the formLabel() helper.

* [CHG] Instead of building the list of invalid messages internally, use the
formInvalid() helper.


Solar_View_Helper_FormPassword
------------------------------

* [BRK] Update password helper with security options. Passwords values should
not be echoed back between requests. Additionally indicate that browsers
should not remember a password. Options are set to default on, despite
potential BC concerns. Higher security by default is better.


Solar_View_Helper_TypekeyLink
-----------------------------

* [CHG] Allow the adding of attributes to the anchor created.

* [CHG] Add backward compatibility to typekeylink helper regarding new anchor
helper changes where the href is returned if no text is specified.

* [FIX] The Typekey API changed. Typekey redirects from https to the same url
in http. If you pass port 443, typekey constructs the url as
http:/www.typekey.com:443/ This url is incorrect, the wrong protocol on the
wrong port. This is a bug in typekey, but changing the link generator to
compensate.
22.07.2009 15:33:45pmjones
3897svn property changes22.07.2009 13:47:56pmjones
3892merging branches/page to trunk

$ svn merge -r3882:HEAD branches/page trunk

Changes (and a break) to Solar_Controller_Page and Solar_App_Base.

These are things from Solar_App_Base that are useful in lots of apps, and add
some conveniences for error handling and "not found" sitiuations.



Solar_Controller_Page
---------------------

* [ADD] Added these directories and files:

Layout/ # baseline layouts
default.php # simplest possible HTML layout
View/ # baseline views
_errors.php # partial for listing errors
error.php # generic application error template
exception.php # generic server error template
notFound.php # generic "page/action not found" template

These will allow you to extend a page controller directly from
Solar_Controller_Page, with baseline layouts and views included.

- [DEL] Properties $controller and $action have been removed, leaving the
$_action and $_controller public properties in place. The controller and
action values are now populated into the template "manually" in the
_preRender() method.

- [ADD] Property $_errors to retain error messages.

- [CHG] Method _preRender() now populates $_controller, $_action, $_layout,
and $_errors "manually" into the template as $controller, $action, $layout,
and $errors.

- [CHG] Because a default layout is available, the $_layout_default property
is now 'default' (vice null).

- [BRK] Method _notFound() no longer throws an exception by default. Instead,
it fills $_errors with the action and params values, sets the view to
'notFound', and sets the response status code to 404. This behavior also
makes the _notFound() method useful for action error reporting.

- [BRK] Method _exceptionDuringFetch() no longer re-throws the exception.
Instead, it retaing the exception as an error, sets the view to 'exception',
sets the response status code to 500, and renders the view and layout
directly by calling _render().

- [ADD] Empty method actionError() for error display.

- [ADD] Method _error() to add an error and forward to the error action.


Solar_App_Base
--------------

- [BRK] Public property $layout, as protected $_layout is pushed into the view
by Solar_Controller_Page::_preRender() now.

- [BRK] Public property $errors, as protected $_errors is pushed into the view
by Solar_Controller_Page::_preRender() now. This means you need to change
from setting $this->errors to $this->_errors.

- [DEL] Method actionError(), as it is now in Solar_Controller_Page.

- [DEL] Method _error(), as it is now in in Solar_Controller_Page.

- [DEL] Method _notFound(); now using the default from Solar_Controller_Page.

- [DEL] Method _exceptionDuringFetch(); now using the default from
Solar_Controller_Page.


Solar_Cli_MakeApp
-----------------

- [CHG] Now defaults to extending Solar_Controller_Page, not Solar_App_Base.



22.07.2009 00:19:59pmjones
3880Solar_Sql_Adapter_Sqlite: [FIX] Now discovers autoin cols quoted with brackets, backticks, and single quotes (as well as double quotes). Thanks, Anthony Gentile, for the report that led to this fix. (Fixes #190.)14.07.2009 14:51:30pmjones
3865Solar_Sql_Model: [FIX] In method insert(), return last insert id even when the autoinc column is not represented in the data. Thanks, Anthony Gentile, for the report that led to this fix.26.06.2009 17:22:42pmjones
3858comment changes25.06.2009 22:57:34pmjones
3857Solar_Mail_Message: [FIX] Set the encoding properly in the constructor, instead of re-setting charset. Thanks, Clay Loveless, for the report.

fixes #189
25.06.2009 22:00:22pmjones
3856Solar_Cli_MakeDocs: [FIX] In writeClassConfig(), show "None" when there are no config keys.25.06.2009 19:54:51pmjones
3855Solar_Cli_MakeDocs: [CHG] Add config keys for class_dir and package_dir so they can be controlled via config file; cli options are no longer required.25.06.2009 19:42:26pmjones
3854Solar_Sql_Model: [FIX] Method _fixSelectParams() is protected, not public.25.06.2009 19:41:21pmjones
3853Solar_Base: [FIX] Method _postConfig() is protected, not public.

Also, standardizing constructor comments.
25.06.2009 19:40:31pmjones
3852Solar_Cli_MakeDocs: [CHG] Method _writeClassContents() now has a line for 'Config'.25.06.2009 01:14:06pmjones
3851remove unused config key comment24.06.2009 20:36:30pmjones
3850mass docblock update to start using @config tags for configuration keys24.06.2009 20:18:27pmjones
3849Solar_Cli_MakeDocs: Add support for config key documentation.

* [CHG] Method _writeOverview() now write a 'Configuration' section with a list of config keys.

* [ADD] Method _writeClassConfig() to document the configuration keys.
24.06.2009 15:51:24pmjones
3848Solar_Docs_Apiref: [ADD] Method _addConfigKeys() to add config keys to the API array.24.06.2009 15:49:00pmjones
3847Solar_Docs_Phpdoc: [ADD] Method parseConfig() to support parsing of non-standard @config tag (for Solar configuration key descriptions).24.06.2009 15:32:20pmjones
3838Solar_Model_Nodes_Record: [FIX] In method _postDelete(), use deleteAll(), not just delete(), on the taggings collection.18.06.2009 23:50:36pmjones
3837Solar_App_Bookmarks: [FIX] In method actionAdd(), when redirecting, set a 'success_added' flash value (vs 'add_ok').18.06.2009 23:49:52pmjones
3835More docblock updates; thanks, Anthony Gentile, for pointing out the lack.12.06.2009 20:05:36pmjones
3833Add/fix comments; thanks, Anthony Gentile, for the nagging.12.06.2009 02:18:00pmjones
3772Change how Struct objects (including records) track parentage and status, and fixes/changes internal to records; thanks, Jeff Moore.

$ svn merge --revision=3763:3770 branches/dirty trunk


Solar_Struct
------------

* [DEL] Remove all properties, method, and logic related to setting parent
structs. Affects $_parent, setParent(), getParent(), setStatus(), free(),
and __set(). Now only XML-structs attempt to set status on their parents.


Solar_Struct_Xml
----------------

* [ADD] Add all properties, method, and logic related to setting parent
structs that were previously in Solar_Struct. Affects $_parent, setParent(),
getParent(), setStatus(), free(). Note that __set() **does not** set the
parent automatically; you need to call setParent() explicitly when adding
child XML-structs.


Solar_Sql_Model_Collection
--------------------------

* [CHG] Per changes in Solar_Struct parent and status tracking, methods
__get() and appendNew() no longer set the collection as parent to the
record.


Solar_Sql_Model_Record
----------------------

* [CHG] Per changes in Solar_Struct parent and status tracking, method init()
now explicitly sets the record as parent to XML-struct objects.

* [CHG] Per changes in Solar_Struct parent and status tracking, method
newRelated() no longer sets the record as parent to the new related record
or collection.

* [CHG] Method load() no longer attempts to unserialize columns. This is line
with the idea that load() is usually being called with data already in
the expected "usable" format, not a serialized format (e.g., from a POST
operation).

* [CHG] Clarify when record operations should use property acccess and thus
trigger accessor methods versus when the record may access the data values
directly. The $_data array represents the state of the object as saved to
the DB (Except for serialized cols). Accessor methods may provide an
alternative external view of that data.

Internally, all marshalling between the DB and the Record takes place via
the $_data array and does not trigger accessor methods. Detecting changed
values also takes place on the level of $_data. All other access should use
accessor methods and $this->col or $this->$col style access.

Affects methods _modInsert(), _modUpdate(), refresh(), setStatus(), and
isChanged().


Solar_Sql_Model_Related_BelongsTo
---------------------------------

* [BRK] Method save() **no longer saves the belonged-to object**. This is to
prevent infinite recursions.


Solar_Sql_Model_Related_ToOne
-----------------------------

* [CHG] Method _extractDependentOne() now returns null, not array(), when
there is no related record.

* [CHG] Methods joinOne() and joinAll() now correctly handle null records in
a left join.


30.05.2009 16:11:42pmjones
3761Solar_Sql_Model_Related, ToOne, ToMany: [ADD] Method fetchNew() to support explicit fetching of new records/collections. (This should have been part of the merge; thanks to Jeff Moore for discovering the error.)

27.05.2009 18:20:20pmjones
3759Solar_Sql_Model and Solar_Sql_Model_Record: MAJOR BC BREAK FOR MODEL

Make the Model object less active, and the Record object more active. This
puts all the major modification behaviors inside the Record object, and
removes special checking behaviors from the Model insert/update routines,
thereby making the logic easier to trace through. The order of events is
preserved, but there are some major BC breaks, notably to the returns from
Model::insert() and Model::update(). See below for new logic sequences.

Note that although this breaks Model insert/update/delete behavior, the Record
insert/update/delete behavior should be effectively unchanged.


Solar_Sql_Model
---------------

* [BRK] Method insert() dramatically changed to be much less active. Almost
all special behaviors have been moved to the Record class. Of note, returns
the last inserted ID, not the data as inserted, on success.

* [BRK] Method update() dramatically changed to be much less active. Almost
all special behaviors have been moved to the Record class. Of note, returns
the number of affected rows, not the data as updated, on success.

* [CHG] Method delete() now returns the number of affected rows on success.

* [CHG] In method unserializeCols(), don't attempt to unserialize columns that
aren't there.

* [CHG] In method serializeCols(), do not attempt to serialize a column that
does not exist in $data. Additionally, use NULL as a canonical value for any
empty value that you attempt to serialize. (As unserializeCols() cannot
correctly unserialize empty values such as "", 0, or false.)


Solar_Sql_Model_Record
----------------------

* [ADD] Method _modInsert() to modify record data before insertion.

* [ADD] Method _getInsertData() to get a array copy of the record data to send
to the Model::insert() method.

* [CHG] Method _insert() now handles the special behaviors that used to be in
Model::insert(). No longer calls refresh() after an insert.

* [ADD] Method _modUpdate() to modify record data before updateion.

* [ADD] Method _getUpdateData() to get a array copy of the record data to send
to the Model::update() method.

* [CHG] Method _update() now handles the special behaviors that used to be in
Model::update(). No longer calls refresh() after an update.

* [CHG] Simplify the load() method by setting values directly, causing __set()
to handle accessor methods and change tracking.

* [REV] In method init(), revert back to only creating placeholders for
calculate-cols, *not* for all table and calculate cols. This is because
setting placeholders for table cols makes it hard to tell if the cols were
actually fetched from the table. Thanks to Jeff Moore for pointing this out.

* [CHG] Method newRelated() now calls Related::fetchNew(), vice newObject(),
so that we get an actual new record/collection.

* [CHG] Because of the change in newRelated() above, method _fixRelatedData()
now calls Related::newObject() directly, since its purpose is to fill in
existing related data (if any).


Record::_insert() Logic
=======================

Old | New
--------------------------------------------------------------- | ---------------------------------------------------
- Record::_preInsert() | - Record::_preInsert()
- Model::insert() | - Record::_modInsert()
- modify created | - modify created
- modify updated | - modify updated
- modify inherit | - modify inherit
- modify sequence | - modify sequence
- Record::filter() | - Record::filter()
- Model::serializeCols() | - Record::_getInsertData()
- remove non-table cols and empty autoinc cols | - copy only table cols
- Sql::insert() | - Model::serializeCols()
- Model::unserializeCols() | - Model::insert()
- modify autoinc value | - remove non-table cols and empty autoinc cols
- Cache::deleteAll() | - Sql::insert()
- Record::refresh() | - Cache::deleteAll()
- Record::setStatus() | - return last-insert-id
- return $data | - modify autoinc value
- Record::_postInsert() | - Record::setStatus()
- (done) | - Record::_postInsert

Major differences:

- Model::insert() is much less active now; the only thing it does to the data
is remove non-table columns. No more created, updated, inherit, etc. This
makes it more a TableDataGateway than a TableModule. It also takes only data
arrays, not record objects.

- The data modifications (created, updated, etc) now apply to the record data
directly via Record::_modInsert(). This makes the Record more "active" than
previous.

- The record sends a copy of its data array to Model::insert(). The copy is
what Model::serializeCols() operates on, not the record data itself. This
means we don't need to unserialize afterwards.

- We no longer call Record::refresh() after an insert. This is because the
record data has already been modified.

- Model::insert() returns the last inserted id, or true if there are no
autoinc cols, *not* the array of data as inserted.


Record::update() Logic
======================

Old | New
--------------------------------------------------------------- | -----------------------------------------------------
- Record::_preUpdate() | - Record::_preUpdate()
- Model::update() | - Record::_modUpdate()
- modify updated | - modify updated
- modify inherit | - modify inherit
- modify sequence | - modify sequence
- Record::filter() | - Record::filter()
- Record::serializeCols() | - Record::_getUpdateData()
- retain only changed cols | - copy only table cols that have changed
- if no changed cols, Record::refresh() and return | - Model::serializeCols()
- unset primary key | - If no changed cols, Record::setStatus() and return
- remove non-table cols | - Model::update()
- Sql::update() | - unset primary key
- Model::unserializeCols() | - remove non-table cols
- Cache::deleteAll() | - Sql::update()
- Record::refresh() | - return count of affected rows
- return $data | - Record::setStatus()
- Record::_postUpdate() | - Record::_postUpdate()


Major differences:

- Model::update() is much less active now; the only thing it does to the data
is remove non-table columns. No more created, updated, inherit, etc. This
makes it more a TableDataGateway than a TableModule. It also takes only data
arrays, not record objects.

- The data modifications (updated, inherit, etc) now apply to the record data
directly via Record::_modUpdate(). This makes the Record more "active" than
previous.

- The record sends a copy of its data array to Model::update(). The copy is
what Model::serializeCols() operates on, not the record data itself. This
means we don't need to unserialize afterwards.

- We no longer call Record::refresh() after an insert. This is because the
record data has already been modified.

- Model::update() returns the number of affected columns, *not* the data as
updated.
27.05.2009 01:49:24pmjones
3749Solar_Sql_Model_Record: [REV] Revert earlier change regarding placeholders; only hold places for calculate cols, not all table cols. Thanks, Jeff Moore, for pointing out the flaws in the change.17.05.2009 02:07:36pmjones
3748Solar_Mail_Message

* [ADD] Property $_encoding, config key 'encoding', and methods setEncoding() and getEncoding() to allow setting of the encoding value (previous locked at 'quoted-printable'). New default is '8bit'.

* [CHG] Methods setText() and setHtml() now use $this->_encoding instead of being locked to 'quoted-printable'.
17.05.2009 02:02:07pmjones
3744Solar_Form_Load_Model: [FIX] Don't include xmlstruct_cols in the default list ('*') of columns for forms. Thanks, Jeff Moore, for the patch.15.05.2009 21:32:48pmjones
3743Solar_Sql_Model_Record

* [FIX] Method _saveRelated() now retains the existing record status and resets it properly after saving relateds (which cascade their status changes up the parent chain).

* [CHG] Method form() now sends $this, not $this->toArray(), when calling $form->setValues(). This is in line with Solar_Form::setValues() now accepting a Solar_Struct as a data source.
15.05.2009 21:07:54pmjones
3742Solar_Form: [CHG] Method setValues() can now accept a Solar_Struct object (such as a model record) in addition to an array as the data source. Thanks, Jeff Moore, for the original patch.15.05.2009 21:04:14pmjones
3741Solar_Cli_MakeVendor: [FIX] Method _createSymlinks() now creates *relative* symlinks, not absolute ones. Thanks, Nicholas Sloan, for the report that led to this fix.15.05.2009 01:34:31pmjones
3740Solar_Sql_Model_Related_ToOne: [CHG] Method newObject(), when $data is empty, now uses Model::fetchNew() to create a new record; when $data is not empty, uses Model::newRecord().13.05.2009 20:27:02pmjones
3739Solar_Sql_Model_Record: [FIX] In method init(), make sure we have all table and calculate cols from the outset.13.05.2009 16:25:17pmjones
3738Solar_Form: [FIX] Method addInvalid() now uses setStatus() to set the form status to invalid. Thanks, Jeff Moore, for the fix.07.05.2009 20:53:18pmjones
3737Solar_Sql_Model_Record

* [CHG] Method isChanged() can now be called without a $col parameter to tell if any of the initial values at all have changed.

* [FIX] Method load() only sets the status to dirty when the record has changed as a result of the load (prev. would cause an update even if no changes). Thanks, Jeff Moore, for the report leading to this fix.
07.05.2009 19:41:47pmjones
3736Solar_Sql_Model_Record: [FIX] In method load(), force the record status to dirty so we know to save it later.06.05.2009 15:34:11pmjones
3735Solar_Sql_Model_Record: [FIX] Method init() now correctly sets placeholders for calculated columns. Forms trying to use those columns need to have them available immediately.
05.05.2009 20:12:16pmjones
3734force boolean return01.05.2009 21:40:10pmjones
3733Solar_Auth_Adapter: [ADD] Method isAllowed() to check if authentication is allowed or not. Per request from Jeff Moore.01.05.2009 21:39:48pmjones
3732whitespace and comment fixes
29.04.2009 17:27:56pmjones
3731whitespace changes29.04.2009 17:14:01pmjones
3730tests: now that Solar_Test_Suite looks for config.php automatically, rename Solar.config.php to just config.php28.04.2009 01:36:07pmjones
3729comment change28.04.2009 01:35:25pmjones
3728Solar_Test_Suite: auto-discover test-config files. Thanks to Anthony Gentile for prompting these changes.

* [ADD] Method _fetchTestCaseConfig(), given a test class name, searches various locations for the test config. Order of precedence is: the --test-config value; $system/config/test/Vendor.config.php; $system/source/vendor/tests/config.php; none.

* [CHG] Method run() now uses _fetchTestCaseConfig() for each test class, and logs a diagnostic line to indicate what config file is being used for the test case.
28.04.2009 01:34:50pmjones
3727Solar: [CHG] In method exception(), use the new Solar_Class::vendor() logic instead of local code to discover the vendor name.28.04.2009 01:30:10pmjones
3726Solar_Locale: [CHG] In method fetch(), use the new Solar_Class::vendor() logic instead of local code to discover the vendor name.28.04.2009 01:29:34pmjones
3725Solar_Controller_Page: [CHG] In method _addViewHelpers(), use the new Solar_Class::vendor() logic instead of local code to discover the vendor name.28.04.2009 01:28:52pmjones
3724Solar_Sql_Model_Catalog: [CHG] In method _setStack(), use the new Solar_Class::vendor() logic instead of local code to discover the vendor name.28.04.2009 01:28:13pmjones
3723Solar_Class: [ADD] Method vendor() to return the vendor portion of a class name.
28.04.2009 01:04:26pmjones
3722comment fix27.04.2009 20:02:46pmjones
3721Solar_Sql_Model_Record: [FIX] In method_preSave(), track and retain invalidity of relateds. Because each related status chains back up to the record, a later valid related used to overwrite an earlier invalid related, which is not what we want. Any invalid related means the record is invalid as a result.23.04.2009 20:27:35pmjones
3720Solar_Sql_Model_Collection: [FIX] In method __get(), make sure the records in the collection have the collection as their parent.23.04.2009 20:25:11pmjones
3719Solar_Sql_Model_Related: [ADD] Method isInvalid() to check validity of relateds; most useful with has-many-through.23.04.2009 20:20:41pmjones
3718Solar_Sql_Model_Record: report validation failure messages on relateds.

* [CHG] Method save() now reports success/failure based on record validity, *not* based on merely passing through _save() and _saveRelated() without exception.

* [CHG] Method getInvalid() now returns validation failure messages for all related records and collections.

* [ADD] Method _getInvalid() to collect validation failure messages on relateds.

* [ADD] Method isInvalid() as a shorthand for $_status == self::STATUS_INVALID.
23.04.2009 19:23:28pmjones
3717Solar_Sql_Model_Collection: add support for reporting invalid records after saving a collection.

* [ADD] Property $_invalid_offsets and method getInvalidOffsets() to find the
offset numbers of invalid records (populated at save() time).

* [CHG] Method save() now tracks if record saves are valid or not, and retains
the offsets.

* [CHG] Method save() now returns boolean true if all saved records were
valid, or false if any of them were invalid.

* [ADD] Method getInvalid() returns an array of all invalid messages for all
invalid records in the collection, keyed by record offset.

* [ADD] Method getInvalidRecords() returns an array of all invalid records
in the collection.
23.04.2009 19:14:00pmjones
3716Solar_Sql_Model_Related_BelongsTo: [CHG] In method _preSave(), add 'name' to the exception info.23.04.2009 16:33:53pmjones
3715comment change22.04.2009 14:49:06pmjones
3714Solar_Sql_Model: [FIX] In _fixSelectParams(), always call _fixSelectParamsEager(). Thanks, Jeff Moore, for finding this bug.21.04.2009 22:52:10pmjones
3713Solar_Markdown_Wiki_Link

* [CHG] The sprintf() formatting for interwikis now allows for 2 more placeholders (in addition to the existing combined page+fragment placeholder): one for the page name, and one for the fragment.

* [CHG] The sprintf() formatting for wiki links now allows for 2 more placeholders (in addition to the existing combined normalized page+fragment placeholder): one for the normalized page name, and one for the fragment.

Thanks, Dmytro Konstantinov, for these improvements.
21.04.2009 21:50:02pmjones
3712update text21.04.2009 21:37:40pmjones
3711Solar_Cli_Base: [CHG] In help text, use bold instead of black for the 'Usage' line. Thanks, Dmytro Konstantinov, for the patch.21.04.2009 21:36:12pmjones
3710Solar_Cli_Help: [CHG] In info text, use bold instead of black for the 'Usage' line. Thanks, Dmytro Konstantinov, for the patch.21.04.2009 21:35:19pmjones
3709Solar_Model_Tags_Collection: [CHG] Use removeOne() instead of unset() when removing an unused tag.21.04.2009 21:32:33pmjones
3708Solar_Sql_Model_Filter_ValidateUnique: [CHG] Per talk w/Jeff Moore, add logic to check if we're validating the primary key.21.04.2009 15:00:09pmjones
3707updated comments21.04.2009 14:59:10pmjones
3706update comments21.04.2009 14:57:33pmjones
3705Solar_Sql_Model_Record: [CHG] Method filter() now takes a single param, $filter, so you can inject your own filter. Request per Jeff Moore.20.04.2009 22:01:09pmjones
3704Solar_Sql_Model_Collection: [FIX] In method getRecordOffset(), honor integer-zero offsets.20.04.2009 19:42:01pmjones
3703Solar_Sql_Model_Collection: [FIX] Triple-equals only works if the objects being compared are references to the same instance, which makes it not-useful in too many cases. Instead, compare by primary key and class name.20.04.2009 19:34:55pmjones
3702bugfix20.04.2009 19:30:33pmjones
3701Solar_Sql_Model_Related: [CHG] Apply array_unique() to all $collection->getPrimaryVals() calls.20.04.2009 19:25:04pmjones
3700Solar_Sql_Model_Collection

* [CHG] Method getPrimaryVals() now returns key-value pairs where the key is the offset in the collection, and the value is the primary value. Values are no longer subjected to array_unique() before returning.

* [FIX] Method deleteAll() now deletes by element offset, instead of by record primary value.

* [ADD] Method getRecordOffset(). Given a record object, this will return the offset value for that record (if any) inside the collection.

* [CHG] Method deleteOne() now accepts a record *or* an offset value as its parameter.

* [ADD] Method removeAll() to remove all records from the collection **without deleting them**.

* [ADD] Method removeOne() to remove a record from the collection **without deleting it**.

20.04.2009 19:24:15pmjones
3699Solar_Sql_Model_Record: [BRK] Change from protected _newFilter() to public newFilter() to allow for external validation processes. Per request of Jeff Moore.20.04.2009 16:24:58pmjones
3698Solar_Sql_Model_Collection: [FIX] Method getColVals() no longer iterates over $this to collect values; instead, iterates over $this->_data, so as not to screw up external iterators.
18.04.2009 02:18:22pmjones
3697Solar_Model_Tags_Collection: [FIX] Method setNames() now correctly removes all tags, not just every-other one.

This is where SPL iterators (at least the way we're using them) become trouble. If you are iterating over $this internally, it will interact with *external* iterators because iteration properties are all on the same instance. Thus, to iterate over $this internally, you have to clone($this) and use the clone for iteration, while performing any necessary actions on $this. Confusing and unintuitive, until you remember how SPL iterators work. Perhaps there is some better implementation that I'm currently unaware of.
18.04.2009 02:07:00pmjones
3696Solar_Filter: allow whitelisting of data keys in the filter chain.

* [ADD] Method setChainWhitelist() and property $_chain_whitelist to set the whitelist of data keys for the filter chain to work with.

* [CHG] Method applyChain() now honors the chain whitelist of data keys.
18.04.2009 01:47:04pmjones
3695Solar_Example_Model_Comments: [NEW] A simple comments model for has-many testing on nodes.18.04.2009 01:16:20pmjones
3694Solar_Model: update models to take advantage of new functionality

Solar_Model_Areas
-----------------

* [REF] Rebuilt using `solar make-model`.


Solar_Model_Bookmarks
---------------------

* [REF] Rebuilt using `solar make-model`.


Solar_Model_Nodes
-----------------

* [REF] Rebuilt using `solar make-model`.


Solar_Model_Nodes_Record
------------------------

* [REF] Move all significant __getTagsAsString() logic to the
Solar_Model_Tags_Collection class.

* [REF] Move all significant __setTagsAsString() logic to the
Solar_Model_Tags_Collection class.

* [DEL] Method _postSave(). The automatic connection of mapping records and
the new Solar_Model_Tags_Collection logic now takes care of all the previous
logic.


Solar_Model_Taggings
--------------------

* [REF] Rebuilt using `solar make-model`.


Solar_Model_Tags
----------------

* [REF] Rebuilt using `solar make-model`.


Solar_Model_Tags_Collection
---------------------------

* [ADD] Method setNames() to set all records in the collection to a list of
tag names. Automatically adds and removes tags from the collection based
on the new list of names.

* [ADD] Method getNamesAsString() to return a space-separated list of tag
names in the collection.
18.04.2009 01:14:41pmjones
3693Solar_Sql_Model_Related: various fixes and additions

Solar_Sql_Model_Collection
--------------------------

* [FIX] Method appendNew() now correctly sets the parent on the new record.


Solar_Sql_Model_Record
----------------------

* [ADD] Method newRelated() to create a new object from a named relation,
optionally with initial data.

* [CHG] Method _fixRelatedData() now checks uses the newRelated() method,
and checks for empty data as well.


Solar_Sql_Model_Related_HasManyThrough
--------------------------------------

* [CHG] In method save(), use the new Record newRelated() method to get an
empty "through" collection, instead of doing things the hard way.

* [FIX] When deleting an existing "through" mapping, use the element position
of the related record in the collection, *not* the primary value of that
record.


Solar_Sql_Model_Related_ToOne
-----------------------------

* [CHG] Method newObject() now always returns an object, instead of possibly
an empty value.

* [CHG] Check-for-empty logic moved out of newObject() and into method
fetch().


Solar_Sql_Model_Related_ToMany
------------------------------

* [CHG] Method newObject() now always returns an object, instead of possibly
an empty value.

* [CHG] Check-for-empty logic moved out of newObject() and into method
fetch().


Solar_Struct
------------

* [FIX] Method appendNew() now sets the parent on the new value, when the
value is itself a Solar_Struct.

18.04.2009 01:03:56pmjones
3692comment change18.04.2009 00:54:00pmjones
3691Solar_Auth_Adapter

* [REF] Move all process-login logic from start() to processLogin().

* [REF] Move all process-logout logic from start() to processLogout().

* [ADD] Config keys for 'login_callback' and 'logout_callback', and add hooks for these to be called in processLogin() and processLogout() respectively. This will help to add behavior to login/logout without having to extend adapters directly. Thanks, Jeff Moore, for the suggestion leading to this feature.

*
17.04.2009 01:10:18pmjones
3690Solar_Role_Adapter: Change to use a cache-based approach, as vs a direct session-based approach. Session cache adapter is used by default. No known BC breaks. Per talks with Jeff Moore.


Solar_Role_Adapter
------------------

* [ADD] Config key 'cache' for the cache dependency injection, and property $_cache for the object.

* [DEL] Config key 'session_class' (obviated by the cache prefix value) and the $_session property.

* [CHG]Uses $_cache->fetch() instead of $_session->get(), and $_cache->save() instead of $_session->set(), throughout.

* [CHG] Method setList() now only sets the list of roles if the new list is *not* identical to the existing list.

* [CHG] Methods add() and addList() now fetch from the cache, add to the fetched data, and re-save the data, since we can no longer access the array directly.
17.04.2009 00:58:32pmjones
3689Solar_Auth_Adapter: BC BREAK, read below.

Change to use a cache-based approach, as vs a direct session-based approach. Session cache adapter is used by default.

The only BC break is changing from getFlash() to getStatusText() in your views, and a change to Solar_App_Base in this commit takes that into account.

Per talks with Jeff Moore.


Solar_Auth_Adapter
------------------

* [ADD] Config key 'cache' as a dependency injection; default is to use the Solar_Cache_Adapter_Session class to keep things in a session.

* [DEL] Config key 'session_class'; it is obviated by the cache adapter 'prefix' value.

* [ADD] Property $_cache for the cache object.

* [DEL] Property $_session.

* [CHG] Use $_cache->save() instead of $_session->set(), and $_cache->fetch() instead of $_session->get(), throughout the class.

* [CHG] In method reset(), because we no longer have a session object, check session_id() and regenerate the session ID directly, but only if a session already exists.

* [BRK] Remove method getFlash(). This was used exclusively to get the session value for 'status_text'. Change to the new getStatusText() method in its place.


Solar_App_Base
--------------

* [CHG] In the _auth layout partial, use getStatusText() instead of getFlash() to get the auth message.

17.04.2009 00:51:15pmjones
3688Solar_Filter: make it possible to get back untranslated messages

* [CHG] Method setChainLocaleObject() now allows null (to indicate $this), false (to indicate "no translation"), in addition to the previous allowance of any Solar_Base object. Now throws an exception if you pass a non-Solar_Base object, or a non-null non-false value.

* [CHG] Method __construct() now sets the default chain-locale-object to $this.

* [CHG] Method applyChain() no longer sets the chain-locale-object.

* [CHG] Method _chainLocale() now defaults to the message key, not null, so that "no translation" (or "translation turned off") will return the key.
16.04.2009 20:18:16pmjones
3687Solar_Sql_Model_Record: [REF] Add method _newFilter() to create filter object, instead of embedding in filter() method. Per talk w/ Jeff Moore.16.04.2009 19:52:00pmjones
3686Solar_Session

* [ADD] Method has() to see if a data key exists in the session.

* [ADD] Method delete() to delete a data key.

* [ADD] Method deleteFlash() to delete a flash key.

15.04.2009 15:56:29pmjones
3685Solar_Cache_Adapter_*: [FIX] Properly add key prefixes using the entry() method when fetching, saving, etc. Affects Eaccelerator, Xcache, Memcache, Apc, and Var.
15.04.2009 15:54:14pmjones
3684Solar_Cache_Adapter_Session: [NEW] Cache adapter to store values in .15.04.2009 15:51:17pmjones
3683Solar_Sql_Model: auto-connect related records and collections

Solar_Sql_Model_Collection
--------------------------

* [BRK] Rename delete() to deleteAll(), to differentiate from new deleteOne()
method (below). Hook methods _preDelete() and _postDelete() are renamed to
_preDeleteAll() and _postDeleteAll() as well.

* [CHG] Method uniqueKeys() is renamed to getPrimaryVals() to reflect naming
conventions and to indicate the nature of the keys.

* [ADD] Method getColVals() to get the values of a singles columsn from every
record in the collection.

* [ADD] Method appendNew() to allow one-step addition of new records to the
collection. Is like fetchNew() in that you pass a data array and get back
the newly appended record.

* [ADD] Method deleteOne() to delete a single record from the collection (and
properly remove it from the collection as well).

Solar_Sql_Model_Record
----------------------

* [CHG] In method _save(), call the relationship preSave() method, to prepare
the native record for saving based on the relationships.

* [CHG] In method _saveRelated(), no longer save the foreign record/collection
directly. Instead, call the relationship save() method to prepare and save
the foreign record/collection. This allows the relationship definition
class to properly connect the native record with the relateds.

* [ADD] Method isDeleted().


Solar_Sql_Model_Related
-----------------------

* [ADD] Empty method preSave() to let the relationship object act on the
native record before the native record is saved.

* [ADD] Abstract method save() to the let relationship object save foreign
records/collections on a particular native record.


Solar_Sql_Model_Related_BelongsTo
---------------------------------

* [ADD] Method preSave() to connect the foreign record to the native record
*before* saving the native record. This is because the native record
retains the foriegn key (unlike the "has" relationships) and so it needs the
foreign key before saving.

* [ADD] Method save() to save the foreign record; connection has already been
taken care of in preSave().


Solar_Sql_Model_Related_HasOne
------------------------------

* [ADD] Method save() to connect the foreign record to the native record, then
save the foreign record.


Solar_Sql_Model_Related_HasMany
-------------------------------

* [ADD] Method save() to connect each foreign record in the foreign collection
to the native record, then save the foreign collection.

Solar_Sql_Model_Related_HasManyThrough
--------------------------------------

* [ADD] Method save() to save the foreign collection, then to process the
mapping collection so as to connect the native record to the correct foreign
record in the foreign collection. Deletes and adds mapping records as
needed, and saves the mapping collection.

13.04.2009 18:20:57pmjones
3682Solar_Base: [ADD] Method _postConfig() as a hook to execute after _buildConfig() in the constructor. Added per suggestion of Jeff Moore.08.04.2009 19:41:54pmjones
3681Solar_Sql_Model: support "affected rows", stop forcing WHERE clauses on records

Solar_Sql_Model
---------------

* [ADD] Property $_affected_rows; is set on each insert(), update(), and
delete() to retain the number of rows affected.

* [ADD] Method getAffectedRows() as accessor.

* [BRK] Method update(), when given a record object, *no longer* forces the
WHERE clause to update only that record. The WHERE clause is now left alone.

* [BRK] Method delete(), when given a record object, *no longer* forces the
WHERE clause to update only that record. The WHERE clause is now left alone.


Solar_Sql_Model_Record
----------------------

* [CHG] In method _update(), because Solar_Sql_Model::update() no longer does
it for us, we set a WHERE clause to make the update affect only this record.

* [CHG] In method delete(), because Solar_Sql_Model::update() no longer does
it for us, we set a WHERE clause to make the update affect only this record.

07.04.2009 00:27:19pmjones
3680Solar_Sql_Model_Record: [FIX] Choose insert/update based on record status, not primary key emptiness. Thanks, Jeff Moore, for the fix.04.04.2009 00:14:10pmjones
3679Solar_Auth_Adapter: [REF] Move loading of handle and passwd to its own method, _loadCredentials(). Per request from Jeff Moore.02.04.2009 20:04:05pmjones
3678Solar_Sql_Adapter and Select: look for "as" and "AS" not just "AS"

Solar_Sql_Adapter
-----------------

* [FIX] Methods quoteName() and quotesNamesIn() now recognize "as" *and* "AS", not just "AS". Thanks, Jon Elofson, for the report.

Solar_Sql_Select
----------------

* [FIX] Method _build() now now recognizes "as" *and* "AS", not just "AS". Thanks, Jon Elofson, for the report.


fixes #183
02.04.2009 19:16:58pmjones
3677Solar_Sql_Adapter and Select: add support for compound (UNION, UNION ALL, etc) queries.

Solar_Sql_Adapter
-----------------

* [CHG] Method _select() now builds single or compound queries, based on the
presence of a 'compound' element in $parts.

* [CHG] Rename _sqlSelect() to _selectSingle().

* [ADD] Method _selectCompound() to build compound query statements.


Solar_Sql_Select
----------------

* [ADD] Properties $_compound (to hold compound query descriptions),
$_compound_type (for the compounding phrase, e.g. "UNION"), $_compound_order
(for the overall order), and $_compound_limit (for the overall limit).

* [ADD] Method union(), unionAll(), and _addCompound() for building compound
queries.

* [ADD] Methods compoundOrder(), compoundLimit(), and compoundLimitPage() to
work with order and limit clauses on compound queries.

* [ADD] Method _clearParts() to clear all parts and sources, without affecting
compound elements.

* [ADD] Method _clearCompound() to clear only compound elements, not parts and
sources.

* [REF] Method clear() now hands off to _clearParts() and _clearCompound()
when clearing all elements.

* [ADD] Method clear() now takes 'compound' as a part name, to clear all
compound elements (including type, order, and limit).

* [CHG] Method clear() now throws an exception when you try to clear a part
it doesn't recognize.

* [REF] Extract the building of parts from fetch() and place into new method,
_build(). The new _build() method **does not** work on properties; instead,
it builds a separate copy of parts and sources. This is so we don't step on
compound queries until they are ready.

* [CHG] Methods _buildFrom(), _buildJoin(), and _buildSelect() now take
&$parts as their first parameter, to reflect the fact that _build() works
with its own copy of the select parts, not the object properties.

* [CHG] Method fetch() now honors compound queries.
02.04.2009 16:56:05pmjones
3676Solar_Sql_Model_Catalog: [ADD] Method loadModel() to wrap and catch exceptions, for test-loading a model. Feature request per Jeff Moore.01.04.2009 19:44:22pmjones
3675Solar_Sql_Model_Collection: [DEL] Remove code that no longer gets called.01.04.2009 16:26:30pmjones
3673MERGE branches/pmjones back to trunk

$ svn merge --revision=3641:HEAD branches/pmjones trunk

This is a Jeff Moore (procata) edition. With few if any exceptions, all the
changes noted here are from work by Jeff Moore. Thanks, Jeff, for your effort
and contributions. :-)


New Classes
-----------

* Solar_Sql_Model_Related_HasManyThrough: For now, this is an identical copy
of HasMany so that all tests pass. Eventually this will become its "own"
class.

* Solar_Sql_Model_Related_ToMany and ToOne: new abstract classes serve as the
base for the other relateds.

* Solar_Sql_Model_Select: to handle SELECTs with special cases for models and
relationships, esp. eager relateds.

* Solar_Sql_Model_Catalog: A common holding-place for model instances. Special
Note: If you free() a model from the catalog, subsequent uses of that model
will show "missing property" errors (especially $_cache). This is because
the catalog retains the model internally instead of discarding it. What
previously was a good practice (freeing a factoried model) is *not* a good
practice when using the catalog.


Solar_App_Base
--------------

* [ADD] New property $_model, populated in _setup(), for a model catalog.


Solar_App_Bookmarks
-------------------

* [CHG] Now that we have $this->_model as a model catalog, remove
$this->_bookmarks and $this->_tags in favor of $this->_model->bookmarks and
$this->_model->tags.


Solar_Cli_MakeApp
-----------------

* [CHG] Rename {:model_var} placeholder to {:model_name}.

* [CHG] In the app-model. php template, remove _preRun() method in favor of
_setup() method, and set up a model catalog object therein.

* [CHG] In the app-model.php template, use references to $this->_model (model
catalog) instead of individual model instances.


Solar_Model_Nodes
-----------------

* [CHG] In method fetchAllByTags(), use the new 'eager' parameters correctly.


Solar_Model_Tags
----------------

* [CHG] In method fetchAllWithCount(), the new 'eager' behaviors mean we need
a 'require_related' flag when counting nodes based on tags.


Solar_Sql_Model
---------------

* [ADD] Properties $_record_prototype and $_collection_prototype to clone new
records and collections from (except in cases of inheritance).

* [ADD] Methods _newRecord() and _newCollection() to create and use the
appropriate prototypes.

* [CHG] Renamed `public fixSelectParams` to 'protected _fixSelectParams`.

* [ADD] Method _fixSelectParamsEager() to begin the transition to recursive
eager fetching. The $params['eager'] value is now an array of arrays where
the key is the related name, and the value is options for the eager fetch.
Changed all foreach() loops on $params['eager'] to use $name => $opts as
part of this.

* [ADD] Method modEagerOptions() in anticipation of the need to modify eager
fetches in extended classes.

* [ADD] Method _hasManyThrough() to make it a first-class related type.

* [ADD] Method getWhereMods() to get WHERE clause modifications for model-wide
conditions, such as single-table inheritance.

* [CHG] Method fetchNew() now adds empty placeholders for relateds so as not
to trigger lazy-loading.

* [CHG] Default value for the $_select_class property is now
'Solar_Sql_Model_Select'.

* [CHG] The various fetch*() methods no longer handle joins and eagers;
instead, they are handled by the Select and Related classes.

* [BRK] When fetching records, placeholders for calculated columns
*do not* get created. This means that instead of checking for null on a
calculated column, you should check empty() instead.

* [ADD] Property $_catalog for the common catalog of model instances.

* [ADD] Config key 'catalog' for a Solar_Sql_Model_Catalog dependency
injection. default value is 'model_catalog'.

* [CHG] Method __construct() now accepts the catalog dependency injection.

* [CHG] Method newRecord() now uses the catalog to find inherited models
instead of its own class stack.

* [ADD] Method getPrimary() to return the fully-qualified primary key name.

Solar_Sql_Model_Collection
--------------------------

* [ADD] Method uniqueKeys() to retrieve all the primary key values in the
collection.


Solar_Sql_Model_Record
----------------------

* [ADD] Constants for all statuses.

* [ADD] Static property $_access_methods_list, to retain accessor methods
across all record objects.

* [DEL] Property $_related_page, as it is never used.

* [CHG] Property $_access_methods now keys on [col][method], not [method][col].

* [CHG] Methods __get(), __set(), __isset(), and __unset() no longer call
_checkDeleted(). This is an optimization.

* [ADD] Methods _setAccessMethods() and _loadAccessMethodsList() to maintain
accessor methods. This is an optimization,

* [CHG] Method setStatus() no longer lets you set 'dirty' on a new record.

* [DEL] Method getStatus(), since it exists in the parent class.

* [CHG] Method __get() uses idfferent lazy-loading algorithm.

* [ADD] Method _fetchRelatedData() for handling related data from eager
fetches.

* [DEL] Method setModel(), replaced with added method init().

* [ADD] Method _fixRelatedData() to handle loading of related data.

* [CHG] Method load() no longer sets placeholders for calculated or related
cols.

* [CHG] Method toArray() no longer includes unloaded related cols.

* [ADD] Method fetchRelated() to fetch data from a related object.

* [ADD] Method init() to initialize a record object for the first time. This
is an equivalent to setModel()/load()/setStatus(), but optimized for the
initial data load.



Solar_Sql_Model_Related
-----------------------

* [CHG] Now uses the foreign model getWhereMods() method for model-specific
conditions.

* [DEL] Now that getWhereMods() is used, properties $foreign_inherit_col and
$foreign_inherit_val have been removed.

* [CHG] Methods isMany() and isOne() are now abstract, implemented by the
ToMany and ToOne classes.

* [ADD] Method fetch() as the eventual replacement for fetchArray() and
fetchObject(). Placeholder alias to fetchObject() for now, while we
transition to the new relationship behaviors.

* [DEL] Various properties no longer needed, or moved to ToMany and ToOne, or
moved the extended classes. These include $native_table, $through (et. al.),
$distinct, $group, $having, $paging, $_fetch_object.

* [BRK] The fetch() options for 'distinct', 'fetch', 'group', 'having', and
'paging' are no longer honored.

* [ADD] Property $_fromselect_threshold, to indicate how many records in a
collection you can have and still use the IN() form of joins; after this,
subselect-based joins are used.

* [ADD] Property $_join_strategy, to indicate collation of related records at
the 'server' (the database) or at the 'client' (the PHP layer).

* [ADD] Method _joinResults() to collate related result sets.

* [ADD] Method _fixEagerOptions() to correct 'eager' settings.

* [ADD] Method _fixColumnPrefixOption() to deal with to-one related column
prefixes.

* [ADD] Various methods to support multi-level eager chaining, join
strategies, etc.

* [CHG] Method _setForeignModel() no longer uses the native model class stack
to find the foreign model. Instead, uses the catalog.


Solar_Sql_Model_Related_BelongsTo
---------------------------------

* [CHG] Now extends Solar_Sql_Model_Related_ToOne.

* [DEL] Method modSelectEager (eager selection now handled very differently)

* [DEL] Property $fetch since ToOne handles that.



Solar_Sql_Model_Related_HasMany
-------------------------------

* [CHG] Now extends Solar_Sql_Model_Related_ToMany.

* [DEL] Removed unneeded "has many through" logic (now in the HasManyThrough
class).

* [CHG] Now uses the foreign model getWhereMods() method for model-specific
conditions.

* [DEL] Property $_fetch_object since ToMany now handles that.

* [DEL] Method _setForeignClass() since ToMany now handles that.

* [DEL] Method modSelectEager (eager selection now handled very differently).

* [DEL] Method modSelectCountPages (selection now handled very differently).

* [DEL] Method _fixForeignKey() since ToMany now handles that.

* [DEL] Method _fixRelatedCol() since the ToMany now handles that.

* [DEL] Method _setRelated() since the ToMany now handles that.


Solar_Sql_Model_Related_HasManyThrough
--------------------------------------

* [CHG] Now extends Solar_Sql_Model_Related_ToMany.

* [DEL] Removed unneeded "has many" (no "through") logic; it's now only in the
HasMany class.

* [CHG] Now uses the foreign model getWhereMods() method for model-specific
conditions.

* [CHG] Sets property $type to 'has_many_through'.

* [ADD] Properties $through et. al., since they're needed only for "through"
relationships.

* [ADD] Method overrides for _modSelectRelatedTo(Record|Collection|Select).

* [CHG] Method modSelectEager() to handle "through" relateds.

* [ADD] Method _modSelectAddThrough() to add the "through" joins.

* [DEL] Method _fixRelatedCol() since the ToMany now handles that.

* [DEL] Property $fetch since ToMany now handles that.

* [DEL] Method _modSelect() since ToMany now handles that.


Solar_Sql_Model_Related_HasOne
------------------------------

* [CHG] Now extends Solar_Sql_Model_Related_ToOne.

* [DEL] Method modSelectEager (eager selection now handled very differently).

* [DEL] Property $fetch since ToOne now handles that.

* [DEL] Method _fixRelatedCol() since the ToOne now handles that.


Solar_Struct_Xml
----------------

* [FIX] In method _loadSimpleXmlElement(), make sure the conversion results in
an array.


Solar_Test
----------

* [FIX] Method diag() should always show the value, empty or no.

30.03.2009 21:36:01pmjones
3639updating comments10.03.2009 15:32:47pmjones
3638Solar_Test_Suite: [BRK] No longer adds "Test_*" and "test*" prefixes for you. You now *have* to include "Test_" prefix on class names, and "test" prefix on method names, so that they match the class and method names one-for-one. This is so that you can copy the run-tests output directly into a command-line parameter without having to edit it.10.03.2009 15:17:32pmjones
3637Solar_Cli_MakeDocs: [FIX] TO bring in line with fixes to Solar_Getopt, rename options 'package-dir' and 'class-dir' to 'package_dir' and 'class_dir' respectively. Thanks to Dymtro Konstantinov and Raymond Kolbe for the report that led to this fix.10.03.2009 15:14:31pmjones
3636Solar_Php: [FIX] Use 'php' as the default binary name instead of '/usr/local/bin/php'.10.03.2009 15:11:48pmjones
3626remove debug line25.02.2009 16:40:57pmjones
3625Solar_Sql_Model: [CHG] Refactor method fetchNew() to use a support method, _fetchNewData(), thereby making the data generation extensible. Calculate cols are now included in the default data load.20.02.2009 00:16:44pmjones
3624Solar_Sql_Model: comment and loop-variable name changes18.02.2009 22:35:39pmjones
3623Solar_Sql_Model and others: change $_calculate_cols to act like $_table_cols.

Solar_Sql_Model
---------------

* [CHG] The property $_calculate_cols, instead of being a sequential array of
column names, is now converted (via new method _fixCalculateCols()) to look
just like $_table_cols, with name/type/size/etc values. This allows more
complex behaviors, like automatic filters, on calculated keys. This change
is is backwards-compatible with the "old" $_calculate_cols format, so no
changes to _setup() behaviors are required. Thanks, Jeff Moore, for the
suggestion that led to this feature.

* [ADD] Method _fixCalculateCols() to fix up calculated column descriptions.

* [ADD] Method _fixFilterCols() to add filters on any column set, whether
table or calculated.

* [FIX] Method _fixFilterCols() no longer applies string filters on
$_xmlstruct_cols.


Solar_Sql_Model_Record
----------------------

* [CHG] Method load() now examines the model $_calculate_cols *keys*, not
the values, in line with change to $_calculate_cols format.

* [CHG] Method form() now examines the model $_calculate_cols *keys*, not
the values, in line with change to $_calculate_cols format.

* [CHG] Method toArray() now uses array_keys() on $this->_data, since it
already has all the necessary keys.


Solar_Form_Load_Model
---------------------

* [CHG] Method fetch() now examines the model $_calculate_cols *keys*, not
the values, in line with change to $_calculate_cols format.

* [CHG] In method fetch(), when '*' columns are requested for the form, now
includes the model $_calculate_cols.

18.02.2009 22:26:34pmjones
3622Solar_Sql_Model: table scans are now optional.

* [ADD] New config 'table_scan'. When false, does not scan the table for column descriptions (i.e., assumes $this->_table_cols is already correctly set). Default true (for backwards compatibility). Implemented via method _fixTableCols(). Thanks, Jeff Moore, for the request leading to this feature.

* [ADD] Method _fixPrimaryCols() to separate table-column fixes and primary-column fixes.
18.02.2009 20:24:09pmjones
3621Solar_Sql_Model: [CHG] In methods insert() and update(), serializing of columns now occurs **before** the record/data is converted to array. This is because XML struct columns were being converted to arrays instead of to strings, and thus not being saved to the database.17.02.2009 16:00:52pmjones
3620Solar_Sql_Model_Record: [CHG] Method isChanged() now takes Solar_Struct values into account.17.02.2009 15:56:52pmjones
3619Solar_Struct_Xml: [FIX] When loading sub-structs, set the parent object correctly.17.02.2009 15:54:49pmjones
3617MERGE branches/mc back to trunk (a "Jeff Moore" edition ;-)

$ svn merge --revision=3587:HEAD branches/mc/ trunk/


New Classes
-----------

* Solar_Struct_Xml: A struct based around XML input/ouput. (Attributes are not
yet supported, but will be in future.)


Solar_Cache_Adapter_File
------------------------

* [CHG] Use $_life, not $_config['life'], when checking lifetime.


Solar_Cache_Adapter_Var
-----------------------

* [FIX] Honor $_life=0 ('forever'). Thanks, Jeff Moore, for the report that
led to this fix.


Solar_Cli_MakeApp
-----------------

* [FIX] In model template for method actionAdd(), when redirecting, ask the
record for its primary-key value instead of assuming $id property; this
allows for "non-standard" primary-key names. Thanks, Matthew Turland, for
the report that led to this fix.


Solar_Cli_RunTests
------------------

* [ADD] Add --test-config option to pass a config file for the tests (as
opposed to the test-runner).


Solar_Example_Model*
--------------------

* [CHG] Reduce relationship arrays to their absolute minimum.


Solar_Getopt
------------

* [BRK] Option array keys use underscores, not dashes.


Solar_Sql_Adapter_*
-------------------

* [CHG] In method _fetchTableCols(), throw an exception when the table columns
don't appear to exist.


Solar_Sql_Model
---------------

* [ADD] Property $_xmlstruct_cols to say what columns hold XML data, and
should be serialized/unserialized to Solar_Struct_Xml objects at save/fetch
time.

* [ADD] Property $_xmlstruct_class to say what class the XML-struct cols
should use.

* [CHG] Method fetchNew() populates $_xmlstruct_cols with empty
Solar_Struct_Xml objects.

* [CHG] Methods serialize() and unserialize() now perform XML struct
conversions as well.

* [FIX] In method newRecord(), correctly pass $this->_config to the inherited
model when instantiating it (previously, wrapped config in a second array).

* [CHG] In method _fixStack(), modify so that *all* `*_Model` prefixes are
honored, not just Vendor_Model prefixes (e.g., Vendor_Example_Model). Also,
use array_shift() instead of reverse/pop/reverse.

* [CHG] Property $_primary_col now defaults to null, not 'id'. This is to
better support auto-discovery of primary column from the table description.

* [CHG] In method _fixTable(), set $_primary_col from the table columns *only*
if $_primary_col is not already set. Thanks, Jeff Moore, for the report that
led to this change.

* [CHG] Use $related->isOne() and isMany() intead of isOne() and isMany(), per
changes in Solar_Sql_Model_Related.

* [FIX] In method fetchOne(), load the record exactly the same way the
collection object loads records (i.e., all-at-once via the data array, not
piecemeal via the record properties).

* [CHG] Method _addRelated() no longer takes a $type param; it now depends on
$opts['class'] being set properly.

* [CHG] Methods _belongsTo(), _hasMany(), and _hasOne() now set $opts['class']
when it does not already exist. This will let developers override which
related-manager class to use, if they wish. Thanks, Jeff Moore, for the
suggestion that led to this change.

* [CHG] Im method _fixTableCols(), optimize somewhat for fewer SQL calls.
Thanks, Jeff Moore, for the report and patch.


Solar_Sql_Model_Collection
--------------------------

* [CHG] Use the new $related->isOne() and isMany() methods instead of checking
$related->type.

* [ADD] Property $_load_related to track which related keys have been eager-
loaded; this will help eliminate the "empty N+1" problem reported by Jeff
Moore.

* [CHG] Method loadRelated() now tracks which related names are being loaded,
even if the related data for a particular record is empty; this will help
eliminate the "empty N+1" problem reported by Jeff Moore.

* [CHG] Method __get() now sets empty placeholder values for related keys as
tracked by $_load_related; this will help eliminate the "empty N+1" problem
reported by Jeff Moore.

* [CHG] Rename $_related to $_data_related.



Solar_Sql_Model_Record
----------------------

* [CHG] In method toArray(), now calls toArray() on all Solar_Struct objects,
not just Record/Collection objects.

* [CHG] Use the new $related->isOne() and isMany() methods instead of checking
$related->type.

* [FIX] Method load() now tracks all eager-loaded data, even when the data is
empty. Previously, eager-loaded empty data would cause __get() to trigger
a lazy-load of the related data, resulting in an N+1 condition when eager
data was empty. Thanks, Jeff Moore, for the report that led to this fix.


Solar_Sql_Model_Related
-----------------------

* [ADD] Methods isOne() and isMany() to abstract testing for the kind of
relation (vice checking $related->type == 'has_many' etc). Thanks, Jeff
Moore, for the suggestion leading to this.

* [FIX] In _fixForeignKey() methods, use the $_foreign_col property of models
to determine the default foreign key. Thanks, Jeff Moore, for the report
that led to this fix.


Solar_Struct
------------

* [ADD] Property $_parent and methods getParent() and setParent() to note if
this struct is the child of another struct.

* [ADD] "Status" behaviors: constants STATUS_CLEAN and STATUS_DIRTY, property
$_status, methods getStatus() and setStatus(). Method __set() now marks the
struct as "dirty", and recursively ascends to all parent structs to mark
them as "dirty" too.

* [ADD] Methods __toString() and toString() to convert the struct to a string.

* [CHG] Method toArray() now recursively descends into the data looking for
child structs and converts *them* to arrays as well using added support
method _toArray().

* [ADD] Methods free() and _free() to free up memory from child/parent
structs.
16.02.2009 19:47:30pmjones
3586Solar_Controller_Page

* [FIX] Now sends a default Content-Type header with charset when using the default format. Thanks, Jeff Moore, for the query that led to this fix.

* [FIX] Method _fixFormat() now adds the format back with an integer zero key instead of an empty-string key, when adding the format onto an empty $_info array. Thanks, Jeff Moore, for the report that led to this fix.
29.01.2009 01:41:38pmjones
3584comment changes27.01.2009 16:15:22pmjones
3582Solar_Uri: [ADD] Config key 'host' to allow default hosts for URIs; e.g., public URIs pointing to a separate asset server.27.01.2009 15:45:16pmjones
3581Solar_Sql_Adapter: [CHG] Method quoteInto() now supports multiple placeholder replacements. Thanks, Anthony Gentile, for the report that led to this change.

fixes #181
18.01.2009 23:00:36pmjones
3580Solar_Sql_Model_Collection: [CHG] When loading related data from a fetch 'all', renumber the keys so they are sequential. Data loaded from 'assoc' fetches still key per the 'assoc' column. The reason for this change is that new developers are understandably confused as to why the keys aren't 0, 1, 2 etc (since the key source is the fetch for all related records for the collection, not just the record related to the particular record in the collection.) Thanks, Anthony Gentile, for the report that led to this fix.

fixes #180
18.01.2009 22:51:30pmjones
3579Solar_Cache_Adapter_File
------------------------

* [CHG] In __construct(), when building $_path, add the $_prefix value to it
so that different prefixes get their own directories.

11.01.2009 17:01:22pmjones
3578Solar_Cache_Adapter_(Apc|Eaccelerator|Memcache|Var|Xcache)
----------------------------------------------------------

* [CHG] Use parent entry() method implementation.

11.01.2009 17:00:36pmjones
3577Solar_Cache_Adapter
-------------------

* [ADD] Config key `prefix` and property `$_prefix` to help deconflict between
uses of the same cache among different systems (e.g., to use the same cache
for dev, staging, and production, and keep those values separate from each
other.) Default is null for BC.

* [CHG] Method entry() is no longer abstract; is now a baseline implementation
for finding entry key names. Default is to prefix the entry key with the
new $_prefix deconfliction value.

* [ADD] Method fetchOrSave() fetches an entry, but if the entry does not
exist, it uses a callback to generate data for the entry and saves it. This
is to encapsulate a common caching idiom.

* [ADD] Method fetchOrSave() fetches an entry, but if the entry does not
exist, it uses a callback to generate data for the entry and adds it to the
cache in a race-condition-safe manner. This is to encapsulate a common
caching idiom.

11.01.2009 16:59:53pmjones
3576brace line change11.01.2009 16:44:01pmjones
3575Solar_View_Helper_Form: [ADD] Method __toString() to allow simple echoing of the object itself, instead of echoing the fetch() result.01.01.2009 01:38:30pmjones
3574Solar_View_Helper_Form

* [REF] Continue refactoring; add _buildElementInvalid() and _buildGroupInvalid() methods to handle display of "invalid" messages.

* [BRK] Remove listFeedback() method entirely; it was the only method that provided output aside from fetch(), and you should be using only fetch() for output on this class.
01.01.2009 01:26:07pmjones
3573Solar_View_Helper_Form

* [REF] Major refactoring to break the fetch() method up into a series of _build*() methods. This should make it easier to modify and extend the default behavior. Aside from whitespace and linebreaks, the output should be *identical* to previous versions. Thanks, Jeff Moore and others, for the impetus to perform this refactoring.

* [ADD] Methods setAttribs() and addElements() to make it easier to set multiples of these. Thanks, Jeff Moore, for the request leading to these.

31.12.2008 22:47:05pmjones