Overview -------- * [BRK] The default config file location is now SYSTEM/config.php, not SYSTEM/config/Solar.config.php. You will need to move your config file; be sure to check on how many times you nest dirname(__FILE__) in it. * [BRK] Rename relationship definition 'where' and eager param 'join_cond' to 'conditions'. This is a break. Because related fetches use the 'where' conditions both in WHERE *and* JOIN ON clauses, the relationship definition key 'where' is now renamed to 'conditions' to indicate they are used as conditions in different places. Similarly, Solar_Sql_Model::getWhereMods() is renamed to getConditions(). Finally, in eager fetches, the 'join_cond' value is used in both WHERE and JOIN ON clauses, so it too has been renamed to 'conditions'. The method for it is no longer joinCond(), but addCondition(). * [BRK] Form elements from model objects are now named in the *singular*, not the plural, using the new Model::$_array_name value. This is a break. * If you modify form elements in, e.g., Record::newForm(), you'll need to change those from plural to singular. * The Vendor_Controller_Model class now looks for the singular, not the plural. You can update your vendor source by deleting your Vendor_Controller_Model class and re-running `./script/solar make-vendor`; the script will replace the missing class with the newer version. New Classes ----------- * Solar_Cli_LinkPublic: Creates per-class public symlinks. * Solar_Cli_LinkVendor: Creates vendor symlinks. * Solar_Cli_UnlinkVendor: Removes vendor symlinks. * Solar_Filter_ValidateEquals: Validates that two data elements are equivalent (==). * Solar_Filter_ValidateNotEquals: Validates that two data elements are not equivalent (!=). * Solar_Filter_ValidateNotSame: Validates that two data elements are not identical (!==). * Solar_Filter_ValidateSame: Validates that two data elements are not identical (===). * Solar_Struct_Iterator: IteratorAggregate support class for Solar_Struct. * Solar_Symlink: utility to create symbolic links. * Solar_View_Helper_ActionUri: returns a URI object for the current action. Deleted Classes --------------- * The entire Solar_Example hierarchy has been moved to the new Mock_Solar hierarchy, since its whole purpose was for testing. * Solar_Filter_ValidateCompare: use Solar_Filter_ValidateEquals instead. * Solar_Filter_ValidateConfirm: use Solar_Filter_ValidateEquals instead. * Removed example apps and models entirely from the standard Solar distribution. These will reappear, in modified form, as apps and models under an example vendor space called "Proxima". - Solar/App/Base.php - Solar/App/Base/* - Solar/App/Bookmarks.php - Solar/App/Bookmarks/* - Solar/App/HelloApp.php - Solar/App/HelloApp/* - Solar/Model/* script/solar ------------ * [CHG] Use the new system-specific config file, always. no more vendor-specific fallback. Solar_Auth_Adapter ------------------ * [FIX] Compare idle time against session.gc_maxlifetime and exipre time against session.cookie_lifetime; as vs comparing both against session.cache_lifetime (which has nothing to do with cookie timeouts). Thanks, Jeff Moore, for the report and direction. Solar_Access_Adapter -------------------- * [ADD] Property $_owner_method (format is `instance_name` => `method_name`). * [CHG] Method isOwner() is now implemented (not abstract). It loops through the $_owner_method property; if the content object is an instance of the noted class, isOwner() calls the noted method name to check ownership of the object, passing the Auth and Role objects as params. Solar_Access_Adapter_File ------------------------- * [CHG] Method fetch() now recognizes "handle ?" to indicate only unauthenticated users. (This is in addition to 'handle *' indicating all users, and 'handle +' indicating only authenticated users.) * [BRK] Method isOwner() no longer returns true by default; the method is removed in favor of the parent isOwner() implementation. Solar_Access_Adapter_Sql ------------------------ * [CHG] Method fetch() now recognizes "handle ?" to indicate only unauthenticated users. (This is in addition to 'handle *' indicating all users, and 'handle +' indicating only authenticated users.) * [BRK] Method isOwner() no longer returns true by default; the method is removed in favor of the parent isOwner() implementation. Solar_App_Base -------------- * [ADD] Add Solar/App/Base/Public directory for public assets (e.g. styles), and move all general-purpose Solar/App/Public files to it. * [CHG] In method _preRender(), examine app's public directory for a style.css file, instead of a Vendor/styles/app/{:controller}.css file. * [CHG] In Layout/_head.php, point to Solar/App/Base for styles instead of Solar/styles. Solar_App_Bookmarks ------------------- * [ADD] Add Solar/App/Bookmarks/Public directory, and move Solar/styles/app/bookmarks.css to it. Solar/App/Public ---------------- * [DEL] Move styles/pager.css to Solar_View_Helper_Pager public directory. * [DEL] Removed remainder to Solar/App/Base/Public. Solar_Cli_LinkVendor -------------------- * [CHG] Add support for include/Mock/Vendor -> tests/Mock/Vendor. Solar_Cli_MakeApp ----------------- * [ADD] Create a Vendor/App/{:name}/Public directory, and link it. * [CHG] The application skeleton now has properties for $item_cols, $list_cols, and $_form_cols, to honor the changes in Solar_Cli_MakeVendor boilerplate Controller_Model class. * [BRK] The basic page-controller is now called Bread, not Model, as it is more descriptive of what's going on. Solar_Cli_MakeModel ------------------- * [CHG] In model skeleton, use Solar_Class::dir() instead of building the dir string manually. * [FIX] In method _writeLocaleFile(), create a base $descr array to avoid notices when --connect=false. * [FIX] In method _writeLocaleFile(), check to see if the table_cols.php file exists before attempting to include it. Thanks, Sean Coates, for the report leading to this fix. * [FIX] Method _writeLocaleFile() now looks for the proper table_cols.php file to get strings from. * [CHG] In skeleton files, put setup file reads in _preSetup(), not _setup(). Solar_Cli_MakeTests ------------------- * [CHG] Output is now more readable. * [CHG] Skeleton script files use the new preTest() and postTest() hooks (vice setup() and teardown(), respectively). * [CHG] Now creates separate test skeletons for abstract adapter classes, as vs concrete adapter classes. This is so that the abstract test has all the test methods, and the concrete adapter just inherits from it (with no test methods of its own). * [DEL] Skeleton for abstract class test no longer includes what are effectively empty stub methods for __destruct(), preTest(), and postTest(). * [ADD] Skeleton for concrete adapter classes. * [DEL] Skeleton for factory class test no longer includes what are effectively empty stub methods for _preConfig(), _postConfig(), _postConstruct(), __destruct(), preTest(), and postTest(). * [FIX] Skeleton for factory class test__call() no longer uses params. * [CHG] Skeleton for adapter classes is now marked as abstract. * [ADD] Skeleton for adapter classes now incorporates a standardized idiom for testing construction via $_adapter_class, $_adapter, and preTest() setup for $_adapter. * [DEL] Skeleton for concrete class test no longer includes what are effectively empty stub methods for _preConfig(), _postConfig(), _postConstruct(), __destruct(), preTest(), and postTest(). * [FIX] Skeleton for abstract test does not need to skip; the suite runner skips abstracts automatically. * [CHG] Rename skeleton classAdapter to classAdapterAbstract. * [CHG] Skeleton classAdapterAbstract marks itself as todo; remove the __construct() method after you provide useful config values. Solar_Cli_MakeVendor -------------------- * [CHG] Method _createLinks() now invokes Solar_Cli_LinkVendor to make the vendor links. * [DEL] No longer create a Vendor/App/Public directory. Apps will now each have their own public directory. * [ADD] Create a Vendor/Controller/Page/Public directory. * [ADD] Create a Vendor/Controller/Model/Public directory. * [ADD] Now creates `vendor/tests/Mock` directory and `vendor/tests/config.php` file. * [CHG] Modificatons to the boilerplate Vendor_Controller_Model class: - [ADD] Properties $item_cols and $list_cols to say which columns should be displayed for items and lists, respectively. - [BRK] Rename property $_record_cols to $_form_cols, and change format so that different actions can have different form elements. - [DEL] Property $_use_acl; *always* use access control. Since the default is the "open" access adapter, this causes no BC break. Method _isUserAllowed() changed accordingly. - [DEL] In method _setup(), assume the existence of the necessary registry objects, since it's coming from a default Solar distribution in the first place. - [CHG] Method _loadItem() now honors the $_form_cols property for the current action. - [CHG] Method _setFormItem() now honors the $_form_cols property for the current action. * [CHG] Modificatons to the boilerplate Vendor_Controller_Model views: - [CHG] All

are now

and all

are now

, to accommodate site-branding

tags. - [CHG] In 'edit' view, only show the delete button when the user has the correct access privileges. - [CHG] The '_list' partial honors the new $this->list_cols property. - [CHG] In 'browse' view, only show the add link when the user has the correct access privileges. - [CHG] The '_item' partial honors the new $this->item_cols property. - [CHG] In 'read' view, only show the edit link when the user has the correct access privileges. * [FIX] In skeleton for Controller_Model view _list, use $this->list (not $item) to get the model. * [CHG] In skeleton classes, put the class brace on the next line, not the same line, per PEAR standard. * [BRK] The basic page-controller is now called Bread, not Model, as it is more descriptive of what's going on. Solar_Cli_UnlinkVendor ---------------------- * [CHG] Add support for include/Mock/Vendor -> tests/Mock/Vendor. Solar_Class ----------- * [ADD] Method nameToFile(), thereby implementing PSR-0 from the project interop group. Solar_Controller_Command ------------------------ * [CHG] Method _outln() now appends PHP_EOL and hands off to _out(), instead of duplicating the fwrite() call from _out(). Solar_Controller_Front ---------------------- * [REF] Refactor static routing into its own method, _routing(). * [ADD] Config key 'rewrite', property $_rewrite, and method _rewrite() to support regex-based dynamic rewriting of the supplied URI path elements. Rewriting occurs before static routing. Thanks, Sean Coates, for the report and request that led to this feature. * [ADD] Config key 'replace' to allow override replacement strings for rewrite rules. * [FIX] Property $_disable is now an empty array by default (previously was an array with one element, 'base'), and properties $_rewrite and $_routing are now also empty arrays. Thanks, Sean Coates, for the note that led to this fix. * [ADD] Property $_explain and config key 'explain'. Per notes from Sean Coates, we now retain explanatory messages about the front-controller process. * [CHG] Method _notFound() now dumps the explanatory messages as part of the not-found page when the 'explain' config key is true. * [CHG] Config keys for 'default' and 'disable' are now empty. * [FIX] In method _notFound(), close the tag. Thanks, Jon Elofson, for the report. Solar_Controller_Page --------------------- * [CHG] Method _preRender() adds another "magic" view property $controller_class to make access testing inside the view easier. * [FIX] Always cast $params to an array. Thanks, Jon Elofson, for the report. Solar_Debug_Var --------------- * [FIX] Now uses _preConfig(), not _postConfig(), to set the default output mode. * [BRK] Method fetch() now applies htmlspecialchars() and wraps in
 tags
  before returning, instead of display() doing it. This is to make it easier
  to test.


Solar_Dir
---------

* [FIX] Because this is a static class, no longer extend Solar_Base.

* [ADD] Static method _exception() to mimic Solar_Base::_exception().

* [CHG] In methods mkdir() and rmdir(), use the new static _exception()
  method.


Solar_Docs_Phpdoc
-----------------

* [CHG] Improve discovery of summary lines: look for punctuation, or a
  double-newline when there is no punctuation. Updated test coverage.


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

* [ADD] Method dataKeyExists(), to see if a particular key exists in the data
  to be filtered.

* [CHG] Method _applyChain(), when a data key is not required, looks to see if
  the data key exists. If not required and not present, skips filtering of the
  non-existent data key.


Solar_Filter_Abstract
---------------------

* [FIX] In method _resetInvalid(), set the $_invalid property, not the $error
  property, when working with a Sanitize filter.

Solar_Form
----------

* [FIX] In method addInvalid(), set the form status first, not last. This
  helps to make sure that all invalids on missing elements get into the
  form-level feedback without being cleared by accident.

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

* [CHG] Method fetch() now accepts empty and '*' to indicate the default list
  of all columns (less special columns).


Solar_Http_Request_Adapter
--------------------------

* [FIX] Use 'expires', not 'expire', for cookie expiration label.

* [ADD] Config key 'auto_set_length', default true.

* [CHG] Method _prepareRequest() method now honors the 'auto_set_length'
  config key. When true, it auto-sets the Content-Length header based on the
  $content value (the existing backwards-compatible behavior). When false, it
  leaves the Content-Length header as-is.

* [FIX] Method getOptions() now populates the 'user_agent' key.

* [CHG] Method setCookie() now accepts an array as the second param, allowing
  you to pass an entire cookie descriptor array, not just a value.  This
  affected setCookies() as well, by indirection.


Solar_Http_Response
-------------------

* [FIX] Use 'expires', not 'expire', for cookie expiration label.


Solar_Mail_Transport_Adapter_File
---------------------------------

* [FIX] Use "/tmp/mail", not "/mail", as the default directory when in a Solar
  system.


Solar_Markdown_Plugin_Link
--------------------------

* [FIX] Method _parseInline() is now protected.


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

* [FIX] Method getList() now properly returns an empty array when the cache
  misses.

* [FIX] Methods add() and addList() now use getList() instead of accessing the
  cache directly.


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

* [CHG] Method fetchTableList() now takes an optional param, $schema, to
  indicate which schema to get a table list for.

* [CHG] Method _fetchTableList() now takes a $schema parameter.

* [CHG] Methods fetchTableCols() and fetchIndexInfo() now allow the use of
  "schema.table" identifiers.

* [CHG] Methods _fetchTableCols() and _fetchIndexInfo() now take two params,
  $table and $schema.

* [CHG] Method _checkIdentifier() now supports "schema.ident" formats.

* [ADD] Method _checkIdentifierPart() to check one part of a dotted
  identifier.

* [REF] Refactored method _checkIdentifer() to extract added method
  _checkIdentifierColumn().

* [ADD] Method _splitSchemaIdent() to split a dotted identifier into schema
  and identifier-name portions.


Solar_Sql_Adapter_Sqlite
------------------------

* [CHG] Method _fetchTableList() now takes a $schema parameter; when $schema
  is set, the method returns only tables from that attached database file.
  Note that you need to query `ATTACH DATABASE '$file' AS '$schema'` at some
  point prior to this.

* [CHG] Method _fetchTableCols() now takes a second parameter, $schema; when
  $schema is present, it returns columns from the table in that attached
  database file. Note that you need to query `ATTACH DATABASE '$file' AS
  '$schema'` at some point prior to this.

* [CHG] Method _fetchIndexInfo() now takes a second parameter, $schema; when
  $schema is present, it returns indexes from the table in that attached
  database file. Note that you need to query `ATTACH DATABASE '$file' AS
  '$schema'` at some point prior to this.


Solar_Sql_Adapter_Mysql
------------------------

* [CHG] Method _fetchTableList() now takes a $schema parameter; when $schema
  is set, the method returns only tables from that other database.

* [CHG] Method _fetchTableCols() now takes a second parameter, $schema; when
  $schema is present, it returns columns from the table in that other
  database.

* [CHG] Method _fetchIndexInfo() now takes a second parameter, $schema; when
  $schema is present, it returns indexes from the table in that other
  database.


Solar_Sql_Adapter_Pgsql
-----------------------

* [CHG] Method _fetchTableList() now takes a $schema parameter; when $schema
  is set, the method returns only tables from that other schema in the
  database.

* [CHG] Method _fetchTableCols() now takes a second parameter, $schema; when
  $schema is present, it returns columns from the table in that other schema
  in the database.

* [CHG] Method _fetchIndexInfo() now takes a second parameter, $schema; when
  $schema is present, it returns indexes from the table in that other schema
  in the database.


Solar_Sql_Adapter_Oracle
------------------------

* [CHG] Added $schema params to _fetchTableList(), _fetchTableCols(), and
  _fetchIndexInfo(), but have not implemented the behavior.


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

* [BRK] Per notes from Jeff Moore, remove method _fixOrder(). This means that
  no default order will be forced on a model when one is not already defined.
  You can still set a default order of your own using $this->_order.

* [CHG] Now that we don't force a default order ... in method newSelect(),
  only add default order when a default order is actually defined.

* [BRK] Rename method getWhereMods() to getConditions().


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

* [CHG] In method getColVals(), no longer need to iterate over the internal
  data structure, now that Solar_Struct implements IteratorAggregate.

* [CHG] In method toArray(), no longer need to iterate over a clone, now that
  Solar_Struct implements IteratorAggregate.

* [ADD] Method isEmpty() to say if the collection is empty or not.


Solar_Sql_Model_Params_Eager
----------------------------

* [BRK] Rename param key 'join_cond' to 'conditions'.

* [BRK] Rename method joinCond() to addCondition().



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

* [ADD] Method dump() to get a dump of the record (not including its model
  object).

* [CHG] Method newForm() now passes an empty $cols to the form, letting the
  form object determine the default elements. This is to avoid seeing
  created/updated elements by default.


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

* [CHG] Method _setOrder() no longer forces an order on the related when none
  is defined. Thanks, Jeff Moore, for the report.

* [REF] Extract new method getForeignWhereMods() from _modEagerFetch(). The
  method merges $this->where along with the foreign model getWhereMods(). This
  will let us retrieve the where modifications for through relationships.

* [ADD] Property 'foreign_name' to indicate the name of the foreign model.
  This is as vs 'foreign_class', which specifies the foreign model class
  directly.  The 'foreign_class' takes priority.

* [CHG] Method _modEagerFetch() no longer adds the foreign where modifications
  itself; instead, that is handled by each type of related. This is because
  the conditions may be part of the WHERE clause, or they may be part of a
  JOIN ON clause (e.g. in eager loading vs. lazy loading, and esp. with the
  has-many-through behaviors).

* [CHG] Method fetch() now merges foreign where mods itself, placing them
  in the WHERE clause.

* [CHG] Method _fetchIntoArrayOne() now merges foreign where mods itself,
  placing them in the WHERE clause.

* [CHG] Method _fetchIntoArrayAll() now merges foreign where mods itself. It
  does so either as part of the JOIN ON clause for the subselect strategy,
  or as part of the WHERE clause for the WHERE IN strategy.

* [REF] Since method _modEagerFetch() only calls _modEagerFetchJoin(), make
  it abstract. Calls now 

* [BRK] Rename property $where to $conditions; this means that relationship
  definition arrays need to use 'conditions', not 'where'.

* [CHG] Rename method _setWhere() to _setConditions().


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

* [DEL] Method _setRelated() no longer honors the user-defined value of
  'through_table' or 'through_alias'. This is in preparation for honoring
  the where conditions on the through relationship. (If the user can re-
  define the alias name, then the where conditions in the "through" definition
  may be incorrect for the fetch.)

* [CHG] In method _setRelated(), because $this->through is always set, no
  need to check for it in the rest of the logic.

* [BRK] In method _setRelated(), no longer convert 'join_cond' to 'where'
  clauses on a left join; this was regarded as too magical.  Thanks, Jeff
  Moore, for pointing it out.

* [CHG] In method _setRelated(), merge the "through" relationship where mods
  into $this->where, so that through relationship conditions are honored on
  all fetches.

* [ADD] Property $through_where to hold the "through" model's foreign where
  modifications. The separate property is needed because the through
  conditions are added in different places that the regular "foreign"
  conditions.

* [CHG] Method _modEagerFetchJoin() now uses a left join, not an inner join,
  to attach to the through table.  This is in the interest of keeping the
  native record collection the same even when no through records are found.

* [CHG] Method _modEagerFetchJoin() now adds the "through" conditions to the
  through JOIN ON clause, instead of the WHERE clause.

* [CHG] Method _modEagerFetchJoin() now merges foreign where mods itself,
  placing them in the JOIN ON clause for the foreign table.

* [CHG] Method _modEagerFetchJoin() now calls DISTINCT on the fetch, as with
  the has-many relationship, to eliminate duplicate rows.

* [CHG] Method _fetchIntoArrayOne() now adds the "through" conditions to the
  through JOIN ON clause, instead of the WHERE clause. Also, it merges foreign
  where mods itself, placing them in the WHERE clause.

* [CHG] Method _fetchIntoArrayAll() now merges foreign where mods itself. It
  does so either as part of the JOIN ON clause for the subselect strategy,
  or as part of the WHERE clause for the WHERE IN strategy.

* [CHG] Method fetch() now merges "through" where mods into the JOIN ON clause
  for the through table. It also merges foreign where mods itself, placing
  them in the WHERE clause.

* [REF] Rename _modEagerFetchJoin() to _modEagerFetch(), now that parent
  _modEagerFetch() is abstract.

* [BRK] Rename property $through_where to $through_conditions.

* [CHG] Use getForeignConditions() instead of getForeignWhereMods().



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

* [BRK] In method _setRelated(), no longer convert 'join_cond' to 'where'
  clauses on a left join; this was regarded as too magical.  Thanks, Jeff
  Moore, for pointing it out.

* [CHG] Method _setForeignClass() now examines $opts['foreign_name'] to 
  pre-emptively determine the foreign class.

* [CHG] Method _modEagerFetchJoin() now merges foreign where mods itself,
  placing them in the JOIN ON clause.

* [REF] Rename _modEagerFetchJoin() to _modEagerFetch(), now that parent
  _modEagerFetch() is abstract.

* [CHG] Use getForeignConditions() instead of getForeignWhereMods().


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

* [BRK] In method _setRelated(), no longer convert 'join_cond' to 'where'
  clauses on a left join; this was regarded as too magical.  Thanks, Jeff
  Moore, for pointing it out.

* [CHG] Method _setForeignClass() now examines $opts['foreign_name'] to 
  pre-emptively determine the foreign class.

* [CHG] Method _modEagerFetchJoin() now merges foreign where mods itself,
  placing them in the JOIN ON clause.

* [REF] Rename _modEagerFetchJoin() to _modEagerFetch(), now that parent
  _modEagerFetch() is abstract.

* [CHG] Use getForeignConditions() instead of getForeignWhereMods().


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

* [CHG] Implement IteratorAggregate instead of Iterator. This means you should
  no longer need to clone($this) and iterate over the clone, when doing a
  foreach() of the struct from within the struct.

* [DEL] Methods current(), key(), next(), valid(), and rewind(); also property
  $_iterator_valid.

* [ADD] Method getIterator() as part of the IteratorAggregate implementation.

* [ADD] Method getKeys() to get all keys on the struct.


Solar_Test
----------

* [BRK] Rename setup() and teardown() to preTest() and postTest(),
  respectively. This is to be consistent with all other pre- and post-hooks
  throughout Solar. You will need to rename your generated test methods
  accordingly. :-/


Solar_Test_Suite
----------------

* [CHG] The run-test.php script now honors the new preTest() and postTest()
  hooks (vice setup() and teardown(), respectively).

* [FIX] On constructor fail/todo/skip, update the info counts properly.

* [CHG] Show a nicer log message when ignoring multiple tests.

* [CHG] Method _fetchTestCaseConfig() now looks in
  source/vendor/config/run-tests.php for default test configs (previously
  source/vendor/tests/config.php).

* [CHG] In load-tests.php script, trim directory separator from the dir
  argument, so we don't get ugly double-slashes


Solar_Uri
---------

* [ADD] Method getPath() to return the path array as a string, including the
  format.


Solar_View_Helper_ActionHref
----------------------------

* [CHG] If text is empty, use href for the current action.


Solar_View_Helper_Form

* [REF] Extract new methods _buildDecoratorBegin() and _buildDecoratorEnd() to
  build decorator tags. The new methods now add classes based on the element
  ID to the elem, label, and value decorator tags. Thanks, Christian Dailey
  and Bedrich Rios, for the reporting that lead to this feature.


Solar_View_Helper_Head
----------------------

* [CHG] Method fetch() now renders styles as  tags, not
   tags. Thanks, Bedrich Rios, for the report and
  request leading to this change.


Solar_View_Helper_Pager
-----------------------

* [ADD] Public directory with style.css for pager.

* [CHG] Config key 'style_href' defaults to new public directory location.