Compare commits

..

67 Commits

Author SHA1 Message Date
abijah 30c6e0b0f4 Forgot to save the file before the last checkin. Added the possibility of a 'credits' table, but I'll probably be wiping this out moving forward.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@68 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-04 03:48:35 +00:00
abijah 46e3316ce1 Added some changes to try and resolve some accounting problems. However, I may be about to redo the accounting stuff altogether.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@67 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-04 01:56:09 +00:00
abijah e1671a9fca Additional work on generating ledger information. I've been reading up on accounting basics though, and I feel I'm just not going in the right direction. I'm checking this in, since it works somewhat, and will probably try to head in a different direction.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@66 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-04 01:54:15 +00:00
abijah e586268dee Added a couple helpers, including Html, to our app controller and removed Html from each individual controller
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@65 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-03 22:33:03 +00:00
abijah 24730fda1b Added links everywhere for charge/payment/receipt. Also, minor tweaking to the views in a couple places.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@64 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 08:39:33 +00:00
abijah b6ec85205d Added the payments controller and views.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@63 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 08:15:51 +00:00
abijah b6a0809350 Added the charges controller and views. Fixed a couple minor bugs found with receipts.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@62 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 08:05:53 +00:00
abijah f42ce65768 Changed the charge_to date to allow NULL, since not all charges cover a time period (security deposits, some late charges, POS, etc)
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@61 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 07:26:00 +00:00
abijah ef180e7dda Added a receipt controller to verify receipt data
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@60 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 07:24:51 +00:00
abijah 4aa59a40a2 Removed the test code I'd forgot and left in the table element
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@59 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 07:23:42 +00:00
abijah 0c43a0f884 Fixed copy/paste error
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@58 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 07:23:05 +00:00
abijah e65db5c759 Rolled back the last changes, which were checked in for documentation only.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@57 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 06:28:56 +00:00
abijah 59b549955e Added payments under each receipt in the ledger. This isn't something I really want, just something I was testing. Snapshotting before I delete it, since it did work correctly
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@56 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 06:25:59 +00:00
abijah 603a08393e Moved the view action to use the Containable behavior instead of the convoluted bind/unbind
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@55 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 06:17:49 +00:00
abijah 1db887cf38 Removed the debug comments that were helping me with the sitelink migration, and added in the actual comments that were entered in sitelink.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@54 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 05:44:44 +00:00
abijah 4ebe1db2cc Cleaned up the controllers and now make use of the Linkable behavior for listing out items.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@53 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 04:36:28 +00:00
abijah f74073a2e1 Cleaned up the paginate comment remnants and added the undocumented 'extra' parameter to paginate
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@52 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 04:30:32 +00:00
abijah 3f6c526718 Removed the named table alias from each of the HABTM joins, since we don't know in advance what name will be used in the actual join
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@51 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 04:29:26 +00:00
abijah 903209a47e Performed cleanup, and started the thought process of figuring out how to use one link table multiple times in the same query. My changes worked actually, but I want to wait on this to see if I can figure out if there is already a core solution (since it seems likely that things behaving like a tree would have one table used multiple times in the same query... although they probably get around that by running 100 different queries come to think of it).
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@50 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 04:27:34 +00:00
abijah 23a81ae924 I've been around and around with paging. I started using the Containable behavior, which is fantastic for something like 'view', but is highly problematic for listings, especially with pagination. I discovered the Linkable behavior, and it's much more database efficient, and I actually can get it to work with pagination (except when using GROUP BY). I did have to tweak it though, to handle some of the more complex queries that I intend. This checkin includes a bunch of garbage, but given the amount of time I've spent on this crap, I'm afraid to lose anything that might later be useful information. I'll clean up on the next checkin.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@49 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 02:36:26 +00:00
abijah 9db4dd737d Added some of the original formatting back into the sql log table.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@48 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 02:11:48 +00:00
abijah 52528f1c0e Minor tweak to the table headers
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@47 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-01 02:11:14 +00:00
abijah 6bf06a3a3c Changed how fields are handled, so that they are all included by default and the user is not forced to specify them. This works with paginate, but the additional fields are requested in the count query. Would like to resolve this, but it doesn't seem to be confusing paginate.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@46 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-31 18:27:21 +00:00
abijah 387c1ae87b Testing out a possible model behavior called linkable. I may not go this route, but I'll just delete it if not.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@45 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-31 17:02:41 +00:00
abijah 70812e0a0c Getting sidemenu ready for more dynamic actions based on context. Couple minor tweaks to layout.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@44 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-30 20:51:07 +00:00
abijah 7fae1bcaad Modified table element algorithm to be cleaner and to handle multiple class types. Modified ledger listings to group the charges and associated payment rows with one color. Fixed summary balance data to come from the controller instead of being created in the view. Created an infobox to carry pertinent info in the top right of the view pages.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@43 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-30 20:07:24 +00:00
abijah c041174b0c Changed how tables are layed out (since I was repeatedly duplicating code in many places) by adding a table element to be used wherever we need a table. This could probably have been a helper instead of an element, but it's not clear to me why one should be chosen over the other, and I already know how to quickly add an element (I think the real choice resides in whether you need a collection of helper functions, or you just want to drop in a chunk of html, i.e. a helper element). Also, a major revamp to the style sheets as well, although more work is clearly needed.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@42 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-30 15:56:41 +00:00
abijah 2a4b8079fb Added comment blocks and context specific side menu link items. Also tweaked the Page titles and headings for the table listings.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@41 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 16:01:47 +00:00
abijah 79bcf99fc5 Removed unnecessary sidemenu links function, as the overriding class can just call the parent to get the standard links.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@40 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 15:55:50 +00:00
abijah 9d09afca35 Minor CSS layout tweak
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@39 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 15:54:33 +00:00
abijah f384e051bf Initial working version ofa consistent layout with side menu
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@38 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 14:49:11 +00:00
abijah 2da7b6b2c0 Added a higher preference for horizontal unit names
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@37 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 06:57:22 +00:00
abijah 2c85566ffc The map is working quite well now, including the legend. Next steps will be to add the sidemenu.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@36 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 05:10:46 +00:00
abijah db03c73b59 Fixed the underlying hotlink map to match the coordinates of the actual image. Also fixed a few issues with requested_width propogation, although there may still be some bugs.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@35 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 04:37:24 +00:00
abijah 684f02ebc5 More tweaks to get the map working. At the moment, the clickable area is off because it's not scaled like the actual image is. I'll have to work on that next.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@34 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 03:36:28 +00:00
abijah 4e33c58246 Further progress on the site map. The scale is off at the moment, but it's working well enough that it's worth a snapshot.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@33 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 02:45:23 +00:00
abijah 9fc5562dd8 Adding mapping ability. Incomplete as of yet, but coming along nicely.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@32 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-29 01:47:12 +00:00
abijah 3cc8e95ff4 Added a name for our lone map
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@31 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 23:18:20 +00:00
abijah 15930fae30 Moved the unit status logic into the model where it belongs.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@30 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 22:09:04 +00:00
abijah dbe037fee8 Added support for querying only occupied or vacant units. It's working at the moment, but I'll probably move some more logic to the controller next.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@29 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 21:52:14 +00:00
abijah 5c6189cdef Added preliminary support for units. The queries are giving me a heck of a time, so I've cheated in some places. For the most part though, it's working. Also, something went wrong with svn, and view/contacts/view.ctp was not right (a checkin seems to have been omitted on it). This checking brings it up to date.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@28 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 11:26:09 +00:00
abijah 4a86d3dda0 Removal of site_id from the maps table, corresponding with the last checkin
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@27 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 11:09:56 +00:00
abijah ec3d986c78 Removed site_id from the maps table, since the it already references site_area_id which fully qualifies the site anyway.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@26 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 11:09:19 +00:00
abijah e38e99c94e Removed the revisit code, as use of it would only screw up pagination anyway.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@25 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 09:36:58 +00:00
abijah aed2c6912c Added more models
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@24 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 09:27:29 +00:00
abijah 7433e6868c Fixed duplicate row entries and other paginate issues. The fix might be a hack, but it works for now.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@23 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 09:07:53 +00:00
abijah 8393403443 First pass at listing the customers. Need to figure out how to paginate based on a HABTM relationship.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@22 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 08:04:22 +00:00
abijah ed04f81dda Modified to allow the display_name to be NULL
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@21 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 08:03:12 +00:00
abijah 4923712238 Moved the contact info into the contacts controller.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@20 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 07:12:32 +00:00
abijah ffe04ed6fd Added Lease History and security deposit tracking.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@19 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 07:05:05 +00:00
abijah 0021eb1768 Changed the charge/receipt comments slightly to help clarify the intent.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@18 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 06:42:20 +00:00
abijah 0ef51ee30f Added a Financial Accounts table, for allowing transactions to be exported to financial software (definition is presently incomplete). Rearranged the table definitions a bit as well.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@17 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 06:40:40 +00:00
abijah 28bf192853 Added phone and address models as well as outputing them to the view.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@16 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 06:31:07 +00:00
abijah df846f9963 Very, very early snapshot. Some models are working, and I have a controller for testing. Everything is subject to change. I _do_ have a working tenant ledger though, so it's worth a snapshot.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@15 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-28 05:49:03 +00:00
abijah f4007a0269 Adjusted database details and sitelink conversion script to go along with new schema naming convention changes
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@14 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 20:54:14 +00:00
abijah 6b53d8a25a Omission bug on last checkin
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@13 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 20:52:32 +00:00
abijah 76a06d1655 Further naming conventions to match CakePHP
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@12 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 20:49:54 +00:00
abijah eeb8775820 Further changes to the table naming conventions to match expectations of CakePHP
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@11 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 20:32:31 +00:00
abijah 2d9a85ad82 Changed table naming convention
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@10 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 20:25:00 +00:00
abijah 0da1080b86 Added database schema file. For the complete revision history of schema.sql, see branches/rent_manager_20090510/db path of the 'domain' repository
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@9 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 19:47:48 +00:00
abijah 2665d012c2 Added a scripts directory and the latest copy of our sitelink conversion script. For the complete revision history of sitelink2pmgr.pl, see branches/rent_manager_20090510 path of the 'domain' repository
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@8 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 19:26:04 +00:00
abijah c5d5e2c651 Removed the cache files from the repository
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@7 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 19:23:05 +00:00
abijah c22be388cf Fixed the stupid svn:ignore properties, which all had a trailing space (doh!)
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@6 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 04:35:43 +00:00
abijah 220284d20f Added svn:ignore for all of the tmp directories
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@5 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 04:24:45 +00:00
abijah 4502b73b2e Load pmgr into branches/initial_20090526/site.
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@4 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 04:18:23 +00:00
abijah 3251ba340d Create directories to load project into.
* branches/initial_20090526/site: New directory.


git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@3 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 04:18:18 +00:00
Abijah c9f9d0867b Added branch point for initial work. The site directory will be added using the svn_import script, and will represent the output of the command 'cake bake pmgr'
git-svn-id: file:///svn-source/pmgr/branches/initial_20090526@2 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-05-27 04:17:45 +00:00
545 changed files with 5245 additions and 38509 deletions
-394
View File
@@ -1,394 +0,0 @@
<?php
/* SVN FILE: $Id: app_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
/**
* Short description for file.
*
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.app
* @since CakePHP(tm) v 0.2.9
* @version $Revision: 7945 $
* @modifiedby $LastChangedBy: gwoo $
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Short description for class.
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @package cake
* @subpackage cake.app
*/
class AppController extends Controller {
var $helpers = array('Html', 'Form', 'Javascript', 'Format', 'Time');
var $components = array('DebugKit.Toolbar');
function sideMenuLinks() {
return array(
array('name' => 'Common', 'header' => true),
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
array('name' => 'Leases', 'url' => array('controller' => 'leases', 'action' => 'index')),
array('name' => 'Customers', 'url' => array('controller' => 'customers', 'action' => 'index')),
array('name' => 'Contacts', 'url' => array('controller' => 'contacts', 'action' => 'index')),
array('name' => 'Accounts', 'url' => array('controller' => 'accounts', 'action' => 'index')),
array('name' => 'Ledgers', 'url' => array('controller' => 'ledgers', 'action' => 'index')),
);
}
function beforeRender() {
$this->set('sidemenu', $this->sideMenuLinks());
}
/**************************************************************************
**************************************************************************
**************************************************************************
* helper: jqGridView
* - called by function to create an index listing
*/
function jqGridView($title, $action = null) {
$this->set('title', $title);
// The resulting page will contain a jqGrid, which will
// use ajax to obtain the actual data for this action
$this->set('action', $action ? $action : $this->params['action']);
$this->render('/elements/' . $this->params['controller']);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: jqGridData
* - Fetches the actual data requested by jqGrid as XML
*/
function jqGridData() {
// Grab a copy of the parameters that control this request
$params = array();
if (isset($this->params['url']) && is_array($this->params['url']))
$params = $this->params['url'];
// Do any preliminary setup necessary
$this->jqGridDataSetup($params);
// Get the top level model for this grid
$model = $this->jqGridDataModel($params);
// Establish the basic query and conditions
$query = array_intersect_key($this->jqGridDataCountTables($params, $model),
array('link'=>1, 'contain'=>1));
$query['conditions'] = $this->jqGridDataConditions($params, $model);
// Get the number of records prior to pagination
$count = $this->jqGridDataRecordCount($params, $model, $query);
// Start the query over, this time getting the actual set
// of tables needed, not just those needed for counting.
$query = array_intersect_key($this->jqGridDataTables($params, $model),
array('link'=>1, 'contain'=>1));
$query['conditions'] = $this->jqGridDataConditions($params, $model);
// Verify a few parameters and determine our starting row
$limit = $params['rows'];
$total = ($count < 0) ? 0 : ceil($count/$limit);
$page = ($params['page'] <= 1) ? 1 : (($params['page'] > $total) ? $total : $params['page']);
$start = $limit*$page - $limit;
// Grab the actual records taking pagination into account
$query['group'] = $this->jqGridDataGroup($params, $model);
$query['order'] = $this->jqGridDataOrder($params, $model,
isset($params['sidx']) ? $params['sidx'] : null,
isset($params['sord']) ? $params['sord'] : null);
$query['limit'] = $this->jqGridDataLimit($params, $model, $start, $limit);
$query['fields'] = $this->jqGridDataFields($params, $model);
$results = $this->jqGridDataRecords($params, $model, $query);
// Post process the records
$this->jqGridRecordsPostProcess($params, $model, $results);
// Add in any needed hyperlinks
$this->jqGridRecordLinks($params, $model, $results, array());
// DEBUG PURPOSES ONLY!
$params['query'] = $query;
// Finally, dump out the data
$this->jqGridDataOutputHeader($params, $model);
echo "<?xml version='1.0' encoding='utf-8'?>\n";
echo "<rows>\n";
$this->jqGridDataOutputSummary($params, $model, $page, $total, $count);
$this->jqGridDataOutputRecords($params, $model, $results);
echo "</rows>\n";
// Call out to finalize everything
$this->jqGridDataFinalize($params);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* virtual: jqGridData* functions
* - These set up the context for the jqGrid data, and will
* need to be overridden in the derived class for anything
* other than the most basic of grids.
*/
function jqGridDataSetup(&$params) {
// Assume we're debugging.
// The actual jqGrid request will set this to false
$debug = true;
if (isset($this->passedArgs['debug']))
$debug = $this->passedArgs['debug'];
$params['debug'] = $debug;
if (!$debug) {
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
}
// Establish some defaults (except for serialized items)
$params = array_merge(array('page' => 1,
'rows' => 20),
$params);
// Unserialize our complex structure of fields
// This SHOULD always be set, except when debugging
if (isset($params['fields']))
$params['fields'] = unserialize($params['fields']);
else
$params['fields'] = array($this->{$this->modelClass}->alias
.'.'.
$this->{$this->modelClass}->primarKey);
// Unserialize the list of ids, if present.
if (isset($params['custom']))
$params['custom'] = unserialize($params['custom']);
else
$params['custom'] = null;
// Unserialize the list of ids, if present.
if (isset($params['idlist']))
$params['idlist'] = unserialize($params['idlist']);
}
function jqGridDataModel(&$params) {
return $this->{$this->modelClass};
}
function jqGridDataCountTables(&$params, &$model) {
// If not overridden, we use the same tables to
// perform our count as we do to for the actual query
return $this->jqGridDataTables($params, $model);
}
function jqGridDataTables(&$params, &$model) {
return array('contain' => false);
}
function jqGridDataConditions(&$params, &$model) {
$searches = array();
if (isset($params['_search']) && $params['_search'] === 'true') {
if (isset($params['searchOper'])) {
$searches[] = array('op' => $params['searchOper'],
'field' => $params['searchField'],
'value' => $params['searchString']);
}
else {
// DOH! Crappy mechanism puts toolbar search terms
// directly into params as name/value pairs. No
// way to know which elements of params are search
// terms, so skipping this at the moment.
}
}
elseif (isset($params['filt']) && $params['filt']) {
$searches[] = array('op' => 'bw',
'field' => $params['filtField'],
'value' => $params['filtValue']);
}
$ops = array('eq' => array('op' => null, 'pre' => '', 'post' => ''),
'ne' => array('op' => '<>', 'pre' => '', 'post' => ''),
'lt' => array('op' => '<', 'pre' => '', 'post' => ''),
'le' => array('op' => '<=', 'pre' => '', 'post' => ''),
'gt' => array('op' => '>', 'pre' => '', 'post' => ''),
'ge' => array('op' => '>=', 'pre' => '', 'post' => ''),
'bw' => array('op' => 'LIKE', 'pre' => '', 'post' => '%'),
'ew' => array('op' => 'LIKE', 'pre' => '%', 'post' => ''),
'cn' => array('op' => 'LIKE', 'pre' => '%', 'post' => '%'),
);
$conditions = array();
foreach ($searches AS $search) {
$op = $ops[$search['op']];
$field = $search['field'] . ($op['op'] ? ' '.$op['op'] : '');
$value = $op['pre'] . $search['value']. $op['post'];
$conditions[] = array($field => $value);
}
if (isset($params['action']) && $params['action'] === 'idlist') {
if (count($params['idlist']))
$conditions[] = array($model->alias.'.'.$model->primaryKey => $params['idlist']);
else
$conditions[] = '0=1';
}
return $conditions;
}
function jqGridDataFields(&$params, &$model) {
return null;
}
function jqGridDataGroup(&$params, &$model) {
return $model->alias.'.'.$model->primaryKey;
}
function jqGridDataOrder(&$params, &$model, $index, $direction) {
return $index ? array($index .' '. $direction) : null;
}
function jqGridDataLimit(&$params, &$model, $start, $limit) {
return $start . ', ' . $limit;
}
function jqGridDataRecordCount(&$params, &$model, $query) {
return $model->find('count', $query);
}
function jqGridDataRecords(&$params, &$model, $query) {
return $model->find('all', $query);
}
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
$model_alias = $model->alias;
$id = $model->primaryKey;
foreach ($records AS &$record) {
$record['jqGrid_id'] = $record[$model_alias][$id];
// Add the calculated fields (if any), to the model fields
if (isset($record[0])) {
$record[$model_alias] += $record[0];
unset($record[0]);
}
}
// DEBUG PURPOSES ONLY!
//$params['records'] = $records;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
foreach ($links AS $table => $fields) {
$special = array('controller', 'id');
$controller = Inflector::pluralize(Inflector::underscore($table));
$id = 'id';
extract(array_intersect_key($fields, array_flip($special)));
foreach ($records AS &$record) {
if (!isset($record[$table]))
continue;
foreach (array_diff_key($fields, array_flip($special)) AS $field) {
if (!isset($record[$table][$id]) || !isset($record[$table][$field]))
continue;
// DEBUG PURPOSES ONLY!
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
$record[$table][$field] =
'<A HREF="' .
Router::url(array('controller' => $controller,
'action' => 'view',
$record[$table][$id])) .
'">' .
$record[$table][$field] .
'</A>';
}
}
}
}
function jqGridDataOutputHeader(&$params, &$model) {
if ($params['debug']) {
ob_start();
}
else {
header("Content-type: text/xml;charset=utf-8");
}
}
function jqGridDataOutputSummary(&$params, &$model, $page, $total, $records) {
echo " <params><![CDATA[\n" . print_r($params, true) . "\n]]></params>\n";
echo " <page>$page</page>\n";
echo " <total>$total</total>\n";
echo " <records>$records</records>\n";
}
function jqGridDataOutputRecords(&$params, &$model, &$records) {
$id_field = 'jqGrid_id';
foreach ($records AS $record) {
$this->jqGridDataOutputRecord($params, $model, $record,
$record[$id_field], $params['fields']);
}
}
function jqGridDataOutputRecord(&$params, &$model, &$record, $id, $fields) {
echo " <row id='$id'>\n";
foreach ($fields AS $field) {
$this->jqGridDataOutputRecordField($params, $model, $record, $field);
}
echo " </row>\n";
}
function jqGridDataOutputRecordField(&$params, &$model, &$record, $field) {
if (preg_match("/\./", $field)) {
list($tbl, $col) = explode(".", $field);
$data = $record[$tbl][$col];
}
else {
$data = $record[$model->alias][$field];
}
$this->jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
}
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
// be sure to put text data in CDATA
if (preg_match("/^\d*$/", $data))
echo " <cell>$data</cell>\n";
else
echo " <cell><![CDATA[$data]]></cell>\n";
}
function jqGridDataFinalize(&$params) {
if ($params['debug']) {
$xml = ob_get_contents();
ob_end_clean();
$xml = preg_replace("/&/", "&amp;", $xml);
$xml = preg_replace("/</", "&lt;", $xml);
$xml = preg_replace("/>/", "&gt;", $xml);
echo ("\n<PRE>\n$xml\n</PRE>\n");
}
}
}
?>
-167
View File
@@ -1,167 +0,0 @@
<?php
class AccountsController extends AppController {
var $uses = array('Account', 'LedgerEntry');
var $sidemenu_links =
array(array('name' => 'Accounts', 'header' => true),
array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')),
array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')),
array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')),
array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')),
array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')),
array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / asset / liability / equity / income / expense / all
* - Generate a chart of accounts
*/
function index() { $this->all(); }
function asset() { $this->jqGridView('Asset Accounts'); }
function liability() { $this->jqGridView('Liability Accounts'); }
function equity() { $this->jqGridView('Equity Accounts'); }
function income() { $this->jqGridView('Income Accounts'); }
function expense() { $this->jqGridView('Expense Accounts'); }
function all() { $this->jqGridView('All Accounts', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (!isset($params['action']))
$params['action'] = 'all';
}
function jqGridDataCountTables(&$params, &$model) {
return parent::jqGridDataTables($params, $model);
}
function jqGridDataTables(&$params, &$model) {
return array
('link' =>
array(// Models
'CurrentLedger' => array
(// Models
'LedgerEntry'
/* REVISIT <AP> 20090615:
* I'll remove this 'conditions' section on a future checkin,
* after I've proven out the %{MODEL_ALIAS} feature will be
* sticking around.
=> array
('conditions' =>
array('OR' =>
array('LedgerEntry.debit_ledger_id = CurrentLedger.id',
'LedgerEntry.credit_ledger_id = CurrentLedger.id'),
),
),
* END REVISIT
*/
),
),
);
}
function jqGridDataFields(&$params, &$model) {
return array
('Account.*',
'SUM(IF(LedgerEntry.debit_ledger_id = CurrentLedger.id,
LedgerEntry.amount, NULL)) AS debits',
'SUM(IF(LedgerEntry.credit_ledger_id = CurrentLedger.id,
LedgerEntry.amount, NULL)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, 1, -1)
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
) AS balance",
'COUNT(LedgerEntry.id) AS entries');
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if (in_array($params['action'], array('asset', 'liability', 'equity', 'income', 'expense'))) {
$conditions[] = array('Account.type' => strtoupper($params['action']));
}
return $conditions;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Account'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific account
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
// Get details about the account and its ledgers (no ledger entries yet)
$account = $this->Account->find
('first',
array('contain' =>
array(// Models
'CurrentLedger' =>
array('fields' => array('id', 'sequence')),
'Ledger' =>
array('order' => array('Ledger.open_stamp' => 'DESC')),
),
'conditions' => array(array('Account.id' => $id)),
)
);
// Get all ledger entries of the CURRENT ledger
$entries = $this->Account->findLedgerEntries($id);
$account['CurrentLedger']['LedgerEntry'] = $entries['Entries'];
// Summarize each ledger
foreach($account['Ledger'] AS &$ledger)
$ledger = array_merge($ledger,
$this->Account->Ledger->stats($ledger['id']));
// Obtain stats across ALL ledgers for the summary infobox
$stats = $this->Account->stats($id, true);
$stats = $stats['Ledger'];
// Prepare to render
$title = 'Account: ' . $account['Account']['name'];
$this->set(compact('account', 'title', 'stats'));
}
}
-79
View File
@@ -1,79 +0,0 @@
<?php
class ContactsController extends AppController {
var $sidemenu_links = array();
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / all
* - Generate a listing of contacts
*/
function index() { $this->all(); }
function all() { $this->jqGridView('All Contacts', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataOrder(&$params, &$model, $index, $direction) {
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
if ($index === 'Contact.last_name') {
$order[] = 'Contact.first_name ' . $direction;
}
if ($index === 'Contact.first_name') {
$order[] = 'Contact.last_name ' . $direction;
}
return $order;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific contact
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$contact = $this->Contact->find
('first', array
('contain' => array
(// Models
'ContactPhone',
'ContactEmail',
'ContactAddress',
'Customer'),
'conditions' => array('Contact.id' => $id),
));
// Prepare to render.
$title = $contact['Contact']['display_name'];
$this->set(compact('contact', 'title'));
}
}
-250
View File
@@ -1,250 +0,0 @@
<?php
class CustomersController extends AppController {
var $sidemenu_links =
array(array('name' => 'Tenants', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'customers', 'action' => 'current')),
array('name' => 'Past', 'url' => array('controller' => 'customers', 'action' => 'past')),
array('name' => 'All', 'url' => array('controller' => 'customers', 'action' => 'all')),
);
//var $components = array('RequestHandler');
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / current / past / all
* - Creates a list of tenants
*/
function index() { $this->current(); }
function current() { $this->jqGridView('Current Tenants'); }
function past() { $this->jqGridView('Past Tenants'); }
function all() { $this->jqGridView('All Tenants', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (!isset($params['action']))
$params['action'] = 'all';
}
function jqGridDataTables(&$params, &$model) {
return array
('link' =>
array(// Models
'PrimaryContact',
'CurrentLease' => array('fields' => array()),
),
);
}
function jqGridDataFields(&$params, &$model) {
return array('Customer.*',
'COUNT(CurrentLease.id) AS lease_count');
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'current') {
$conditions[] = 'CurrentLease.id IS NOT NULL';
}
elseif ($params['action'] === 'past') {
$conditions[] = 'CurrentLease.id IS NULL';
}
return $conditions;
}
function jqGridDataOrder(&$params, &$model, $index, $direction) {
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
if ($index === 'PrimaryContact.last_name') {
$order[] = 'PrimaryContact.first_name ' . $direction;
}
if ($index === 'PrimaryContact.first_name') {
$order[] = 'PrimaryContact.last_name ' . $direction;
}
return $order;
}
function jqGridDataRecordCount(&$params, &$model, $query) {
// We don't have a good way to use the query to obtain
// our count. The problem is that we're relying on the
// group by for the query, which will destroy the count,
// whether we omit the group by or leave it in.
// So, build a fresh query for counting.
$query['conditions'] = parent::jqGridDataConditions($params, $model);
$count = $model->find('count',
array_merge(array('link' => array_diff_key($query['link'],
array('CurrentLease'=>1))),
array_diff_key($query, array('link'=>1))));
if ($params['action'] === 'all')
return $count;
$query['conditions'][] = 'CurrentLease.id IS NULL';
$count_past = $model->find('count', $query);
// Since we can't easily count 'current' directly, we
// can quickly derive it since 'current' customers
// are mutually exclusive to 'past' customers.
if ($params['action'] == 'current')
$count = $count - $count_past;
elseif ($params['action'] == 'past') {
$count = $count_past;
}
return $count;
}
function jqGridDataRecords(&$params, &$model, $query) {
$customers = parent::jqGridDataRecords($params, $model, $query);
// Get the balance on each customer.
foreach ($customers AS &$customer) {
$stats = $this->Customer->stats($customer['Customer']['id']);
$customer['Customer']['balance'] = $stats['balance'];
}
return $customers;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Customer'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific customer
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$customer = $this->Customer->details($id);
$outstanding_balance = $customer['stats']['balance'];
$outstanding_deposit = $customer['deposits']['summary']['balance'];
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Payment', 'url' => array('action' => 'payment', $id));
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
// Prepare to render.
$title = $customer['Customer']['name'];
$this->set(compact('customer', 'title',
'outstanding_balance',
'outstanding_deposit'));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: payment
* - Sets up the payment entry page for the given customer.
*/
function payment($id = null) {
/* if (!$id) { */
/* $this->Session->setFlash(__('Invalid Item.', true)); */
/* $this->redirect(array('action'=>'index')); */
/* } */
/* if ($this->RequestHandler->isPost()) { */
/* pr($this->data); */
/* //$this->redirect(array('action'=>'index')); */
/* $customer = $this->data; */
/* } */
if (isset($id)) {
$this->Customer->recursive = -1;
$customer = $this->Customer->read(null, $id);
$customer = $customer['Customer'];
$unreconciled = $this->Customer->findUnreconciledLedgerEntries($id);
$charges = $unreconciled['debit'];
}
else {
$customer = null;
$charges = array('balance' => 0, 'entry' => array());
}
$title = 'Payment Entry';
$this->set(compact('customer', 'charges', 'title'));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unreconciledEntries
* - returns the list of unreconciled entries
*/
function unreconciled($id) {
//$this->layout = 'ajax';
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
header("Content-type: text/xml;charset=utf-8");
App::import('Helper', 'Xml');
$xml = new XmlHelper();
// Find the unreconciled entries, then manipulate the structure
// slightly to accomodate the format necessary for XML Helper.
$unreconciled = $this->Customer->findUnreconciledLedgerEntries($id);
$unreconciled = array('entries' =>
array_intersect_key($unreconciled['debit'],
array('entry'=>1, 'balance'=>1)));
// XML Helper will dump an empty tag if the array is empty
if (!count($unreconciled['entries']['entry']))
unset($unreconciled['entries']['entry']);
pr($unreconciled);
//$reconciled = $cust->reconcileNewLedgerEntry($cust_id, 'credit', $amount);
$opts = array();
//$opts['format'] = 'tags';
echo $xml->header();
echo $xml->serialize($unreconciled, $opts);
}
}
-133
View File
@@ -1,133 +0,0 @@
<?php
class LeasesController extends AppController {
var $sidemenu_links =
array(array('name' => 'Leases', 'header' => true),
array('name' => 'Active', 'url' => array('controller' => 'leases', 'action' => 'active')),
array('name' => 'Closed', 'url' => array('controller' => 'leases', 'action' => 'closed')),
array('name' => 'All', 'url' => array('controller' => 'leases', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / active / closed / all
* - Generate a listing of leases
*/
function index() { $this->all(); }
function active() { $this->jqGridView('Active Leases'); }
function closed() { $this->jqGridView('Closed Leases'); }
function all() { $this->jqGridView('All Leases', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (!isset($params['action']))
$params['action'] = 'all';
}
function jqGridDataTables(&$params, &$model) {
return array
('link' => array('Unit' => array('fields' => array('Unit.id', 'Unit.name')),
'Customer' => array('fields' => array('Customer.id', 'Customer.name'))));
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'active') {
$conditions[] = 'Lease.close_date IS NULL';
}
elseif ($params['action'] === 'closed') {
$conditions[] = 'Lease.close_date IS NOT NULL';
}
return $conditions;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Lease'] = array('number');
$links['Unit'] = array('name');
$links['Customer'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
function jqGridDataRecords(&$params, &$model, $query) {
$leases = parent::jqGridDataRecords($params, $model, $query);
// Get the balance on each lease.
foreach ($leases AS &$lease) {
$stats = $this->Lease->stats($lease['Lease']['id']);
$lease['Lease']['balance'] = $stats['balance'];
}
return $leases;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific lease
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
// Get details about the lease and its ledgers (no ledger entries yet)
$lease = $this->Lease->find
('first',
array('contain' =>
array(// Models
'LeaseType',
'Unit',
'Customer',
),
'conditions' => array(array('Lease.id' => $id)),
'limit' => 2
)
);
// Obtain the overall lease balance
$this->Lease->statsMerge($lease['Lease'],
array('stats' => $this->Lease->stats($id)));
$outstanding_balance = $lease['Lease']['stats']['balance'];
// Determine the lease security deposit
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
$outstanding_deposit = $deposits['summary']['balance'];
// Prepare to render
$title = 'Lease: #' . $lease['Lease']['id'];
$this->set(compact('lease', 'title',
'outstanding_deposit',
'outstanding_balance'));
}
}
-344
View File
@@ -1,344 +0,0 @@
<?php
class LedgerEntriesController extends AppController {
var $sidemenu_links = array();
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (isset($params['custom']['ar_account'])) {
$params['custom']['account_id'] =
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
}
}
function jqGridDataTables(&$params, &$model) {
$link =
array(// Models
'Transaction' =>
array('fields' => array('id', 'stamp'),
),
'MonetarySource' =>
array('fields' => array('id', 'name'),
),
'Customer' =>
array('fields' => array('id', 'name'),
),
'Lease' =>
array('fields' => array('id', 'number'),
'Unit' =>
array('fields' => array('id', 'name'),
),
),
);
if (isset($params['custom']['account_ftype'])) {
$ftype = $params['custom']['account_ftype'];
$ftype = ucfirst($ftype);
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$link[$ftype . 'Ledger'] =
array('fields' => array('id', 'sequence'),
'Account' => array('class' => 'Account',
'fields' => array('id', 'name'),
),
);
}
elseif (isset($params['custom']['ledger_id'])) {
$ledger_id = $params['custom']['ledger_id'];
$link['Ledger'] =
array('fields' => array('id', 'sequence'),
'conditions' => ("Ledger.id = IF(LedgerEntry.debit_ledger_id = $ledger_id," .
" LedgerEntry.credit_ledger_id," .
" LedgerEntry.debit_ledger_id)"),
'Account' => array(
'fields' => array('id', 'name'),
),
);
}
else {
$link['DebitLedger'] =
array('fields' => array('id', 'sequence'),
'DebitAccount' => array('class' => 'Account',
'fields' => array('id', 'name'),
),
);
$link['CreditLedger'] =
array('fields' => array('id', 'sequence'),
'CreditAccount' => array('class' => 'Account',
'fields' => array('id', 'name'),
),
);
}
if (isset($params['custom']['account_id'])) {
$account_id = $params['custom']['account_id'];
$link['Ledger'] =
array('fields' => array('id', 'sequence'),
'conditions' => ("Ledger.id = IF(DebitLedger.account_id = $account_id," .
" LedgerEntry.credit_ledger_id," .
" LedgerEntry.debit_ledger_id)"),
'Account' => array(
'fields' => array('id', 'name'),
),
);
}
if (isset($params['custom']['reconcile_id'])) {
$ftype = $params['custom']['account_ftype'];
$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$ftype = ucfirst($ftype);
$link[$ftype.'ReconciliationLedgerEntry'] =
array('fields' => array('Reconciliation.amount'));
}
return array('link' => $link);
}
function jqGridDataFields(&$params, &$model) {
$ledger_id = (isset($params['custom']['ledger_id'])
? $params['custom']['ledger_id']
: null);
$account_id = (isset($params['custom']['account_id'])
? $params['custom']['account_id']
: null);
$account_type = (isset($params['custom']['account_type'])
? $params['custom']['account_type']
: null);
return $model->ledgerContextFields2($ledger_id, $account_id, $account_type);
}
function jqGridDataConditions(&$params, &$model) {
$ledger_id = (isset($params['custom']['ledger_id'])
? $params['custom']['ledger_id']
: null);
$account_type = (isset($params['custom']['account_type'])
? $params['custom']['account_type']
: null);
$conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'ledger') {
$conditions[] = $model->ledgerContextConditions($ledger_id, $account_type);
}
if (isset($params['custom']['reconcile_id'])) {
$ftype = $params['custom']['account_ftype'];
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$conditions[] = array('Reconciliation.'.$ftype.'_ledger_entry_id' => $params['custom']['reconcile_id']);
}
if (isset($params['custom']['account_id'])) {
$conditions[] =
array('OR' =>
array(array('CreditAccount.id' => $params['custom']['account_id']),
array('DebitAccount.id' => $params['custom']['account_id'])));
}
if (isset($params['custom']['customer_id'])) {
$conditions[] =
array('Customer.id' => $params['custom']['customer_id']);
/* $Account = new Account(); */
/* if (isset($params['custom']['account_ftype']) || */
/* isset($params['custom']['ledger_id'])) { */
/* $conditions[] = */
/* array('OR' => array('Account.id' => $Account->invoiceAccountID(), */
/* 'Account.id' => $Account->receiptAccountID())); */
/* } else { */
/* $conditions[] = */
/* array('OR' => array('DebitAccount.id' => $Account->invoiceAccountID(), */
/* //'CreditAccount.id' => $Account->invoiceAccountID(), */
/* //'DebitAccount.id' => $Account->receiptAccountID(), */
/* 'CreditAccount.id' => $Account->receiptAccountID(), */
/* )); */
/* } */
}
if (isset($params['custom']['lease_id'])) {
$conditions[] =
array('Lease.id' => $params['custom']['lease_id']);
/* $Account = new Account(); */
/* if (isset($params['custom']['account_ftype']) || */
/* isset($params['custom']['ledger_id'])) { */
/* $conditions[] = */
/* array('OR' => array('Account.id' => $Account->invoiceAccountID(), */
/* 'Account.id' => $Account->receiptAccountID())); */
/* } else { */
/* $conditions[] = */
/* array('OR' => array('DebitAccount.id' => $Account->invoiceAccountID(), */
/* //'CreditAccount.id' => $Account->invoiceAccountID(), */
/* //'DebitAccount.id' => $Account->receiptAccountID(), */
/* 'CreditAccount.id' => $Account->receiptAccountID(), */
/* )); */
/* } */
}
if (isset($params['custom']['transaction_id'])) {
$conditions[] =
array('Transaction.id' => $params['custom']['transaction_id']);
}
return $conditions;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Transaction'] = array('id');
$links['LedgerEntry'] = array('id');
$links['Account'] = array('controller' => 'accounts', 'name');
$links['DebitAccount'] = array('controller' => 'accounts', 'name');
$links['CreditAccount'] = array('controller' => 'accounts', 'name');
$links['MonetarySource'] = array('name');
$links['Customer'] = array('name');
$links['Lease'] = array('number');
$links['Unit'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
function jqGridDataGroup(&$params, &$model) {
if (isset($params['custom']['notxgroup']))
return parent::jqGridDataGroup($params, $model);
return $model->alias.'.transaction_id';
}
function jqGridDataOrder(&$params, &$model, $index, $direction) {
/* if ($index === 'balance') */
/* return ($index .' '. $direction); */
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
if ($index === 'Transaction.stamp') {
$order[] = 'LedgerEntry.id ' . $direction;
}
return $order;
}
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
parent::jqGridRecordsPostProcess($params, $model, $records);
$subtotal = 0;
foreach ($records AS &$record) {
$amount = (isset($record['LedgerEntry']['balance'])
? $record['LedgerEntry']['balance']
: $record['LedgerEntry']['amount']);
$record['LedgerEntry']['subtotal'] = ($subtotal += $amount);
continue;
// Experiment to minimize columns by putting the monetary source
// as the Account, when available
if ($record['MonetarySource']['name'])
$record['Account']['name'] = $record['MonetarySource']['name'];
}
}
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
/* if ($field === 'CreditAccount.name') { */
/* $data .= '-OK'; */
/* } */
parent::jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific entry
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
}
// Get the LedgerEntry and related fields
$entry = $this->LedgerEntry->find
('first',
array('contain' => array('MonetarySource.id',
'MonetarySource.name',
'MonetarySource.MonetaryType.id',
'Transaction.id',
'Transaction.stamp',
'DebitLedger.id',
'DebitLedger.sequence',
'DebitLedger.account_id',
'CreditLedger.id',
'CreditLedger.sequence',
'CreditLedger.account_id',
'Customer.id',
'Customer.name',
'Lease.id',
),
'fields' => array('LedgerEntry.id',
'LedgerEntry.amount',
'LedgerEntry.comment'),
'conditions' => array('LedgerEntry.id' => $id),
));
pr($entry);
// Because 'DebitLedger' and 'CreditLedger' both relate to 'Account',
// CakePHP will not include them in the LedgerEntry->find (or so it
// seems). We'll have to break out each Account separately.
// Get the Account from DebitLedger
$entry['DebitLedger'] += $this->LedgerEntry->DebitLedger->Account->find
('first',
array('contain' => true,
'fields' => array('Account.id', 'Account.name', 'Account.type', 'Account.trackable'),
'conditions' => array('Account.id' => $entry['DebitLedger']['account_id']),
));
// Get the Account from CreditLedger
$entry['CreditLedger'] += $this->LedgerEntry->CreditLedger->Account->find
('first',
array('contain' => true,
'fields' => array('Account.id', 'Account.name', 'Account.type', 'Account.trackable'),
'conditions' => array('Account.id' => $entry['CreditLedger']['account_id']),
));
// Get the reconciliation balances for this ledger entry
$stats = $this->LedgerEntry->stats($id);
if ($entry['DebitLedger']['Account']['trackable'])
$stats['debit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['debit_amount_reconciled'];
if ($entry['CreditLedger']['Account']['trackable'])
$stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled'];
//pr($stats);
$reconciled = $this->LedgerEntry->findReconciledLedgerEntries($id);
//pr($reconciled);
// Prepare to render.
$title = "Ledger Entry #{$entry['LedgerEntry']['id']}";
$this->set(compact('entry', 'title', 'reconciled', 'stats'));
}
}
-149
View File
@@ -1,149 +0,0 @@
<?php
class LedgersController extends AppController {
var $sidemenu_links =
array(array('name' => 'Ledgers', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'ledgers', 'action' => 'current')),
array('name' => 'Closed', 'url' => array('controller' => 'ledgers', 'action' => 'closed')),
array('name' => 'All', 'url' => array('controller' => 'ledgers', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / current / closed / all
* - Generate a list of ledgers
*/
function index() { $this->all(); }
function current() { $this->jqGridView('Current Ledgers'); }
function closed() { $this->jqGridView('Closed Ledgers'); }
function all() { $this->jqGridView('All Ledgers', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (!isset($params['action']))
$params['action'] = 'all';
}
function jqGridDataCountTables(&$params, &$model) {
return array('contain' => false);
}
function jqGridDataTables(&$params, &$model) {
return array
('link' =>
array(// Models
'Account',
'LedgerEntry',
),
);
}
function jqGridDataFields(&$params, &$model) {
return array
('Ledger.*',
'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence',
'SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id,
LedgerEntry.amount, NULL)) AS debits',
'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id,
LedgerEntry.amount, NULL)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
) AS balance",
'COUNT(LedgerEntry.id) AS entries');
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'current') {
$conditions[] = array('NOT' => array('Ledger.closed'));
}
elseif ($params['action'] === 'closed') {
$conditions[] = 'Ledger.closed';
}
return $conditions;
}
function jqGridDataOrder(&$params, &$model, $index, $direction) {
$id_sequence = false;
if ($index === 'id_sequence') {
$id_sequence = true;
$index = 'Ledger.account_id';
}
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
if ($id_sequence) {
$order[] = 'Ledger.sequence ' . $direction;
}
return $order;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Ledger'] = array('id_sequence');
$links['Account'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific ledger
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
// Get details about the ledger itself (no entries yet)
$ledger = $this->Ledger->find
('first',
array('contain' =>
array(// Models
'Account',
),
'conditions' => array(array('Ledger.id' => $id)),
)
);
// Get ledger stats for our summary box
$stats = $this->Ledger->stats($id);
// OK, set our view variables and render!
$title = 'Ledger: #' . $ledger['Account']['id'] .'-'. $ledger['Ledger']['sequence'];
$this->set(compact('ledger', 'title', 'stats'));
}
}
@@ -1,77 +0,0 @@
<?php
class MonetarySourcesController extends AppController {
var $sidemenu_links = array();
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / all
* - Generate a listing of MonetarySources
*/
function index() { $this->all(); }
function all() { $this->jqGridView('All MonetarySources', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataTables(&$params, &$model) {
return array
('link' => array('MonetaryType' => array('fields' => array('MonetaryType.id', 'MonetaryType.name')),
),
);
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['MonetarySource'] = array('id');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific entry
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
}
// Get the MonetarySource and related fields
$monetary_source = $this->MonetarySource->find
('first', array
('contain' => array
('MonetaryType',
),
));
// Prepare to render.
$title = "Monetary Source #{$monetary_source['MonetarySource']['id']}";
$this->set(compact('monetary_source', 'title'));
}
}
-288
View File
@@ -1,288 +0,0 @@
<?php
class TransactionsController extends AppController {
var $components = array('RequestHandler');
var $sidemenu_links =
array(array('name' => 'Transactions', 'header' => true),
array('name' => 'All', 'url' => array('controller' => 'transactions', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / all
* - Generate a listing of transactions
*/
function index() { $this->all(); }
function all() { $this->jqGridView('All Transactions', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Transaction'] = array('id');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific transaction
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$transaction = $this->Transaction->find
('first',
array('contain' =>
array(// Models
'LedgerEntry' => array('fields' => array('LedgerEntry.id',
'LedgerEntry.amount',
'LedgerEntry.comment'),
//Models
'DebitLedger' => array
('fields' => array('DebitLedger.id', 'DebitLedger.sequence'),
'Account' => array
('fields' => array('Account.id', 'Account.name')),
),
'CreditLedger' => array
('fields' => array('CreditLedger.id', 'CreditLedger.sequence'),
'Account' => array
('fields' => array('Account.id', 'Account.name')),
),
),
),
'conditions' => array('Transaction.id' => $id),
));
// Figure out the transaction total
$total = 0;
foreach($transaction['LedgerEntry'] AS $entry)
$total += $entry['amount'];
// OK, prepare to render.
$title = 'Transaction #' . $transaction['Transaction']['id'];
$this->set(compact('transaction', 'title', 'total'));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: postReceipt
* - handles the creation of a payment receipt
*/
function postReceipt() {
$this->autoRender = false;
if (!$this->RequestHandler->isPost()) {
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
return;
}
//pr(array('thisdata' => $this->data));
if (isset($this->data['customer_id'])) {
$C = new Customer();
$C->recursive = -1;
$customer = $C->find
('first',
array('contain' => array('Account.CurrentLedger.id'),
'fields' => false,
'conditions' => array('Customer.id', $this->data['customer_id']),
));
$ledger_id = $customer['Account']['CurrentLedger']['id'];
}
else {
// Payment by Unit, Lease, etc
$ledger_id = 0;
}
$amount = 0;
foreach ($this->data['LedgerEntry'] AS &$entry) {
$reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'],
'credit',
$entry['amount']);
pr(compact('entry', 'reconciled'));
foreach ($reconciled['debit']['entry'] AS $rec) {
$entry['DebitReconciliationLedgerEntry'] =
array('amount' => $rec['applied'],
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => $rec['id']
);
}
$amount += isset($entry['amount']) ? $entry['amount'] : 0;
$entry['debit_ledger_id'] = 6; // Cash/Payments
$entry['credit_ledger_id'] = $ledger_id;
}
pr($this->data);
$T = new Transaction();
$T->create();
if ($T->saveAll($this->data,
array(
'validate' => false,
//'fieldList' => array(),
//'callbacks' => true,
))) {
$tid = $T->id;
$this->Session->setFlash(__("New Transaction Created ($tid)!", true));
//$this->redirect(array('action'=>'view', $mid));
}
else {
$this->autoRender = false;
pr(array('checkpoint' => "saveAll failed"));
}
pr($T->data);
$C = new Customer();
$LE = new LedgerEntry();
/* $reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'], */
/* 'credit', */
/* $amount); */
/* pr(compact('amount', 'unreconciled', 'reconciled')); */
/* return; */
foreach ($this->data['LedgerEntry'] AS &$entry) {
$reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'],
'credit',
$entry['amount']);
pr(compact('entry', 'reconciled'));
continue;
foreach ($reconciled['debit']['entry'] AS $rec) {
$data = array('LedgerEntry' =>
array('DebitReconciliationLedgerEntry' =>
array('amount' => $rec['applied'],
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => $rec['id']
),
),
);
//'DebitReconciliationLedgerEntry' => array(
//pr(compact('amount', 'unreconciled', 'reconciled'));
}
}
}
function saveTest() {
$data =
array(
/* 'Customer' => array */
/* ('id' => 7, */
/* ), */
'LedgerEntry' => array
(
'0' => array(
'amount' => 100,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'MonetarySource' => array('name' => 'testmoney', 'monetary_type_id' => 2),
),
'1' => array(
'amount' => 101,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'MonetarySource' => array('name' => 'testmoney2', 'monetary_type_id' => 2),
),
),
'Transaction' => array
(
'stamp' => '06/18/2009',
'comment' => 'no comment',
),
);
$data =
/* array( */
/* 'LedgerEntry' => array */
/* ( */
/* '0' => */
array(
'amount' => 100,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'transaction_id' => 66,
'DebitReconciliationLedgerEntry' =>
array('amount' => 44,
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => 17,
),
/* ), */
/* ), */
);
//$M = new Transaction();
$M = new LedgerEntry();
$M->create();
$retval = $M->saveAll($data,
array(
'validate' => false,
'fieldList' => array(),
'callbacks' => true,
));
$mid = $M->id;
pr(compact('retval', 'mid'));
if ($mid) {
$this->Session->setFlash(__("New Transaction Created ($mid)!", true));
//$this->redirect(array('action'=>'view', $mid));
}
else {
$this->autoRender = false;
pr(array('checkpoint' => "saveAll failed"));
}
/* $LE = new LedgerEntry(); */
/* $LE->create(); */
/* $ret = $LE->save($data, */
/* array( */
/* 'validate' => false, */
/* 'fieldList' => array(), */
/* 'callbacks' => true, */
/* )); */
/* $leid = $LE->id; */
/* pr(array('checkpoint' => "New Ledger Entry", */
/* compact('leid', 'ret'))); */
//pr($LE);
}
}
-151
View File
@@ -1,151 +0,0 @@
<?php
class UnitsController extends AppController {
var $sidemenu_links =
array(array('name' => 'Units', 'header' => true),
array('name' => 'Occupied', 'url' => array('controller' => 'units', 'action' => 'occupied')),
array('name' => 'Vacant', 'url' => array('controller' => 'units', 'action' => 'vacant')),
array('name' => 'Unavailable', 'url' => array('controller' => 'units', 'action' => 'unavailable')),
array('name' => 'All', 'url' => array('controller' => 'units', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / unavailable / vacant / occupied / all
* - Generate a listing of units
*/
function index() { $this->all(); }
function unavailable() { $this->jqGridView('Unavailable Units'); }
function vacant() { $this->jqGridView('Vacant Units'); }
function occupied() { $this->jqGridView('Occupied Units'); }
function all() { $this->jqGridView('All Units', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (!isset($params['action']))
$params['action'] = 'all';
}
function jqGridDataTables(&$params, &$model) {
$link = array
('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
),
);
if ($params['action'] === 'occupied')
$link['Lease'] = array('fields' => array(),
// Models
'Contact' => array('fields' => array('display_name'),
//'type' => 'LEFT',
),
);
return $link;
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'unavailable') {
$conditions[] = $this->Unit->conditionUnavailable();
}
elseif ($params['action'] === 'vacant') {
$conditions[] = $this->Unit->conditionVacant();
}
elseif ($params['action'] === 'occupied') {
$conditions[] = $this->Unit->conditionOccupied();
}
return $conditions;
}
function jqGridDataOrder(&$params, &$model, $index, $direction) {
if ($index === 'Unit.name') {
$index = 'Unit.sort_order';
}
return parent::jqGridDataOrder($params, $model, $index, $direction);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific unit
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>''));
}
$unit = $this->Unit->find
('first',
array('contain' =>
array(// Models
'UnitSize',
'Lease' => array('Customer'),
'CurrentLease' => array('Customer')
),
'conditions' => array('Unit.id' => $id),
));
// Get the balance on each lease.
foreach ($unit['Lease'] AS &$lease) {
$stats = $this->Unit->Lease->stats($lease['id']);
$lease['balance'] = $stats['balance'];
}
$outstanding_balance = 0;
$outstanding_deposit = 0;
if (isset($unit['CurrentLease']['id'])) {
// Figure out the outstanding balance of the current lease.
$stats = $this->Unit->stats($id);
$outstanding_balance =
$stats['CurrentLease']['balance'];
// Figure out the total security deposit for the current lease.
$deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']);
$outstanding_deposit = $deposits['summary']['balance'];
}
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
// Prepare to render.
$title = 'Unit ' . $unit['Unit']['name'];
$this->set(compact('unit', 'title',
'outstanding_balance',
'outstanding_deposit'));
}
}
+1199
View File
File diff suppressed because it is too large Load Diff
-358
View File
@@ -1,358 +0,0 @@
<?php
class Account extends AppModel {
var $name = 'Account';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'external_name' => array('notempty')
);
var $hasOne = array(
'CurrentLedger' => array(
'className' => 'Ledger',
'conditions' => array('NOT' => array('CurrentLedger.closed'))
),
);
var $hasMany = array(
'Ledger',
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: type
* - Returns the type of this account
*/
function type($id) {
$this->cacheQueries = true;
$account = $this->find('first', array
('recursive' => -1,
'fields' => array('type'),
'conditions' => array(array('Account.id' => $id)),
));
$this->cacheQueries = false;
return $account['Account']['type'];
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: fundamentalType
* - Returns the fundmental type of the account, credit or debit
*/
function fundamentalType($id_or_type) {
if (is_numeric($id_or_type))
$type = $this->type($id_or_type);
else
$type = $id_or_type;
// Asset and Expense accounts are debit accounts
if (in_array(strtoupper($type), array('ASSET', 'EXPENSE')))
return 'debit';
// Otherwise, it's a credit account
return 'credit';
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: fundamentalOpposite
* - Returns the opposite fundmental type of the account, credit or debit
*/
function fundamentalOpposite($id_or_type) {
if (in_array(strtolower($id_or_type), array('credit', 'debit')))
$fund = $id_or_type;
else
$fund = $this->fundamentalType($id_or_type);
if ($fund == 'debit')
return 'credit';
return 'debit';
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: accountNameToID
* - Returns the ID of the named account
*/
function accountNameToID($name) {
$this->cacheQueries = true;
$account = $this->find('first', array
('recursive' => -1,
'conditions' => compact('name'),
));
$this->cacheQueries = false;
return $account['Account']['id'];
}
function securityDepositAccountID() { return $this->accountNameToID('Security Deposit'); }
function rentAccountID() { return $this->accountNameToID('Rent'); }
function accountReceivableAccountID() { return $this->accountNameToID('A/R'); }
function invoiceAccountID() { return $this->accountReceivableAccountID(); }
function receiptAccountID() { return $this->accountReceivableAccountID(); }
//function invoiceAccountID() { return $this->accountNameToID('Invoice'); }
//function receiptAccountID() { return $this->accountNameToID('Receipt'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* function: ledgers
* - Returns an array of ledger ids from the given account
*/
function ledgers($id, $all = false) {
if ($all) {
$contain = array('Ledger' => array('fields' => array('Ledger.id')));
} else {
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
}
$this->cacheQueries = true;
$account = $this->find('first', array
('contain' => $contain,
'fields' => array(),
'conditions' => array(array('Account.id' => $id)),
));
$this->cacheQueries = false;
if ($all) {
$ledger_ids = array();
foreach ($account['Ledger'] AS $ledger)
array_push($ledger_ids, $ledger['id']);
}
else {
$ledger_ids = array($account['CurrentLedger']['id']);
}
/* pr(array('function' => 'Account::ledgers', */
/* 'args' => compact('id', 'all'), */
/* 'return' => $ledger_ids)); */
return $ledger_ids;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findLedgerEntries
* - Returns an array of ledger entries that belong to the given
* account, either just from the current ledger, or from all ledgers.
*/
function findLedgerEntries($id, $all = false, $cond = null, $link = null) {
/* pr(array('function' => 'Account::findLedgerEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* )); */
$entries = array();
foreach ($this->ledgers($id, $all) AS $ledger_id) {
$ledger_entries = $this->Ledger->findLedgerEntries
($ledger_id, $this->type($id), $cond, $link);
$entries = array_merge($entries, $ledger_entries);
}
$stats = $this->stats($id, $all, $cond);
$entries = array('Entries' => $entries,
'summary' => $stats['Ledger']);
/* pr(array('function' => 'Account::findLedgerEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* 'vars' => compact('stats'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findLedgerEntriesRelatedToAccount
* - Returns an array of ledger entries that belong to the given
* account, and are related to a specific account, either just from
* the current ledger, or from all ledgers.
*/
function findLedgerEntriesRelatedToAccount($id, $rel_ids, $all = false, $cond = null, $link = null) {
/* pr(array('function' => 'Account::findLedgerEntriesRelatedToAccount', */
/* 'args' => compact('id', 'rel_ids', 'all', 'cond', 'link'), */
/* )); */
if (!isset($cond))
$cond = array();
if (!is_array($rel_ids))
$rel_ids = array($rel_ids);
$ledger_ids = array();
foreach ($rel_ids AS $rel_id)
$ledger_ids = array_merge($ledger_ids, $this->ledgers($rel_id));
array_push($cond, $this->Ledger->LedgerEntry->conditionEntryAsCreditOrDebit($ledger_ids));
$entries = $this->findLedgerEntries($id, $all, $cond, $link);
/* pr(array('function' => 'Account::findLedgerEntriesRelatedToAccount', */
/* 'args' => compact('id', 'relid', 'all', 'cond', 'link'), */
/* 'vars' => compact('ledger_ids'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findUnreconciledLedgerEntries
* - Returns ledger entries that are not yet reconciled
* (such as charges not paid).
*/
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('Account.id' => $id);
foreach (($fundamental_type
? array($fundamental_type)
: array('debit', 'credit')) AS $fund) {
$ucfund = ucfirst($fund);
$unreconciled[$fund]['entry'] = $this->find
('all', array
('link' => array
('Ledger' => array
('fields' => array(),
"LedgerEntry" => array
('class' => "{$ucfund}LedgerEntry",
'fields' => array('id', 'amount'),
"ReconciliationLedgerEntry" => array
('class' => "{$ucfund}ReconciliationLedgerEntry",
'fields' => array
("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
),
),
),
),
),
'group' => ("LedgerEntry.id" .
" HAVING LedgerEntry.amount" .
" <> COALESCE(SUM(Reconciliation.amount),0)"),
'conditions' => $cond,
'fields' => array(),
));
$balance = 0;
foreach ($unreconciled[$fund]['entry'] AS &$entry) {
$entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)),
$entry[0]);
$balance += $entry['balance'];
}
$unreconciled[$fund]['balance'] = $balance;
}
return $unreconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reconcileNewLedgerEntry
* - Returns which ledger entries a new credit/debit would
* reconcile, and how much.
*
* - REVISIT <AP> 20090617
* This should be subject to different algorithms, such
* as apply to oldest charges first, newest first, to fees
* before rent, etc. Until we get there, I'll hardcode
* whatever algorithm is simplest.
*/
function reconcileNewLedgerEntry($id, $fundamental_type, $amount, $cond = null) {
$ofund = $this->fundamentalOpposite($fundamental_type);
$unreconciled = array($ofund => array('entry'=>array(), 'balance'=>0));
$applied = 0;
// if there is no money in the entry, it can reconcile nothing
// don't bother wasting time sifting ledger entries.
if ($amount > 0) {
$unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund, $cond);
foreach ($unreconciled[$ofund]['entry'] AS $i => &$entry) {
// Determine if amount is sufficient to cover the entry
if ($amount > $entry['balance'])
$apply = $entry['balance'];
elseif ($amount > 0)
$apply = $amount;
else {
unset($unreconciled[$ofund]['entry'][$i]);
continue;
}
$entry['applied'] = $apply;
$entry['reconciled'] += $apply;
$entry['balance'] -= $apply;
$applied += $apply;
$amount -= $apply;
}
}
$unreconciled[$ofund]['unapplied'] = $amount;
$unreconciled[$ofund]['applied'] = $applied;
$unreconciled[$ofund]['balance'] -= $applied;
return $unreconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested account.
*/
function stats($id = null, $all = false, $cond = null) {
if (!$id)
return null;
// All old, closed ledgers MUST balance to 0.
// However, the user may want the ENTIRE running totals,
// (not just the balance), so we may have to query all
// ledgers, as dictated by the $all parameter.
$account = $this->find('first',
array('contain' =>
($all
? array('Ledger' => array
('fields' => array('id')))
: array('CurrentLedger' => array
('fields' => array('id')))
),
'conditions' => array
(array('Account.id' => $id))
));
$stats = array();
if ($all) {
foreach ($account['Ledger'] AS $ledger)
$this->statsMerge($stats['Ledger'],
$this->Ledger->stats($ledger['id'], $cond));
}
else {
$stats['Ledger'] =
$this->Ledger->stats($account['CurrentLedger']['id'], $cond);
}
return $stats;
}
}
?>
-337
View File
@@ -1,337 +0,0 @@
<?php
/*
* LinkableBehavior
* Light-weight approach for data mining on deep relations between models.
* Join tables based on model relations to easily enable right to left find operations.
*
* Can be used as a alternative to the ContainableBehavior:
* - On data fetching only in right to left operations,
* wich means that in "one to many" relations (hasMany, hasAndBelongsToMany)
* should only be used from the "many to one" tables. i.e:
* To fetch all Users assigneds to a Project with ProjectAssignment,
* $Project->find('all', array('link' => 'User', 'conditions' => 'project_id = 1'))
* - Won't produce the desired result as data came from users table will be lost.
* $User->find('all', array('link' => 'Project', 'conditions' => 'project_id = 1'))
* - Will fetch all users related to the specified project in one query
*
* - On data mining as a much lighter approach - can reduce 300+ query find operations
* in one single query with joins; "or your money back!" ;-)
*
* - Has the 'fields' param enabled to make it easy to replace Containable usage,
* only change the 'contain' param to 'link'.
*
* Linkable Behavior. Taking it easy in your DB.
* RafaelBandeira <rafaelbandeira3(at)gmail(dot)com>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @version 1.0;
*/
/**********************************************************************
* NOTE TO <AP> 20090615:
* This structure should be linkable (it was my test case).
$entry = $this->LedgerEntry->find
('first',
array('link' => array('DebitLedger' =>
array(
'fields' => array('id'),
'alias' => 'MyDebitLedger',
'Account' =>
array(
'fields' => array('id'),
'alias' => 'MyDebitAccount'),
),
'MyCreditLedger' =>
array(
'fields' => array('id'),
'class' => 'CreditLedger',
'MyCreditAccount' =>
array(
'fields' => array('id'),
'class' => 'Account'),
),
'MyOtherLedger' =>
array(
'fields' => array('id'),
'class' => 'Ledger',
'alias' => 'AliasToMyOtherLedger',
'Account' =>
array(
'fields' => array('id'),
'alias' => 'AliasToMyOtherAccount'),
),
),
'conditions' => array('LedgerEntry.id' => $id),
));
**********************************************************************/
class LinkableBehavior extends ModelBehavior {
protected $_key = 'link';
protected $_options = array(
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
'conditions' => true, 'fields' => true, 'reference' => true,
'class' => true, 'defaults' => true, 'linkalias' => true,
);
protected $_defaults = array('type' => 'LEFT');
/*
* This is a function for made recursive str_replaces in an array
* NOTE: The palacement of this function is terrible, but I don't
* know if I really want to go down this path or not.
*/
function recursive_array_replace($find, $replace, &$data) {
if (!isset($data))
return;
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value)) {
$this->recursive_array_replace($find, $replace, $data[$key]);
} else {
$data[$key] = str_replace($find, $replace, $value);
}
}
} else {
$data = str_replace($find, $replace, $data);
}
}
public function beforeFind(&$Model, $query) {
/* pr("Linkable::beforeFind() begin"); pr($query); */
if (isset($query[$this->_key])) {
$optionsDefaults = $this->_defaults + array('reference' =>
array('class' => $Model->alias,
'alias' => $Model->alias),
$this->_key => array());
$optionsKeys = $this->_options + array($this->_key => true);
if (!isset($query['fields']) || $query['fields'] === true) {
//$query['fields'] = array_keys($Model->_schema);
$query['fields'] = $Model->getDataSource()->fields($Model);
} elseif (!is_array($query['fields'])) {
$query['fields'] = array($query['fields']);
}
$query = am(array('joins' => array()), $query, array('recursive' => -1));
$iterators[] = $query[$this->_key];
$cont = 0;
do {
$iterator = $iterators[$cont];
$defaults = $optionsDefaults;
if (isset($iterator['defaults'])) {
$defaults = array_merge($defaults, $iterator['defaults']);
unset($iterator['defaults']);
}
$iterations = Set::normalize($iterator);
/* pr(array('checkpoint' => 'Iterations', compact('iterations'))); */
foreach ($iterations as $alias => $options) {
if (is_null($options)) {
$options = array();
}
$options = am($defaults, compact('alias'), $options);
if (empty($options['alias'])) {
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
}
if (empty($options['class']))
$options['class'] = $alias;
/* pr(array('checkpoint' => 'Begin Model Work', compact('alias', 'options'))); */
$modelClass = $options['class'];
$modelAlias = $options['alias'];
$referenceClass = $options['reference']['class'];
$referenceAlias = $options['reference']['alias'];
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
$Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
/* pr(array('checkpoint' => 'Aliases Established', */
/* 'Model' => ($modelAlias .' : '. $modelClass . */
/* ' ('. $_Model->alias .' : '. $_Model->name .')'), */
/* 'Reference' => ($referenceAlias .' : '. $referenceClass . */
/* ' ('. $Reference->alias .' : '. $Reference->name .')'))); */
$db =& $_Model->getDataSource();
$associatedThroughReference = 0;
$association = null;
// Figure out how these two models are related, creating
// a relationship if one doesn't otherwise already exists.
if (($associations = $Reference->getAssociated()) &&
isset($associations[$_Model->alias])) {
/* pr("Reference defines association to _Model"); */
$associatedThroughReference = 1;
$type = $associations[$_Model->alias];
$association = $Reference->{$type}[$_Model->alias];
}
elseif (($associations = $_Model->getAssociated()) &&
isset($associations[$Reference->alias])) {
/* pr("_Model defines association to Reference"); */
$type = $associations[$Reference->alias];
$association = $_Model->{$type}[$Reference->alias];
}
else {
// No relationship... make our best effort to create one.
/* pr("No assocation between _Model and Reference"); */
$type = 'belongsTo';
$_Model->bind($Reference->alias);
// Grab the association now, since we'll unbind in a moment.
$association = $_Model->{$type}[$Reference->alias];
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
}
// Determine which model holds the foreign key
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) {
$primaryAlias = $referenceAlias;
$foreignAlias = $modelAlias;
$primaryModel = $Reference;
$foreignModel = $_Model;
} else {
$primaryAlias = $modelAlias;
$foreignAlias = $referenceAlias;
$primaryModel = $_Model;
$foreignModel = $Reference;
}
if ($associatedThroughReference)
$associationAlias = $referenceAlias;
else
$associationAlias = $modelAlias;
$this->recursive_array_replace("%{MODEL_ALIAS}",
$associationAlias,
$association['conditions']);
/* pr(array('checkpoint' => 'Models Established - Check Associations', */
/* 'primaryModel' => $primaryAlias .' : '. $primaryModel->name, */
/* 'foreignModel' => $foreignAlias .' : '. $foreignModel->name, */
/* compact('type', 'association'))); */
if (empty($options['conditions'])) {
if ($type === 'hasAndBelongsToMany') {
if (isset($association['with']))
$linkClass = $association['with'];
else
$linkClass = Inflector::classify($association['joinTable']);
$Link =& $_Model->{$linkClass};
if (isset($options['linkalias']))
$linkAlias = $options['linkalias'];
else
$linkAlias = $Link->alias;
// Get the foreign key fields (for the link table) directly from
// the defined model associations, if they exists. This is the
// users direct specification, and therefore definitive if present.
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
$referenceLink = $Link->escapeField($association['associationForeignKey'], $linkAlias);
// If we haven't figured out the foreign keys, see if there is a
// model for the link table, and if it has the appropriate
// associations with the two tables we're trying to join.
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
// We're running quite thin here. None of the models spell
// out the appropriate linkages. We'll have to SWAG it.
if (empty($modelLink))
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
if (empty($referenceLink))
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
// Get the primary key from the tables we're joining.
$referenceKey = $Reference->escapeField(null, $referenceAlias);
$modelKey = $_Model->escapeField(null, $modelAlias);
// Join the linkage table to our model. We'll use an inner join,
// as the whole purpose of the linkage table is to make this
// connection. As we are embedding this join, the INNER will not
// cause any problem with the overall query, should the user not
// be concerned with whether or not the join has any results.
// They control that with the 'type' parameter which will be at
// the top level join.
$options['joins'][] = array('type' => 'INNER',
'alias' => $modelAlias,
'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true));
// Now for the top level join. This will be added into the list
// of joins down below, outside of the HABTM specific code.
$options['class'] = $linkClass;
$options['alias'] = $linkAlias;
$options['table'] = $Link->getDataSource()->fullTableName($Link);
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
}
elseif (isset($association['foreignKey']) && $association['foreignKey']) {
$foreignKey = $primaryModel->escapeField($association['foreignKey'], $primaryAlias);
$primaryKey = $foreignModel->escapeField($foreignModel->primaryKey, $foreignAlias);
// Only differentiating to help show the logical flow.
// Either way works and this test can be tossed out
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference)
$options['conditions'][] = "{$primaryKey} = {$foreignKey}";
else
$options['conditions'][] = "{$foreignKey} = {$primaryKey}";
}
else {
// No Foreign Key... nothing we can do.
$options['conditions'] = array();
}
// The user may have specified conditions directly in the model
// for this join. Make sure to adhere to those conditions.
if (isset($association['conditions']) && is_array($association['conditions']))
$options['conditions'] = array_merge($options['conditions'], $association['conditions']);
elseif (!empty($association['conditions']))
$options['conditions'][] = $association['conditions'];
}
if (empty($options['table'])) {
$options['table'] = $db->fullTableName($_Model, true);
}
if (!isset($options['fields']) || !is_array($options['fields']))
$options['fields'] = $db->fields($_Model, $modelAlias);
elseif (!empty($options['fields']))
$options['fields'] = $db->fields($_Model, $modelAlias, $options['fields']);
$query['fields'] = array_merge($query['fields'], $options['fields'],
(empty($association['fields'])
? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
/* pr(array('checkpoint' => 'Model Work Complete', compact('options', 'modelClass', 'modelAlias'))); */
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
$options = array_intersect_key($options, $optionsKeys);
if (!empty($options[$this->_key])) {
$iterators[] = $options[$this->_key] +
array('defaults' =>
array_merge($defaults,
array('reference' =>
array('class' => $modelClass,
'alias' => $modelAlias))));
}
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
}
++$cont;
$notDone = isset($iterators[$cont]);
} while ($notDone);
}
/* pr(array('checkpoint' => 'Linkable::beforeFind() end', */
/* compact('query'))); */
return $query;
}
}
-35
View File
@@ -1,35 +0,0 @@
<?php
class Contact extends AppModel {
var $name = 'Contact';
var $validate = array(
'id' => array('numeric'),
'display_name' => array('notempty'),
'id_federal' => array('ssn'),
'id_exp' => array('date')
);
var $hasAndBelongsToMany = array(
'Customer',
'ContactAddress' => array(
'joinTable' => 'contacts_methods',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'POST'",
),
'ContactPhone' => array(
'joinTable' => 'contacts_methods',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'PHONE'",
),
'ContactEmail' => array(
'joinTable' => 'contacts_methods',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'EMAIL'",
),
);
}
?>
-207
View File
@@ -1,207 +0,0 @@
<?php
class Customer extends AppModel {
var $name = 'Customer';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
);
var $belongsTo = array(
'PrimaryContact' => array(
'className' => 'Contact',
),
);
var $hasMany = array(
'CurrentLease' => array(
'className' => 'Lease',
'conditions' => 'CurrentLease.close_date IS NULL',
),
'Lease',
'LedgerEntry',
// Cheat to get Account set as part of this class
'Account',
);
var $hasAndBelongsToMany = array(
'Contact',
'Transaction' => array(
'joinTable' => 'ledger_entries',
'foreignKey' => 'customer_id',
'associationForeignKey' => 'transaction_id',
),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: accountId
* - Returns the account ID for the given customer
*/
function accountId($id) {
$this->cacheQueries = true;
$customer = $this->find('first',
array('contain' => false,
'fields' => array('account_id'),
'conditions' => array(array('Customer.id' => $id))));
$this->cacheQueries = false;
return $customer['Customer']['account_id'];
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: leaseIds
* - Returns the lease IDs for the given customer
*/
function leaseIds($id) {
$this->cacheQueries = true;
$customer = $this->find('first',
array('contain' =>
array('Lease' => array('fields' => array('id'))),
'fields' => array(),
'conditions' => array(array('Customer.id' => $id))));
$this->cacheQueries = false;
$ids = array();
foreach ($customer['Lease'] AS $lease)
$ids[] = $lease['id'];
return $ids;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findSecurityDeposits
* - Returns an array of security deposit entries
*/
function findSecurityDeposits($id, $link = null) {
/* pr(array('function' => 'Customer::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* )); */
$entries = $this->Account->findLedgerEntriesRelatedToAccount
($this->Account->invoiceAccountID(),
$this->Account->securityDepositAccountID(),
true, array('LedgerEntry.customer_id' => $id), $link);
/* pr(array('function' => 'Customer::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* 'vars' => compact('customer'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findUnreconciledLedgerEntries
* - Returns ledger entries that are not yet reconciled
* (such as charges not paid).
*/
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
$unreconciled = $this->Account->findUnreconciledLedgerEntries
($this->Account->accountReceivableAccountID(),
$fundamental_type,
array('LedgerEntry.customer_id' => $id));
return $unreconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reconcileNewLedgerEntry
* - Returns which ledger entries a new credit/debit would
* reconcile, and how much.
*
* - REVISIT <AP> 20090617
* This should be subject to different algorithms, such
* as apply to oldest charges first, newest first, to fees
* before rent, etc. Until we get there, I'll hardcode
* whatever algorithm is simplest.
*/
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
$reconciled = $this->Account->reconcileNewLedgerEntry
($this->Account->accountReceivableAccountID(),
$fundamental_type,
$amount,
array('LedgerEntry.customer_id' => $id));
return $reconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: details
* - Returns detail information for the customer
*/
function details($id = null) {
// Query the DB for need information.
$customer = $this->find
('first', array
('contain' => array
(// Models
'Contact' =>
array(// Models
'ContactPhone',
'ContactEmail',
'ContactAddress',
),
'Lease' =>
array('Unit' =>
array('order' => array('sort_order'),
'fields' => array('id', 'name'),
),
),
),
'conditions' => array('Customer.id' => $id),
));
// Figure out the outstanding balance for this customer
$customer['stats'] = $this->stats($id);
// Figure out the total security deposit for the current lease.
$customer['deposits'] = $this->findSecurityDeposits($id);
return $customer;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested customer.
*/
function stats($id = null) {
if (!$id)
return null;
$stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
array('LedgerEntry.customer_id' => $id));
// Pull to the top level and return
$stats = $stats['Ledger'];
return $stats;
}
}
?>
-158
View File
@@ -1,158 +0,0 @@
<?php
class Lease extends AppModel {
var $name = 'Lease';
var $validate = array(
'id' => array('numeric'),
'number' => array('alphanumeric'),
'lease_type_id' => array('numeric'),
'unit_id' => array('numeric'),
'late_schedule_id' => array('numeric'),
'lease_date' => array('date'),
'movein_planned_date' => array('date'),
'movein_date' => array('date'),
'moveout_date' => array('date'),
'moveout_planned_date' => array('date'),
'notice_given_date' => array('date'),
'notice_received_date' => array('date'),
'close_date' => array('date'),
'deposit' => array('money'),
'amount' => array('money'),
'next_amount' => array('money'),
'next_amount_date' => array('date')
);
var $belongsTo = array(
'LeaseType',
'Unit',
'Customer',
'LateSchedule',
);
var $hasMany = array(
'LedgerEntry',
// Cheat to get Account set as part of this class
'Account',
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: accountId
* - Returns the accountId of the given lease
*/
function accountId($id) {
return $this->Account->invoiceAccountID();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findAccountEntries
* - Returns an array of ledger entries from the account of the given
* lease.
*/
function findAccountEntries($id, $all = false, $cond = null, $link = null) {
/* pr(array('function' => 'Lease::findAccountEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* )); */
if (!isset($cond))
$cond = array();
$cond[] = array('LedgerEntry.lease_id' => $id);
$entries = $this->Account->findLedgerEntries($this->accountId($id),
$all, $cond, $link);
/* pr(array('function' => 'Lease::findAccountEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* 'vars' => compact('lease'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findSecurityDeposits
* - Returns an array of security deposit entries
*/
function findSecurityDeposits($id, $link = null) {
/* pr(array('function' => 'Lease::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* )); */
$entries = $this->Account->findLedgerEntriesRelatedToAccount
($this->accountId($id),
$this->Account->securityDepositAccountID(),
true, array('LedgerEntry.lease_id' => $id), $link);
/* pr(array('function' => 'Lease::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* 'vars' => compact('lease'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findUnreconciledLedgerEntries
* - Returns ledger entries that are not yet reconciled
* (such as charges not paid).
*/
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
return $this->Account->findUnreconciledLedgerEntries
($this->accountId($id), $fundamental_type, array('LedgerEntry.lease_id' => $id));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reconcileNewLedgerEntry
* - Returns which ledger entries a new credit/debit would
* reconcile, and how much.
*
* - REVISIT <AP> 20090617
* This should be subject to different algorithms, such
* as apply to oldest charges first, newest first, to fees
* before rent, etc. Until we get there, I'll hardcode
* whatever algorithm is simplest.
*/
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
return $this->Account->reconcileNewLedgerEntry
($this->accountId($id), $fundamental_type, $amount, array('LedgerEntry.lease_id' => $id));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested lease.
*/
function stats($id = null) {
if (!$id)
return null;
$stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
array('LedgerEntry.lease_id' => $id));
// Pull to the top level and return
$stats = $stats['Ledger'];
return $stats;
}
}
?>
-15
View File
@@ -1,15 +0,0 @@
<?php
class LeaseType extends AppModel {
var $name = 'LeaseType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty')
);
var $hasMany = array(
'Lease',
);
}
?>
-154
View File
@@ -1,154 +0,0 @@
<?php
class Ledger extends AppModel {
var $name = 'Ledger';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
);
var $belongsTo = array(
'Account',
);
var $hasMany = array(
'LedgerEntry' => array(
'foreignKey' => false,
// conditions will be used when JOINing tables
// (such as find with LinkableBehavior)
'conditions' => array('OR' =>
array('LedgerEntry.debit_ledger_id = %{MODEL_ALIAS}.id',
'LedgerEntry.credit_ledger_id = %{MODEL_ALIAS}.id')),
// finderQuery will be used when tables are put
// together across several querys, not with JOIN.
// (such as find with ContainableBehavior)
'finderQuery' => 'SELECT `LedgerEntry`.*
FROM pmgr_ledger_entries AS `LedgerEntry`
WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$})
OR LedgerEntry.credit_ledger_id = ({$__cakeID__$})',
'counterQuery' => ''
),
'DebitLedgerEntry' => array(
'className' => 'LedgerEntry',
'foreignKey' => 'debit_ledger_id',
'dependent' => false,
),
'CreditLedgerEntry' => array(
'className' => 'LedgerEntry',
'foreignKey' => 'credit_ledger_id',
'dependent' => false,
),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findLedgerEntries
* - Returns an array of ledger entries that belong to a given
* ledger. There is extra work done... see the LedgerEntry model.
*/
function findLedgerEntries($id, $account_type = null, $cond = null, $link = null) {
/* pr(array('function' => 'Ledger::findLedgerEntries', */
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
/* )); */
if (!isset($account_type)) {
$ledger = $this->find('first', array
('contain' => array
('Account' => array
('fields' => array('type'),
),
),
'fields' => array(),
'conditions' => array(array('Ledger.id' => $id)),
));
$account_type = $ledger['Account']['type'];
}
// If the requested entries are limited by date, we must calculate
// a balance forward, or the resulting balance will be thrown off.
//
// REVISIT <AP>: This obviously is more general than date.
// As such, it will not work (or, only work if the
// condition only manages to exclude the first parts
// of the ledger, nothing in the middle or at the
// end. For now, I'll just create an 'other' entry,
// not necessarily a balance forward.
$bf = array();
if (0 && isset($cond)) {
//$date = '<NOT IMPLEMENTED>';
$stats = $this->stats($id, array('NOT' => array($cond)));
$bf = array(array(array('debit' => $stats['debits'],
'credit' => $stats['credits'],
'balance' => $stats['balance']),
'LedgerEntry' => array('id' => null,
//'comment' => "Balance Forward from $date"),
'comment' => "-- SUMMARY OF EXCLUDED ENTRIES --"),
'Transaction' => array('id' => null,
//'stamp' => $date,
'stamp' => null,
'comment' => null),
));
}
$entries = $this->LedgerEntry->findInLedgerContext($id, $account_type, $cond, $link);
/* pr(array('function' => 'Ledger::findLedgerEntries', */
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
/* 'vars' => compact('ledger'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested ledger.
*/
function stats($id, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('Ledger.id' => $id);
$stats = $this->find
('first', array
('link' =>
array(// Models
'Account' => array('fields' => array()),
//'LedgerEntry' => array('fields' => array()),
'LedgerEntry' =>
array('fields' => array(),
'Transaction' => array('fields' => array('stamp')),
),
),
'fields' =>
array("SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id,
LedgerEntry.amount, NULL)) AS debits",
"SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id,
LedgerEntry.amount, NULL)) AS credits",
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
) AS balance",
"COUNT(LedgerEntry.id) AS entries"),
'conditions' => $cond,
'group' => 'Ledger.id',
));
// The fields are all tucked into the [0] index,
// and the rest of the array is useless (empty).
return $stats[0];
}
}
?>
-242
View File
@@ -1,242 +0,0 @@
<?php
class LedgerEntry extends AppModel {
var $name = 'LedgerEntry';
var $validate = array(
'id' => array('numeric'),
'transaction_id' => array('numeric'),
'amount' => array('money')
);
var $belongsTo = array(
'MonetarySource',
'Transaction',
'Customer',
'Lease',
'DebitLedger' => array(
'className' => 'Ledger',
'foreignKey' => 'debit_ledger_id',
),
'CreditLedger' => array(
'className' => 'Ledger',
'foreignKey' => 'credit_ledger_id',
),
);
var $hasAndBelongsToMany = array(
'DebitReconciliationLedgerEntry' => array(
'className' => 'LedgerEntry',
'joinTable' => 'reconciliations',
'foreignKey' => 'credit_ledger_entry_id',
'associationForeignKey' => 'debit_ledger_entry_id',
),
'CreditReconciliationLedgerEntry' => array(
'className' => 'LedgerEntry',
'joinTable' => 'reconciliations',
'foreignKey' => 'debit_ledger_entry_id',
'associationForeignKey' => 'credit_ledger_entry_id',
),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: conditionEntryAsCreditOrDebit
* - returns the condition necessary to match a set of
* Ledgers to all related LedgerEntries
*/
function conditionEntryAsCreditOrDebit($ledger_ids) {
return array('OR' =>
array(array('debit_ledger_id' => $ledger_ids),
array('credit_ledger_id' => $ledger_ids)));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: ledgerContext query helpers
* - Returns parameters necessary to generate a query which
* puts ledger entries into the context of a ledger. Since
* debit/credit depends on the account type, it is required
* as an argument for each function to avoid having to
* query the ledger/account to find it out.
*/
function ledgerContextFields($ledger_id = null, $account_type = null) {
$fields = array('id', 'name', 'comment', 'amount');
if (isset($ledger_id)) {
$fields[] = ("IF(LedgerEntry.debit_ledger_id = $ledger_id," .
" LedgerEntry.amount, NULL) AS debit");
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
" LedgerEntry.amount, NULL) AS credit");
if (isset($account_type)) {
if (in_array($account_type, array('ASSET', 'EXPENSE')))
$ledger_type = 'debit';
else
$ledger_type = 'credit';
$fields[] = ("(IF(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id," .
" 1, -1) * LedgerEntry.amount) AS balance");
}
}
return $fields;
}
function ledgerContextFields2($ledger_id = null, $account_id = null, $account_type = null) {
$fields = array('id', 'name', 'comment', 'amount');
if (isset($ledger_id)) {
$fields[] = ("IF(LedgerEntry.debit_ledger_id = $ledger_id," .
" SUM(LedgerEntry.amount), NULL) AS debit");
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
" SUM(LedgerEntry.amount), NULL) AS credit");
if (isset($account_id) || isset($account_type)) {
$Account = new Account();
$account_ftype = $Account->fundamentalType($account_id ? $account_id : $account_type);
$fields[] = ("(IF(LedgerEntry.{$account_ftype}_ledger_id = $ledger_id," .
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
}
}
elseif (isset($account_id)) {
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
" SUM(LedgerEntry.amount), NULL) AS debit");
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
" SUM(LedgerEntry.amount), NULL) AS credit");
$Account = new Account();
$account_ftype = ucfirst($Account->fundamentalType($account_id));
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id," .
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
}
return $fields;
}
function ledgerContextConditions($ledger_id, $account_type) {
if (isset($ledger_id)) {
return array
('OR' =>
array(array('LedgerEntry.debit_ledger_id' => $ledger_id),
array('LedgerEntry.credit_ledger_id' => $ledger_id)),
);
}
return array();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findInLedgerContext
* - Returns an array of ledger entries that belong to a given ledger.
* There is extra logic to also figure out whether the ledger_entry
* amount is either a credit, or a debit, depending on how it was
* written into the ledger, as well as whether the amount increases or
* decreases the balance depending on the particular account type of
* the ledger.
*/
function findInLedgerContext($ledger_id, $account_type, $cond = null, $link = null) {
if (!isset($link))
$link = array('Transaction');
if (!isset($cond))
$cond = array();
$fields = $this->ledgerContextFields($ledger_id, $account_type);
$cond[] = $this->ledgerContextConditions($ledger_id, $account_type);
$order = array('Transaction.stamp');
$entries = $this->find
('all',
array('link' => $link,
'fields' => $fields,
'conditions' => $cond,
'order' => $order,
));
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findReconciledLedgerEntries
* - Returns ledger entries that are reconciled to the given entry.
* (such as payments towards a charge).
*/
function findReconciledLedgerEntries($id = null, $fundamental_type = null) {
foreach (($fundamental_type
? array($fundamental_type)
: array('debit', 'credit')) AS $fund) {
$ucfund = ucfirst($fund);
$reconciled[$fund]['entry'] = $this->find
('all', array
('link' => array
("ReconciliationLedgerEntry" => array
('class' => "{$ucfund}ReconciliationLedgerEntry",
'fields' => array
('id',
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
),
),
),
'group' => ("ReconciliationLedgerEntry.id"),
'conditions' => array('LedgerEntry.id' => $id),
'fields' => array(),
));
//pr($reconciled);
$balance = 0;
foreach ($reconciled[$fund]['entry'] AS &$entry) {
$entry = array_merge($entry["ReconciliationLedgerEntry"], $entry[0]);
$balance += $entry['balance'];
}
$reconciled[$fund]['balance'] = $balance;
}
return $reconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested ledger entry
*/
function stats($id) {
$query = array
(
'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"),
'conditions' => array(isset($cond) ? $cond : array(),
array('LedgerEntry.id' => $id)),
'group' => 'LedgerEntry.id',
);
// Get the applied amounts on the debit side
$query['link'] =
array('DebitReconciliationLedgerEntry' => array('alias' => 'DRLE', 'DRLETransaction' => array('class' => 'Transaction')));
$tmpstats = $this->find('first', $query);
$stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled'];
// Get the applied amounts on the credit side
$query['link'] =
array('CreditReconciliationLedgerEntry' => array('alias' => 'CRLE', 'CRLETransaction' => array('class' => 'Transaction')));
$tmpstats = $this->find('first', $query);
$stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled'];
return $stats;
}
}
-23
View File
@@ -1,23 +0,0 @@
<?php
class Map extends AppModel {
var $name = 'Map';
var $validate = array(
'id' => array('numeric'),
'site_id' => array('numeric'),
'site_area_id' => array('numeric'),
'name' => array('notempty'),
'width' => array('numeric'),
'depth' => array('numeric')
);
var $belongsTo = array(
'SiteArea',
);
var $hasAndBelongsToMany = array(
'Unit',
);
}
?>
-20
View File
@@ -1,20 +0,0 @@
<?php
class MonetarySource extends AppModel {
var $name = 'MonetarySource';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'tillable' => array('boolean')
);
var $belongsTo = array(
'MonetaryType',
);
var $hasMany = array(
'LedgerEntry',
);
}
?>
-16
View File
@@ -1,16 +0,0 @@
<?php
class MonetaryType extends AppModel {
var $name = 'MonetaryType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'tillable' => array('boolean')
);
var $hasMany = array(
'MonetarySource',
);
}
?>
-16
View File
@@ -1,16 +0,0 @@
<?php
class Site extends AppModel {
var $name = 'Site';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty')
);
var $hasMany = array(
'SiteArea',
'SiteOption',
);
}
?>
-20
View File
@@ -1,20 +0,0 @@
<?php
class SiteArea extends AppModel {
var $name = 'SiteArea';
var $validate = array(
'id' => array('numeric'),
'site_id' => array('numeric'),
'name' => array('notempty')
);
var $belongsTo = array(
'Site',
);
var $hasOne = array(
'Map',
);
}
?>
-28
View File
@@ -1,28 +0,0 @@
<?php
class Transaction extends AppModel {
var $name = 'Transaction';
/* var $validate = array( */
/* 'stamp' => array('date') */
/* ); */
var $belongsTo = array(
'Customer',
);
var $hasMany = array(
'LedgerEntry',
);
function beforeSave() {
if(!empty($this->data['Transaction']['stamp'])) {
$this->data['Transaction']['stamp'] =
$this->dateFormatBeforeSave($this->data['Transaction']['stamp']);
}
return true;
}
}
?>
-97
View File
@@ -1,97 +0,0 @@
<?php
class Unit extends AppModel {
var $name = 'Unit';
var $validate = array(
'id' => array('numeric'),
'unit_size_id' => array('numeric'),
'name' => array('notempty'),
'sort_order' => array('numeric'),
'walk_order' => array('numeric'),
'deposit' => array('money'),
'amount' => array('money')
);
var $belongsTo = array(
'UnitSize',
);
var $hasOne = array(
'CurrentLease' => array(
'className' => 'Lease',
'conditions' => 'CurrentLease.close_date IS NULL',
),
);
var $hasMany = array(
'Lease',
);
function statusEnums() {
static $status_enums;
if (!isset($status_enums))
$status_enums = $this->getEnumValues('status');
return $status_enums;
}
function statusValue($enum) {
$enums = $this->statusEnums();
return $enums[$enum];
}
function occupiedEnumValue() {
return statusValue('OCCUPIED');
}
function conditionOccupied() {
return ('Unit.status >= ' . $this->statusValue('OCCUPIED'));
}
function conditionVacant() {
return ('Unit.status BETWEEN ' .
($this->statusValue('UNAVAILABLE')+1) .
' AND ' .
($this->statusValue('OCCUPIED')-1));
}
function conditionUnavailable() {
return ('Unit.status <= ' . $this->statusValue('UNAVAILABLE'));
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: stats
* - Returns summary data from the requested customer.
*/
function stats($id = null) {
if (!$id)
return null;
// Get the basic information necessary
$unit = $this->find('first',
array('contain' => array
('Lease' => array
('fields' => array('Lease.id')),
'CurrentLease' => array
('fields' => array('CurrentLease.id'))),
'conditions' => array
(array('Unit.id' => $id)),
));
// Get the stats for the current lease
$stats['CurrentLease'] = $this->Lease->stats($unit['CurrentLease']['id']);
// Sum the stats for all leases together
foreach ($unit['Lease'] AS $lease) {
$this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id']));
}
// Return the collection
return $stats;
}
}
-25
View File
@@ -1,25 +0,0 @@
<?php
class UnitSize extends AppModel {
var $name = 'UnitSize';
var $validate = array(
'id' => array('numeric'),
'unit_type_id' => array('numeric'),
'code' => array('notempty'),
'name' => array('notempty'),
'width' => array('numeric'),
'depth' => array('numeric'),
'deposit' => array('money'),
'amount' => array('money')
);
var $belongsTo = array(
'UnitType',
);
var $hasMany = array(
'Unit',
);
}
?>
-16
View File
@@ -1,16 +0,0 @@
<?php
class UnitType extends AppModel {
var $name = 'UnitType';
var $validate = array(
'id' => array('numeric'),
'code' => array('notempty'),
'name' => array('notempty')
);
var $hasMany = array(
'UnitSize',
);
}
?>
-5
View File
@@ -1,5 +0,0 @@
To install copy the debug_kit directory to the plugins folder and include the toolbar component in your app_controller.php:
$components = array('DebugKit.Toolbar');
+ Set debug mode to at least 1.
@@ -1,471 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* DebugKit DebugToolbar Component
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class ToolbarComponent extends Object {
/**
* Controller instance reference
*
* @var object
*/
var $controller;
/**
* Components used by DebugToolbar
*
* @var array
*/
var $components = array('RequestHandler');
/**
* The default panels the toolbar uses.
* which panels are used can be configured when attaching the component
*
* @var array
*/
var $_defaultPanels = array('session', 'request', 'sqlLog', 'timer', 'log', 'memory', 'variables');
/**
* Loaded panel objects.
*
* @var array
*/
var $panels = array();
/**
* fallback for javascript settings
*
* @var array
**/
var $_defaultJavascript = array(
'behavior' => '/debug_kit/js/js_debug_toolbar'
);
/**
* javascript files component will be using.
*
* @var array
**/
var $javascript = array();
/**
* initialize
*
* If debug is off the component will be disabled and not do any further time tracking
* or load the toolbar helper.
*
* @return bool
**/
function initialize(&$controller, $settings) {
if (Configure::read('debug') == 0) {
$this->enabled = false;
return false;
}
App::import('Vendor', 'DebugKit.DebugKitDebugger');
DebugKitDebugger::startTimer('componentInit', __('Component initialization and startup', true));
if (!isset($settings['panels'])) {
$settings['panels'] = $this->_defaultPanels;
}
if (isset($settings['javascript'])) {
$settings['javascript'] = $this->_setJavascript($settings['javascript']);
} else {
$settings['javascript'] = $this->_defaultJavascript;
}
$this->_loadPanels($settings['panels']);
unset($settings['panels']);
$this->_set($settings);
$this->controller =& $controller;
return false;
}
/**
* Component Startup
*
* @return bool
**/
function startup(&$controller) {
$currentViewClass = $controller->view;
$this->_makeViewClass($currentViewClass);
$controller->view = 'DebugKit.Debug';
if (!isset($controller->params['url']['ext']) || (isset($controller->params['url']['ext']) && $controller->params['url']['ext'] == 'html')) {
$format = 'Html';
} else {
$format = 'FirePhp';
}
$controller->helpers['DebugKit.Toolbar'] = array('output' => sprintf('DebugKit.%sToolbar', $format));
$panels = array_keys($this->panels);
foreach ($panels as $panelName) {
$this->panels[$panelName]->startup($controller);
}
DebugKitDebugger::stopTimer('componentInit');
DebugKitDebugger::startTimer('controllerAction', __('Controller Action', true));
}
/**
* beforeRender callback
*
* Calls beforeRender on all the panels and set the aggregate to the controller.
*
* @return void
**/
function beforeRender(&$controller) {
DebugKitDebugger::stopTimer('controllerAction');
$vars = array();
$panels = array_keys($this->panels);
foreach ($panels as $panelName) {
$panel =& $this->panels[$panelName];
$vars[$panelName]['content'] = $panel->beforeRender($controller);
$elementName = Inflector::underscore($panelName) . '_panel';
if (isset($panel->elementName)) {
$elementName = $panel->elementName;
}
$vars[$panelName]['elementName'] = $elementName;
$vars[$panelName]['plugin'] = $panel->plugin;
$vars[$panelName]['disableTimer'] = true;
}
$controller->set(array('debugToolbarPanels' => $vars, 'debugToolbarJavascript' => $this->javascript));
DebugKitDebugger::startTimer('controllerRender', __('Render Controller Action', true));
}
/**
* Load Panels used in the debug toolbar
*
* @return void
* @access protected
**/
function _loadPanels($panels) {
foreach ($panels as $panel) {
$className = $panel . 'Panel';
if (!class_exists($className) && !App::import('Vendor', $className)) {
trigger_error(sprintf(__('Could not load DebugToolbar panel %s', true), $panel), E_USER_WARNING);
continue;
}
$panelObj =& new $className();
if (is_subclass_of($panelObj, 'DebugPanel') || is_subclass_of($panelObj, 'debugpanel')) {
$this->panels[$panel] =& $panelObj;
}
}
}
/**
* Set the javascript to user scripts.
*
* Set either script key to false to exclude it from the rendered layout.
*
* @param array $scripts Javascript config information
* @return array
* @access protected
**/
function _setJavascript($scripts) {
$behavior = false;
if (!is_array($scripts)) {
$scripts = (array)$scripts;
}
if (isset($scripts[0])) {
$behavior = $scripts[0];
}
if (isset($scripts['behavior'])) {
$behavior = $scripts['behavior'];
}
if (!$behavior) {
return array();
} elseif ($behavior === true) {
$behavior = 'js';
}
if (strpos($behavior, '/') !== 0) {
$behavior .= '_debug_toolbar';
}
$pluginFile = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . $behavior . '.js';
if (file_exists($pluginFile)) {
$behavior = '/debug_kit/js/' . $behavior . '.js';
}
return compact('behavior');
}
/**
* Makes the DoppleGangerView class if it doesn't already exist.
* This allows DebugView to be compatible with all view classes.
*
* @param string $baseClassName
* @access protected
* @return void
*/
function _makeViewClass($baseClassName) {
if (!class_exists('DoppelGangerView')) {
App::import('View', $baseClassName);
if (strpos('View', $baseClassName) === false) {
$baseClassName .= 'View';
}
$class = "class DoppelGangerView extends $baseClassName {}";
eval($class);
}
}
}
/**
* Debug Panel
*
* Abstract class for debug panels.
*
* @package cake.debug_kit
*/
class DebugPanel extends Object {
/**
* Defines which plugin this panel is from so the element can be located.
*
* @var string
*/
var $plugin = null;
/**
* startup the panel
*
* Pull information from the controller / request
*
* @param object $controller Controller reference.
* @return void
**/
function startup(&$controller) { }
/**
* Prepare output vars before Controller Rendering.
*
* @param object $controller Controller reference.
* @return void
**/
function beforeRender(&$controller) { }
}
/**
* Variables Panel
*
* Provides debug information on the View variables.
*
* @package cake.debug_kit.panels
**/
class VariablesPanel extends DebugPanel {
var $plugin = 'debug_kit';
}
/**
* Session Panel
*
* Provides debug information on the Session contents.
*
* @package cake.debug_kit.panels
**/
class SessionPanel extends DebugPanel {
var $plugin = 'debug_kit';
/**
* beforeRender callback
*
* @param object $controller
* @access public
* @return array
*/
function beforeRender(&$controller) {
return $controller->Session->read();
}
}
/**
* Request Panel
*
* Provides debug information on the Current request params.
*
* @package cake.debug_kit.panels
**/
class RequestPanel extends DebugPanel {
var $plugin = 'debug_kit';
/**
* beforeRender callback - grabs request params
*
* @return array
**/
function beforeRender(&$controller) {
$out = array();
$out['params'] = $controller->params;
if (isset($controller->Cookie)) {
$out['cookie'] = $controller->Cookie->read();
}
$out['get'] = $_GET;
$out['currentRoute'] = Router::currentRoute();
return $out;
}
}
/**
* Timer Panel
*
* Provides debug information on all timers used in a request.
*
* @package cake.debug_kit.panels
**/
class TimerPanel extends DebugPanel {
var $plugin = 'debug_kit';
/**
* startup - add in necessary helpers
*
* @return void
**/
function startup(&$controller) {
if (!in_array('Number', $controller->helpers)) {
$controller->helpers[] = 'Number';
}
}
}
/**
* Memory Panel
*
* Provides debug information on the memory consumption.
*
* @package cake.debug_kit.panels
**/
class MemoryPanel extends DebugPanel {
var $plugin = 'debug_kit';
/**
* startup - add in necessary helpers
*
* @return void
**/
function startup(&$controller) {
if (!in_array('Number', $controller->helpers)) {
$controller->helpers[] = 'Number';
}
}
}
/**
* sqlLog Panel
*
* Provides debug information on the SQL logs and provides links to an ajax explain interface.
*
* @package cake.debug_kit.panels
**/
class sqlLogPanel extends DebugPanel {
var $plugin = 'debug_kit';
var $dbConfigs = array();
/**
* get db configs.
*
* @param string $controller
* @access public
* @return void
*/
function startUp(&$controller) {
if (!class_exists('ConnectionManager')) {
$this->dbConfigs = array();
return false;
}
$this->dbConfigs = ConnectionManager::sourceList();
return true;
}
/**
* Get Sql Logs for each DB config
*
* @param string $controller
* @access public
* @return void
*/
function beforeRender(&$controller) {
$queryLogs = array();
if (!class_exists('ConnectionManager')) {
return array();
}
foreach ($this->dbConfigs as $configName) {
$db =& ConnectionManager::getDataSource($configName);
if ($db->isInterfaceSupported('showLog')) {
ob_start();
$db->showLog();
$queryLogs[$configName] = ob_get_clean();
}
}
return $queryLogs;
}
}
/**
* Log Panel - Reads log entries made this request.
*
* @package cake.debug_kit.panels
*/
class LogPanel extends DebugPanel {
var $plugin = 'debug_kit';
/**
* Log files to scan
*
* @var array
*/
var $logFiles = array('error.log', 'debug.log');
/**
* startup
*
* @return void
**/
function startup(&$controller) {
if (!class_exists('CakeLog')) {
App::import('Core', 'Log');
}
}
/**
* beforeRender Callback
*
* @return array
**/
function beforeRender(&$controller) {
$this->startTime = DebugKitDebugger::requestStartTime();
$this->currentTime = DebugKitDebugger::requestTime();
$out = array();
foreach ($this->logFiles as $log) {
$file = LOGS . $log;
if (!file_exists($file)) {
continue;
}
$out[$log] = $this->_parseFile($file);
}
return $out;
}
/**
* parse a log file and find the relevant entries
*
* @param string $filename Name of file to read
* @access protected
* @return array
*/
function _parseFile($filename) {
$file =& new File($filename);
$contents = $file->read();
$timePattern = '/(\d{4}-\d{2}\-\d{2}\s\d{1,2}\:\d{1,2}\:\d{1,2})/';
$chunks = preg_split($timePattern, $contents, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0, $len = count($chunks); $i < $len; $i += 2) {
if (strtotime($chunks[$i]) < $this->startTime) {
unset($chunks[$i], $chunks[$i + 1]);
}
}
return array_values($chunks);
}
}
?>
@@ -1,32 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Debug Kit App Controller
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class DebugKitAppController extends AppController {
}
?>
-32
View File
@@ -1,32 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Debug Kit App Model
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class DebugKitAppModel extends AppModel {
}
?>
View File
@@ -1,323 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* DebugToolbar Test
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Component', 'DebugKit.Toolbar');
class TestToolbarComponent extends ToolbarComponent {
function loadPanels($panels) {
$this->_loadPanels($panels);
}
}
Mock::generate('DebugPanel');
/**
* DebugToolbar Test case
*/
class DebugToolbarTestCase extends CakeTestCase {
function setUp() {
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::parse('/');
$this->Controller =& ClassRegistry::init('Controller');
$this->Controller->Component =& ClassRegistry::init('Component');
$this->Controller->Toolbar =& ClassRegistry::init('TestToolBarComponent', 'Component');
}
/**
* test Loading of panel classes
*
* @return void
**/
function testLoadPanels() {
$this->Controller->Toolbar->loadPanels(array('session', 'request'));
$this->assertTrue(is_a($this->Controller->Toolbar->panels['session'], 'SessionPanel'));
$this->assertTrue(is_a($this->Controller->Toolbar->panels['request'], 'RequestPanel'));
$this->expectError();
$this->Controller->Toolbar->loadPanels(array('randomNonExisting', 'request'));
}
/**
* test loading of vendor panels from test_app folder
*
* @access public
* @return void
*/
function testVendorPanels() {
$_back = Configure::read('vendorPaths');
Configure::write('vendorPaths', array(APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'test_app' . DS . 'vendors' . DS));
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'panels' => array('test'),
)
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->assertTrue(isset($this->Controller->Toolbar->panels['test']));
$this->assertTrue(is_a($this->Controller->Toolbar->panels['test'], 'TestPanel'));
Configure::write('vendorPaths', $_back);
}
/**
* test initialize
*
* @return void
* @access public
**/
function testInitialize() {
$this->Controller->components = array('DebugKit.Toolbar');
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->assertFalse(empty($this->Controller->Toolbar->panels));
$timers = DebugKitDebugger::getTimers();
$this->assertTrue(isset($timers['componentInit']));
}
/**
* test startup
*
* @return void
**/
function testStartup() {
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'panels' => array('MockDebug')
)
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('startup');
$this->Controller->Toolbar->startup($this->Controller);
$this->assertEqual(count($this->Controller->Toolbar->panels), 1);
$this->assertTrue(isset($this->Controller->helpers['DebugKit.Toolbar']));
$this->assertEqual($this->Controller->helpers['DebugKit.Toolbar'], array('output' => 'DebugKit.HtmlToolbar'));
$timers = DebugKitDebugger::getTimers();
$this->assertTrue(isset($timers['controllerAction']));
}
/**
* Test Before Render callback
*
* @return void
**/
function testBeforeRender() {
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'panels' => array('MockDebug', 'session')
)
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('beforeRender');
$this->Controller->Toolbar->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarPanels']));
$vars = $this->Controller->viewVars['debugToolbarPanels'];
$expected = array(
'plugin' => 'debug_kit',
'elementName' => 'session_panel',
'content' => $this->Controller->Session->read(),
'disableTimer' => true,
);
$this->assertEqual($expected, $vars['session']);
}
/**
* test alternate javascript library use
*
* @return void
**/
function testAlternateJavascript() {
$this->Controller->components = array(
'DebugKit.Toolbar'
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => '/debug_kit/js/js_debug_toolbar',
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => 'jquery',
),
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => '/debug_kit/js/jquery_debug_toolbar.js',
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => false
)
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array();
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => array('my_library'),
),
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => 'my_library_debug_toolbar'
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => array('/my/path/to/file')
),
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => '/my/path/to/file',
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => '/js/custom_behavior',
),
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => '/js/custom_behavior',
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
}
/**
* Test alternate javascript existing in the plugin.
*
* @return void
**/
function testExistingAlterateJavascript() {
$filename = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . 'test_alternate_debug_toolbar.js';
$this->skipIf(!is_writable(dirname($filename)), 'Skipping existing javascript test, debug_kit/vendors/js must be writable');
@touch($filename);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'javascript' => 'test_alternate',
),
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
$expected = array(
'behavior' => '/debug_kit/js/test_alternate_debug_toolbar.js',
);
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
@unlink($filename);
}
/**
* test the Log panel log reading.
*
* @return void
**/
function testLogPanel() {
usleep(20);
$this->Controller->log('This is a log I made this request');
$this->Controller->log('This is the second log I made this request');
$this->Controller->log('This time in the debug log!', LOG_DEBUG);
$this->Controller->components = array(
'DebugKit.Toolbar' => array(
'panels' => array('log', 'session')
)
);
$this->Controller->Component->init($this->Controller);
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$result = $this->Controller->viewVars['debugToolbarPanels']['log'];
$this->assertEqual(count($result['content']), 2);
$this->assertEqual(count($result['content']['error.log']), 4);
$this->assertEqual(count($result['content']['debug.log']), 2);
$this->assertEqual(trim($result['content']['debug.log'][1]), 'Debug: This time in the debug log!');
$this->assertEqual(trim($result['content']['error.log'][1]), 'Error: This is a log I made this request');
}
/**
* teardown
*
* @return void
**/
function tearDown() {
unset($this->Controller);
if (class_exists('DebugKitDebugger')) {
DebugKitDebugger::clearTimers();
}
}
}
?>
View File
@@ -1,62 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Common test objects used in DebugKit tests
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake.tests
* @subpackage cake.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.5432
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
/**
* TestFireCake class allows for testing of FireCake
*
* @package debug_kit.tests.
*/
class TestFireCake extends FireCake {
var $sentHeaders = array();
function _sendHeader($name, $value) {
$_this = FireCake::getInstance();
$_this->sentHeaders[$name] = $value;
}
/**
* skip client detection as headers are not being sent.
*
* @access public
* @return void
*/
function detectClientExtension() {
return true;
}
/**
* Reset the fireCake
*
* @return void
**/
function reset() {
$_this = FireCake::getInstance();
$_this->sentHeaders = array();
$_this->_messageIndex = 1;
}
}
?>
@@ -1,157 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* DebugKit Debugger Test Case File
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake.tests
* @subpackage cake.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.5432
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
App::import('Core', 'Debugger');
App::import('Vendor', 'DebugKit.DebugKitDebugger');
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
/**
* Short description for class.
*
* @package cake.tests
* @subpackage cake.tests.cases.libs
*/
class DebugKitDebuggerTest extends CakeTestCase {
/**
* setUp method
*
* @access public
* @return void
*/
function setUp() {
Configure::write('log', false);
if (!defined('SIMPLETESTVENDORPATH')) {
if (file_exists(APP . DS . 'vendors' . DS . 'simpletest' . DS . 'reporter.php')) {
define('SIMPLETESTVENDORPATH', 'APP' . DS . 'vendors');
} else {
define('SIMPLETESTVENDORPATH', 'CORE' . DS . 'vendors');
}
}
}
/**
* Start Timer test
*
* @return void
**/
function testTimers() {
$this->assertTrue(DebugKitDebugger::startTimer('test1', 'this is my first test'));
usleep(5000);
$this->assertTrue(DebugKitDebugger::stopTimer('test1'));
$elapsed = DebugKitDebugger::elapsedTime('test1');
$this->assertTrue($elapsed > 0.0050);
$this->assertTrue(DebugKitDebugger::startTimer('test2', 'this is my second test'));
sleep(1);
$this->assertTrue(DebugKitDebugger::stopTimer('test2'));
$elapsed = DebugKitDebugger::elapsedTime('test2');
$this->assertTrue($elapsed > 1);
DebugKitDebugger::startTimer('test3');
$this->assertFalse(DebugKitDebugger::elapsedTime('test3'));
$this->assertFalse(DebugKitDebugger::stopTimer('wrong'));
}
/**
* testRequestTime
*
* @access public
* @return void
*/
function testRequestTime() {
$result1 = DebugKitDebugger::requestTime();
usleep(50);
$result2 = DebugKitDebugger::requestTime();
$this->assertTrue($result1 < $result2);
}
/**
* test getting all the set timers.
*
* @return void
**/
function testGetTimers() {
DebugKitDebugger::clearTimers();
DebugKitDebugger::startTimer('test1', 'this is my first test');
DebugKitDebugger::stopTimer('test1');
usleep(50);
DebugKitDebugger::startTimer('test2');
DebugKitDebugger::stopTimer('test2');
$timers = DebugKitDebugger::getTimers();
$this->assertEqual(count($timers), 2);
$this->assertTrue(is_float($timers['test1']['time']));
$this->assertTrue(isset($timers['test1']['message']));
$this->assertTrue(isset($timers['test2']['message']));
}
/**
* test memory usage
*
* @return void
**/
function testMemoryUsage() {
$result = DebugKitDebugger::getMemoryUse();
$this->assertTrue(is_int($result));
$result = DebugKitDebugger::getPeakMemoryUse();
$this->assertTrue(is_int($result));
}
/**
* test _output switch to firePHP
*
* @return void
*/
function testOutput() {
$firecake =& FireCake::getInstance('TestFireCake');
Debugger::invoke(DebugKitDebugger::getInstance('DebugKitDebugger'));
Debugger::output('fb');
$foo .= '';
$result = $firecake->sentHeaders;
$this->assertPattern('/GROUP_START/', $result['X-Wf-1-1-1-1']);
$this->assertPattern('/ERROR/', $result['X-Wf-1-1-1-2']);
$this->assertPattern('/GROUP_END/', $result['X-Wf-1-1-1-5']);
Debugger::invoke(Debugger::getInstance('Debugger'));
Debugger::output();
}
/**
* tearDown method
*
* @access public
* @return void
*/
function tearDown() {
Configure::write('log', true);
}
}
?>
-336
View File
@@ -1,336 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* CakeFirePHP test case
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package debug_kit
* @subpackage cake.debug_kit.tests
* @since CakePHP v 1.2.0.4487
* @version
* @modifiedby
* @lastmodified
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Vendor', 'DebugKit.FireCake');
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
/**
* Test Case For FireCake
*
* @package debug_kit.tests
*/
class FireCakeTestCase extends CakeTestCase {
/**
* setup test
*
* Fill FireCake with TestFireCake instance.
*
* @access public
* @return void
*/
function setUp() {
$this->firecake =& FireCake::getInstance('TestFireCake');
}
/**
* test getInstance cheat.
*
* If this fails the rest of the test is going to fail too.
*
* @return void
**/
function testGetInstanceOverride() {
$instance =& FireCake::getInstance();
$instance2 =& FireCake::getInstance();
$this->assertReference($instance, $instance2);
$this->assertIsA($instance, 'FireCake');
$this->assertIsA($instance, 'TestFireCake', 'Stored instance is not a copy of TestFireCake, test case is broken.');
}
/**
* testsetoption
*
* @return void
**/
function testSetOptions() {
FireCake::setOptions(array('includeLineNumbers' => false));
$this->assertEqual($this->firecake->options['includeLineNumbers'], false);
}
/**
* test Log()
*
* @access public
* @return void
*/
function testLog() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::log('Testing');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '26|[{"Type":"LOG"},"Testing"]|');
FireCake::log('Testing', 'log-info');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"LOG","Label":"log-info"},"Testing"]|');
}
/**
* test info()
*
* @access public
* @return void
*/
function testInfo() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::info('I have information');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '38|[{"Type":"INFO"},"I have information"]|');
FireCake::info('I have information', 'info-label');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '59|[{"Type":"INFO","Label":"info-label"},"I have information"]|');
}
/**
* test info()
*
* @access public
* @return void
*/
function testWarn() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::warn('A Warning');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"WARN"},"A Warning"]|');
FireCake::warn('A Warning', 'Bzzz');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '44|[{"Type":"WARN","Label":"Bzzz"},"A Warning"]|');
}
/**
* test error()
*
* @access public
* @return void
**/
function testError() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::error('An error');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"ERROR"},"An error"]|');
FireCake::error('An error', 'wonky');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"ERROR","Label":"wonky"},"An error"]|');
}
/**
* test dump()
*
* @return void
**/
function testDump() {
FireCake::dump('mydump', array('one' => 1, 'two' => 2));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-2-1-1'], '28|{"mydump":{"one":1,"two":2}}|');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-2']));
}
/**
* test table() generation
*
* @return void
**/
function testTable() {
$table[] = array('Col 1 Heading','Col 2 Heading');
$table[] = array('Row 1 Col 1','Row 1 Col 2');
$table[] = array('Row 2 Col 1','Row 2 Col 2');
$table[] = array('Row 3 Col 1','Row 3 Col 2');
FireCake::table('myTrace', $table);
$expected = '162|[{"Type":"TABLE","Label":"myTrace"},[["Col 1 Heading","Col 2 Heading"],["Row 1 Col 1","Row 1 Col 2"],["Row 2 Col 1","Row 2 Col 2"],["Row 3 Col 1","Row 3 Col 2"]]]|';
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], $expected);
}
/**
* testStringEncoding
*
* @return void
**/
function testStringEncode() {
$result = $this->firecake->stringEncode(array(1,2,3));
$this->assertEqual($result, array(1,2,3));
$this->firecake->setOptions(array('maxArrayDepth' => 3));
$deep = array(1 => array(2 => array(3)));
$result = $this->firecake->stringEncode($deep);
$this->assertEqual($result, array(1 => array(2 => '** Max Array Depth (3) **')));
$obj =& FireCake::getInstance();
$result = $this->firecake->stringEncode($obj);
$this->assertTrue(is_array($result));
$this->assertEqual($result['_defaultOptions']['useNativeJsonEncode'], true);
$this->assertEqual($result['_log'], null);
$this->assertEqual($result['_encodedObjects'][0], '** Recursion (TestFireCake) **');
}
/**
* test trace()
*
* @return void
**/
function testTrace() {
FireCake::trace('myTrace');
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
$dump = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
$this->assertPattern('/"Message":"myTrace"/', $dump);
$this->assertPattern('/"Trace":\[/', $dump);
}
/**
* test enabling and disabling of FireCake output
*
* @return void
**/
function testEnableDisable() {
FireCake::disable();
FireCake::trace('myTrace');
$this->assertTrue(empty($this->firecake->sentHeaders));
FireCake::enable();
FireCake::trace('myTrace');
$this->assertFalse(empty($this->firecake->sentHeaders));
}
/**
* test correct line continuation markers on multi line headers.
*
* @access public
* @return void
*/
function testMultiLineOutput() {
FireCake::trace('myTrace');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
$this->assertEqual(substr($header, -2), '|\\');
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-2'];
$this->assertEqual(substr($header, -2), '|\\');
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-3'];
$this->assertEqual(substr($header, -1), '|');
}
/**
* test inclusion of line numbers
*
* @return void
**/
function testIncludeLineNumbers() {
FireCake::setOptions(array('includeLineNumbers' => true));
FireCake::info('Testing');
$result = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
$this->assertPattern('/"File"\:"APP.*fire_cake.test.php/', $result);
$this->assertPattern('/"Line"\:\d+/', $result);
}
/**
* test Group messages
*
* @return void
**/
function testGroup() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::group('test');
FireCake::info('my info');
FireCake::groupEnd();
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '44|[{"Type":"GROUP_START","Label":"test"},null]|');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '27|[{"Type":"GROUP_END"},null]|');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
}
/**
* test fb() parameter parsing
*
* @return void
**/
function testFbParameterParsing() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::fb('Test');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '23|[{"Type":"LOG"},"Test"]|');
FireCake::fb('Test', 'warn');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '24|[{"Type":"WARN"},"Test"]|');
FireCake::fb('Test', 'Custom label', 'warn');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '47|[{"Type":"WARN","Label":"Custom label"},"Test"]|');
$this->expectError();
$this->assertFalse(FireCake::fb('Test', 'Custom label', 'warn', 'more parameters'));
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
}
/**
* Test defaulting to log if incorrect message type is used
*
* @return void
**/
function testIncorrectMessageType() {
FireCake::setOptions(array('includeLineNumbers' => false));
FireCake::fb('Hello World', 'foobared');
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '30|[{"Type":"LOG"},"Hello World"]|');
}
/**
* testClientExtensionDetection.
*
* @return void
**/
function testDetectClientExtension() {
$back = env('HTTP_USER_AGENT');
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.2.1';
$this->assertTrue(FireCake::detectClientExtension());
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.0.4';
$this->assertFalse(FireCake::detectClientExtension());
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4';
$this->assertFalse(FireCake::detectClientExtension());
$_SERVER['HTTP_USER_AGENT'] = $back;
}
/**
* test of Non Native JSON encoding.
*
* @return void
**/
function testNonNativeEncoding() {
FireCake::setOptions(array('useNativeJsonEncode' => false));
$json = FireCake::jsonEncode(array('one' => 1, 'two' => 2));
$this->assertEqual($json, '{"one":1,"two":2}');
$json = FireCake::jsonEncode(array(1,2,3));
$this->assertEqual($json, '[1,2,3]');
$json = FireCake::jsonEncode(FireCake::getInstance());
$this->assertPattern('/"options"\:\{"maxObjectDepth"\:\d*,/', $json);
}
/**
* reset the FireCake counters and headers.
*
* @access public
* @return void
*/
function tearDown() {
TestFireCake::reset();
}
}
?>
@@ -1,144 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* DebugView test Case
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Core', 'View');
if (!class_exists('DoppelGangerView')) {
class DoppelGangerView extends View {}
}
App::import('View', 'DebugKit.Debug');
App::import('Vendor', 'DebugKit.DebugKitDebugger');
/**
* Debug View Test Case
*
* @package debug_kit.tests
*/
class DebugViewTestCase extends CakeTestCase {
/**
* set Up test case
*
* @return void
**/
function setUp() {
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::parse('/');
$this->Controller =& ClassRegistry::init('Controller');
$this->View =& new DebugView($this->Controller, false);
$this->_debug = Configure::read('debug');
}
/**
* start Case - switch view paths
*
* @return void
**/
function startCase() {
$this->_viewPaths = Configure::read('viewPaths');
Configure::write('viewPaths', array(
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
ROOT . DS . LIBS . 'view' . DS
));
}
/**
* test that element timers are working
*
* @return void
**/
function testElementTimers() {
$result = $this->View->element('test_element');
$this->assertPattern('/^this is the test element$/', $result);
$result = DebugKitDebugger::getTimers();
$this->assertTrue(isset($result['render_test_element.ctp']));
}
/**
* test rendering and ensure that timers are being set.
*
* @access public
* @return void
*/
function testRenderTimers() {
$this->Controller->viewPath = 'posts';
$this->Controller->action = 'index';
$this->Controller->params = array(
'action' => 'index',
'controller' => 'posts',
'plugin' => null,
'url' => array('url' => 'posts/index'),
'base' => null,
'here' => '/posts/index',
);
$this->Controller->layout = 'default';
$View =& new DebugView($this->Controller, false);
$View->render('index');
$result = DebugKitDebugger::getTimers();
$this->assertEqual(count($result), 3);
$this->assertTrue(isset($result['viewRender']));
$this->assertTrue(isset($result['render_default.ctp']));
$this->assertTrue(isset($result['render_index.ctp']));
}
/**
* Test for correct loading of helpers into custom view
*
* @return void
*/
function testLoadHelpers() {
$loaded = array();
$result = $this->View->_loadHelpers($loaded, array('Html', 'Javascript', 'Number'));
$this->assertTrue(is_object($result['Html']));
$this->assertTrue(is_object($result['Javascript']));
$this->assertTrue(is_object($result['Number']));
}
/**
* reset the view paths
*
* @return void
**/
function endCase() {
Configure::write('viewPaths', $this->_viewPaths);
}
/**
* tear down function
*
* @return void
**/
function tearDown() {
unset($this->View, $this->Controller);
DebugKitDebugger::clearTimers();
Configure::write('debug', $this->_debug);
}
}
?>
@@ -1,137 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Toolbar Abstract Helper Test Case
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage debug_kit.tests.views.helpers
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', 'DebugKit.FirePhpToolbar');
App::import('Core', array('View', 'Controller'));
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
FireCake::getInstance('TestFireCake');
class FirePhpToolbarHelperTestCase extends CakeTestCase {
/**
* setUp
*
* @return void
**/
function setUp() {
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::parse('/');
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.FirePhpToolbar'));
$this->Toolbar->FirePhpToolbar =& new FirePhpToolbarHelper();
$this->Controller =& ClassRegistry::init('Controller');
if (isset($this->_debug)) {
Configure::write('debug', $this->_debug);
}
}
/**
* start Case - switch view paths
*
* @return void
**/
function startCase() {
$this->_viewPaths = Configure::read('viewPaths');
Configure::write('viewPaths', array(
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
ROOT . DS . LIBS . 'view' . DS
));
$this->_debug = Configure::read('debug');
$this->firecake =& FireCake::getInstance();
}
/**
* test neat array (dump)creation
*
* @return void
*/
function testMakeNeatArray() {
$this->Toolbar->makeNeatArray(array(1,2,3));
$result = $this->firecake->sentHeaders;
$this->assertTrue(isset($result['X-Wf-1-1-1-1']));
$this->assertPattern('/\[1,2,3\]/', $result['X-Wf-1-1-1-1']);
}
/**
* testAfterlayout element rendering
*
* @return void
*/
function testAfterLayout(){
$this->Controller->viewPath = 'posts';
$this->Controller->action = 'index';
$this->Controller->params = array(
'action' => 'index',
'controller' => 'posts',
'plugin' => null,
'url' => array('url' => 'posts/index', 'ext' => 'xml'),
'base' => null,
'here' => '/posts/index',
);
$this->Controller->layout = 'default';
$this->Controller->uses = null;
$this->Controller->components = array('DebugKit.Toolbar');
$this->Controller->constructClasses();
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$result = $this->Controller->render();
$this->assertNoPattern('/debug-toolbar/', $result);
$result = $this->firecake->sentHeaders;
$this->assertTrue(is_array($result));
}
/**
* endTest()
*
* @return void
*/
function endTest() {
TestFireCake::reset();
}
/**
* reset the view paths
*
* @return void
**/
function endCase() {
Configure::write('viewPaths', $this->_viewPaths);
}
/**
* tearDown
*
* @access public
* @return void
*/
function tearDown() {
unset($this->Toolbar, $this->Controller);
ClassRegistry::removeObject('view');
ClassRegistry::flush();
Router::reload();
}
}
?>
@@ -1,358 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Toolbar HTML Helper Test Case
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage debug_kit.tests.views.helpers
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', array('DebugKit.HtmlToolbar', 'Html', 'Javascript'));
App::import('Core', array('View', 'Controller'));
class HtmlToolbarHelperTestCase extends CakeTestCase {
/**
* setUp
*
* @return void
**/
function setUp() {
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::parse('/');
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.HtmlToolbar'));
$this->Toolbar->HtmlToolbar =& new HtmlToolbarHelper();
$this->Toolbar->HtmlToolbar->Html =& new HtmlHelper();
$this->Toolbar->HtmlToolbar->Javascript =& new JavascriptHelper();
$this->Controller =& ClassRegistry::init('Controller');
if (isset($this->_debug)) {
Configure::write('debug', $this->_debug);
}
}
/**
* start Case - switch view paths
*
* @return void
**/
function startCase() {
$this->_viewPaths = Configure::read('viewPaths');
Configure::write('viewPaths', array(
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
ROOT . DS . LIBS . 'view' . DS
));
$this->_debug = Configure::read('debug');
}
/**
* test Neat Array formatting
*
* @return void
**/
function testMakeNeatArray() {
$in = false;
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', '0' , '/strong', '(false)', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = null;
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', '0' , '/strong', '(null)', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = true;
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', '0' , '/strong', '(true)', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array('key' => 'value');
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array('key' => null);
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', 'key', '/strong', '(null)', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array('key' => 'value', 'foo' => 'bar');
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'<li', '<strong', 'foo', '/strong', 'bar', '/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array(
'key' => 'value',
'foo' => array(
'this' => 'deep',
'another' => 'value'
)
);
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'<li', '<strong', 'foo', '/strong',
array('ul' => array('class' => 'neat-array depth-1')),
'<li', '<strong', 'this', '/strong', 'deep', '/li',
'<li', '<strong', 'another', '/strong', 'value', '/li',
'/ul',
'/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array(
'key' => 'value',
'foo' => array(
'this' => 'deep',
'another' => 'value'
),
'lotr' => array(
'gandalf' => 'wizard',
'bilbo' => 'hobbit'
)
);
$result = $this->Toolbar->makeNeatArray($in, 1);
$expected = array(
'ul' => array('class' => 'neat-array depth-0 expanded'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'<li', '<strong', 'foo', '/strong',
array('ul' => array('class' => 'neat-array depth-1')),
'<li', '<strong', 'this', '/strong', 'deep', '/li',
'<li', '<strong', 'another', '/strong', 'value', '/li',
'/ul',
'/li',
'<li', '<strong', 'lotr', '/strong',
array('ul' => array('class' => 'neat-array depth-1')),
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
'/ul',
'/li',
'/ul'
);
$this->assertTags($result, $expected);
$result = $this->Toolbar->makeNeatArray($in, 2);
$expected = array(
'ul' => array('class' => 'neat-array depth-0 expanded'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'<li', '<strong', 'foo', '/strong',
array('ul' => array('class' => 'neat-array depth-1 expanded')),
'<li', '<strong', 'this', '/strong', 'deep', '/li',
'<li', '<strong', 'another', '/strong', 'value', '/li',
'/ul',
'/li',
'<li', '<strong', 'lotr', '/strong',
array('ul' => array('class' => 'neat-array depth-1 expanded')),
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
'/ul',
'/li',
'/ul'
);
$this->assertTags($result, $expected);
$in = array('key' => 'value', 'array' => array());
$result = $this->Toolbar->makeNeatArray($in);
$expected = array(
'ul' => array('class' => 'neat-array depth-0'),
'<li', '<strong', 'key', '/strong', 'value', '/li',
'<li', '<strong', 'array', '/strong', '(empty)', '/li',
'/ul'
);
$this->assertTags($result, $expected);
}
/**
* Test injection of toolbar
*
* @return void
**/
function testInjectToolbar() {
$this->Controller->viewPath = 'posts';
$this->Controller->action = 'index';
$this->Controller->params = array(
'action' => 'index',
'controller' => 'posts',
'plugin' => null,
'url' => array('url' => 'posts/index'),
'base' => null,
'here' => '/posts/index',
);
$this->Controller->helpers = array('Html', 'Javascript', 'DebugKit.Toolbar');
$this->Controller->layout = 'default';
$this->Controller->uses = null;
$this->Controller->components = array('DebugKit.Toolbar');
$this->Controller->constructClasses();
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$result = $this->Controller->render();
$result = str_replace(array("\n", "\r"), '', $result);
$this->assertPattern('#<div id\="debug-kit-toolbar">.+</div></body>#', $result);
}
/**
* test injection of javascript
*
* @return void
**/
function testJavascriptInjection() {
$this->Controller->viewPath = 'posts';
$this->Controller->uses = null;
$this->Controller->action = 'index';
$this->Controller->params = array(
'action' => 'index',
'controller' => 'posts',
'plugin' => null,
'url' => array('url' => 'posts/index'),
'base' => '/',
'here' => '/posts/index',
);
$this->Controller->helpers = array('Javascript', 'Html');
$this->Controller->components = array('DebugKit.Toolbar');
$this->Controller->layout = 'default';
$this->Controller->constructClasses();
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$result = $this->Controller->render();
$result = str_replace(array("\n", "\r"), '', $result);
$this->assertPattern('#<script\s*type="text/javascript"\s*src="/debug_kit/js/js_debug_toolbar.js"\s*>\s?</script>#', $result);
}
/**
* test Injection of user defined javascript
*
* @return void
**/
function testCustomJavascriptInjection() {
$this->Controller->viewPath = 'posts';
$this->Controller->uses = null;
$this->Controller->action = 'index';
$this->Controller->params = array(
'action' => 'index',
'controller' => 'posts',
'plugin' => null,
'url' => array('url' => 'posts/index'),
'base' => '/',
'here' => '/posts/index',
);
$this->Controller->helpers = array('Javascript', 'Html');
$this->Controller->components = array('DebugKit.Toolbar' => array('javascript' => array('my_custom')));
$this->Controller->layout = 'default';
$this->Controller->constructClasses();
$this->Controller->Component->initialize($this->Controller);
$this->Controller->Component->startup($this->Controller);
$this->Controller->Component->beforeRender($this->Controller);
$result = $this->Controller->render();
$result = str_replace(array("\n", "\r"), '', $result);
$this->assertPattern('#<script\s*type="text/javascript"\s*src="js/my_custom_debug_toolbar.js"\s*>\s?</script>#', $result);
}
/**
* test message creation
*
* @return void
*/
function testMessage() {
$result = $this->Toolbar->message('test', 'one, two');
$expected = array(
'<p',
'<strong', 'test', '/strong',
' one, two',
'/p',
);
$this->assertTags($result, $expected);
}
/**
* Test Table generation
*
* @return void
*/
function testTable() {
$rows = array(
array(1,2),
array(3,4),
);
$result = $this->Toolbar->table($rows);
$expected = array(
'table' => array('class' =>'debug-table'),
array('tr' => array('class' => 'odd')),
'<td', '1', '/td',
'<td', '2', '/td',
'/tr',
array('tr' => array('class' => 'even')),
'<td', '3', '/td',
'<td', '4', '/td',
'/tr',
'/table'
);
$this->assertTags($result, $expected);
}
/**
* reset the view paths
*
* @return void
**/
function endCase() {
Configure::write('viewPaths', $this->_viewPaths);
}
/**
* tearDown
*
* @access public
* @return void
*/
function tearDown() {
unset($this->Toolbar, $this->Controller);
ClassRegistry::removeObject('view');
ClassRegistry::flush();
}
}
?>
View File
-33
View File
@@ -1,33 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Test Panel
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake.debug_kit
* @subpackage cake.debug_kit.tests
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class TestPanel extends DebugPanel {
function startup(&$controller) {
$controller->testPanel = true;
}
}
?>
-165
View File
@@ -1,165 +0,0 @@
/* @override http://localhost/cake_debug_kit/debug_kit/css/debug_toolbar.css */
#debug-kit-toolbar {
position: fixed;
top: 0px;
right:0px;
width: 100%;
height: 1%;
overflow: visible;
z-index:10000;
}
/* panel tabs */
#debug-kit-toolbar #panel-tabs {
float: right;
list-style: none;
margin: 0;
}
#debug-kit-toolbar .panel-tab {
clear: none;
float: left;
margin: 0;
padding: 0;
list-style: none;
}
#debug-kit-toolbar .panel-tab a {
float: left;
clear: none;
background: #efefef;
color: #222;
padding: 6px;
border-right: 1px solid #ccc;
font-size: 12px;
line-height: 16px;
margin: 0;
display: block;
}
#debug-kit-toolbar .panel-tab .active,
#debug-kit-toolbar .panel-tab a:hover {
background: #fff;
}
#debug-kit-toolbar .panel-tab.icon a {
padding: 4px;
}
/* Hovering over link shows tab, useful for no js */
#debug-kit-toolbar .panel-tab a:hover + .panel-content,
#debug-kit-toolbar .panel-tab a + .panel-content:hover {
display: block;
}
/* panel content */
#debug-kit-toolbar .panel-content {
position: absolute;
text-align: left;
width: auto;
top:28px;
right:0px;
background: #fff;
color: #000;
width:96%;
padding:20px 2%;
max-height: 550px;
overflow:auto;
border-bottom: 3px solid #333;
}
/* Hide panel content by default */
.panel-content {
display: none;
}
.panel-content p {
margin: 1em 0;
}
.panel-content h2 {
padding: 0;
margin-top:0;
}
.panel-content h3 {
padding: 0;
margin-top: 1em;
}
.panel-content .info {
padding: 4px;
border-top: 1px dashed #6c6cff;
border-bottom: 1px dashed #6c6cff;
}
/* panel tables */
table.debug-table {
width: auto;
border: 0;
}
table.debug-table td,
table.debug-table th {
text-align: left;
border: 0;
padding: 3px;
}
table.debug-table th {
border-bottom: 1px solid #222;
background: 0;;
}
table.debug-table tr.even td {
background:#efefef;
}
/** code tables **/
#debug-kit-toolbar .code-table td {
white-space: pre;
font-family: monaco, corsiva, "courier new", courier, monospaced;
}
#debug-kit-toolbar .code-table td:first-child {
width: 15%;
}
#debug-kit-toolbar .code-table td:last-child {
width: 80%;
}
.panel-content.request {
display: block;
}
/** Neat Array styles **/
.neat-array {
padding: 1px 2px 1px 20px;
background: #CE9E23;
list-style: none;
margin: 0;
}
.neat-array .neat-array {
padding: 0 0 0 20px;
}
.neat-array li {
background: #FEF6E5;
border-top: 1px solid #CE9E23;
border-bottom: 1px solid #CE9E23;
margin: 0;
line-height: 1.5em;
}
.neat-array li:hover {
background: #fff;
}
.neat-array li strong {
padding: 0 8px;
}
/* expandable sections */
.neat-array li.expandable {
cursor: pointer;
}
.neat-array li.expandable.expanded > strong:before {
content: 'v ';
}
.neat-array li.expandable.collapsed > strong:before,
.neat-array li.expandable.expanded .expandable.collapsed > strong:before {
content: '> ';
}
.neat-array li {
cursor: default;
}
-226
View File
@@ -1,226 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* DebugKit Debugger class. Extends and enhances core
* debugger. Adds benchmarking and timing functionality.
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Core', 'Debugger');
App::import('Vendor', 'DebugKit.FireCake');
/**
* Debug Kit Temporary Debugger Class
*
* Provides the future features that are planned. Yet not implemented in the 1.2 code base
*
* This file will not be needed in future version of CakePHP.
* @todo merge these changes with core Debugger
*/
class DebugKitDebugger extends Debugger {
/**
* Start an benchmarking timer.
*
* @param string $name The name of the timer to start.
* @param string $message A message for your timer
* @return bool true
* @static
**/
function startTimer($name = 'default', $message = '') {
$now = getMicrotime();
$_this = DebugKitDebugger::getInstance();
$_this->__benchmarks[$name] = array(
'start' => $now,
'message' => $message,
);
return true;
}
/**
* Stop a benchmarking timer.
*
* $name should be the same as the $name used in startTimer().
*
* @param string $name The name of the timer to end.
* @access public
* @return boolean true if timer was ended, false if timer was not started.
* @static
*/
function stopTimer($name = 'default') {
$now = getMicrotime();
$_this = DebugKitDebugger::getInstance();
if (!isset($_this->__benchmarks[$name])) {
return false;
}
$_this->__benchmarks[$name]['end'] = $now;
return true;
}
/**
* Get all timers that have been started and stopped.
* Calculates elapsed time for each timer.
*
* @return array
**/
function getTimers() {
$_this =& DebugKitDebugger::getInstance();
$times = array();
foreach ($_this->__benchmarks as $name => $timer) {
$times[$name]['time'] = DebugKitDebugger::elapsedTime($name);
$times[$name]['message'] = $timer['message'];
}
return $times;
}
/**
* Clear all existing timers
*
* @return bool true
**/
function clearTimers() {
$_this =& DebugKitDebugger::getInstance();
$_this->__benchmarks = array();
return true;
}
/**
* Get the difference in time between the timer start and timer end.
*
* @param $name string the name of the timer you want elapsed time for.
* @param $precision int the number of decimal places to return, defaults to 5.
* @return float number of seconds elapsed for timer name, 0 on missing key
* @static
**/
function elapsedTime($name = 'default', $precision = 5) {
$_this =& DebugKitDebugger::getInstance();
if (!isset($_this->__benchmarks[$name]['start']) || !isset($_this->__benchmarks[$name]['end'])) {
return 0;
}
return round($_this->__benchmarks[$name]['end'] - $_this->__benchmarks[$name]['start'], $precision);
}
/**
* Get the total execution time until this point
*
* @access public
* @return float elapsed time in seconds since script start.
* @static
*/
function requestTime() {
$start = DebugKitDebugger::requestStartTime();
$now = getMicroTime();
return ($now - $start);
}
/**
* get the time the current request started.
*
* @access public
* @return float time of request start
* @static
*/
function requestStartTime() {
if (defined('TIME_START')) {
$startTime = TIME_START;
} else if (isset($_GLOBALS['TIME_START'])) {
$startTime = $_GLOBALS['TIME_START'];
} else {
$startTime = env('REQUEST_TIME');
}
return $startTime;
}
/**
* get current memory usage
*
* @return integer number of bytes ram currently in use. 0 if memory_get_usage() is not available.
* @static
**/
function getMemoryUse() {
if (!function_exists('memory_get_usage')) {
return 0;
}
return memory_get_usage();
}
/**
* Get peak memory use
*
* @return integer peak memory use (in bytes). Returns 0 if memory_get_peak_usage() is not available
* @static
**/
function getPeakMemoryUse() {
if (!function_exists('memory_get_peak_usage')) {
return 0;
}
return memory_get_peak_usage();
}
/**
* Handles object conversion to debug string.
*
* @param string $var Object to convert
* @access protected
*/
function _output($level, $error, $code, $helpCode, $description, $file, $line, $kontext) {
$files = $this->trace(array('start' => 2, 'format' => 'points'));
$listing = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
$trace = $this->trace(array('start' => 2, 'depth' => '20'));
$context = array();
foreach ((array)$kontext as $var => $value) {
$context[] = "\${$var}\t=\t" . $this->exportVar($value, 1);
}
if ($this->_outputFormat == 'fb') {
$this->_fireError($error, $code, $description, $file, $line, $trace, $context);
} else {
echo parent::_output($level, $error, $code, $helpCode, $description, $file, $line, $kontext);
}
}
/**
* Create a FirePHP error message
*
* @param string $error Name of error
* @param string $code Code of error
* @param string $description Description of error
* @param string $file File error occured in
* @param string $line Line error occured on
* @param string $trace Stack trace at time of error
* @param string $context context of error
* @return void
* @access protected
*/
function _fireError($error, $code, $description, $file, $line, $trace, $context) {
$name = $error . ' - ' . $description;
$message = "$error $code $description on line: $line in file: $file";
FireCake::group($name);
FireCake::error($message, $name);
FireCake::log($context, 'Context');
FireCake::log($trace, 'Trace');
FireCake::groupEnd();
}
}
Debugger::invoke(DebugKitDebugger::getInstance());
Debugger::getInstance('DebugKitDebugger');
?>
-539
View File
@@ -1,539 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* FirePHP Class for CakePHP
*
* Provides most of the functionality offered by FirePHPCore
* Interoperates with FirePHP extension for firefox
*
* For more information see: http://www.firephp.org/
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package debug_kit.
* @subpackage debug_kit.vendors
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Core', 'Debugger');
class FireCake extends Object {
/**
* Options for FireCake.
*
* @see _defaultOptions and setOptions();
* @var string
*/
var $options = array();
/**
* Default Options used in CakeFirePhp
*
* @var string
* @access protected
*/
var $_defaultOptions = array(
'maxObjectDepth' => 10,
'maxArrayDepth' => 20,
'useNativeJsonEncode' => true,
'includeLineNumbers' => true,
);
/**
* Message Levels for messages sent via FirePHP
*
* @var array
*/
var $_levels = array(
'log' => 'LOG',
'info' => 'INFO',
'warn' => 'WARN',
'error' => 'ERROR',
'dump' => 'DUMP',
'trace' => 'TRACE',
'exception' => 'EXCEPTION',
'table' => 'TABLE',
'groupStart' => 'GROUP_START',
'groupEnd' => 'GROUP_END',
);
var $_version = '0.2.1';
/**
* internal messageIndex counter
*
* @var int
* @access protected
*/
var $_messageIndex = 1;
/**
* stack of objects encoded by stringEncode()
*
* @var array
**/
var $_encodedObjects = array();
/**
* methodIndex to include in tracebacks when using includeLineNumbers
*
* @var array
**/
var $_methodIndex = array('info', 'log', 'warn', 'error', 'table', 'trace');
/**
* FireCake output status
*
* @var bool
**/
var $_enabled = true;
/**
* get Instance of the singleton
*
* @param string $class Class instance to store in the singleton. Used with subclasses and Tests.
* @access public
* @static
* @return void
*/
function &getInstance($class = null) {
static $instance = array();
if (!empty($class)) {
if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
$instance[0] = new $class();
$instance[0]->setOptions();
}
}
if (!isset($instance[0]) || !$instance[0]) {
$instance[0] = new FireCake();
$instance[0]->setOptions();
}
return $instance[0];
}
/**
* setOptions
*
* @param array $options Array of options to set.
* @access public
* @static
* @return void
*/
function setOptions($options = array()) {
$_this = FireCake::getInstance();
if (empty($_this->options)) {
$_this->options = array_merge($_this->_defaultOptions, $options);
} else {
$_this->options = array_merge($_this->options, $options);
}
}
/**
* Return boolean based on presence of FirePHP extension
*
* @access public
* @return boolean
**/
function detectClientExtension() {
$ua = FireCake::getUserAgent();
if (!preg_match('/\sFirePHP\/([\.|\d]*)\s?/si', $ua, $match) || !version_compare($match[1], '0.0.6', '>=')) {
return false;
}
return true;
}
/**
* Get the Current UserAgent
*
* @access public
* @static
* @return string UserAgent string of active client connection
**/
function getUserAgent() {
return env('HTTP_USER_AGENT');
}
/**
* Disable FireCake output
* All subsequent output calls will not be run.
*
* @return void
**/
function disable() {
$_this = FireCake::getInstance();
$_this->_enabled = false;
}
/**
* Enable FireCake output
*
* @return void
**/
function enable() {
$_this = FireCake::getInstance();
$_this->_enabled = true;
}
/**
* Convenience wrapper for LOG messages
*
* @param string $message Message to log
* @param string $label Label for message (optional)
* @access public
* @static
* @return void
*/
function log($message, $label = null) {
FireCake::fb($message, $label, 'log');
}
/**
* Convenience wrapper for WARN messages
*
* @param string $message Message to log
* @param string $label Label for message (optional)
* @access public
* @static
* @return void
*/
function warn($message, $label = null) {
FireCake::fb($message, $label, 'warn');
}
/**
* Convenience wrapper for INFO messages
*
* @param string $message Message to log
* @param string $label Label for message (optional)
* @access public
* @static
* @return void
*/
function info($message, $label = null) {
FireCake::fb($message, $label, 'info');
}
/**
* Convenience wrapper for ERROR messages
*
* @param string $message Message to log
* @param string $label Label for message (optional)
* @access public
* @static
* @return void
*/
function error($message, $label = null) {
FireCake::fb($message, $label, 'error');
}
/**
* Convenience wrapper for TABLE messages
*
* @param string $message Message to log
* @param string $label Label for message (optional)
* @access public
* @static
* @return void
*/
function table($label, $message) {
FireCake::fb($message, $label, 'table');
}
/**
* Convenience wrapper for DUMP messages
*
* @param string $message Message to log
* @param string $label Unique label for message
* @access public
* @static
* @return void
*/
function dump($label, $message) {
FireCake::fb($message, $label, 'dump');
}
/**
* Convenience wrapper for TRACE messages
*
* @param string $label Label for message (optional)
* @access public
* @return void
*/
function trace($label) {
FireCake::fb($label, 'trace');
}
/**
* Convenience wrapper for GROUP messages
* Messages following the group call will be nested in a group block
*
* @param string $label Label for group (optional)
* @access public
* @return void
*/
function group($label) {
FireCake::fb(null, $label, 'groupStart');
}
/**
* Convenience wrapper for GROUPEND messages
* Closes a group block
*
* @param string $label Label for group (optional)
* @access public
* @return void
*/
function groupEnd() {
FireCake::fb(null, null, 'groupEnd');
}
/**
* fb - Send messages with FireCake to FirePHP
*
* Much like FirePHP's fb() this method can be called with various parameter counts
* fb($message) - Just send a message defaults to LOG type
* fb($message, $type) - Send a message with a specific type
* fb($message, $label, $type) - Send a message with a custom label and type.
*
* @param mixed $message Message to output. For other parameters see usage above.
* @static
* @return void
**/
function fb($message) {
$_this = FireCake::getInstance();
if (headers_sent($filename, $linenum)) {
trigger_error(sprintf(__('Headers already sent in %s on line %s. Cannot send log data to FirePHP.', true), $filename, $linenum), E_USER_WARNING);
return false;
}
if (!$_this->_enabled || !$_this->detectClientExtension()) {
return false;
}
$args = func_get_args();
$type = $label = null;
switch (count($args)) {
case 1:
$type = $_this->_levels['log'];
break;
case 2:
$type = $args[1];
break;
case 3:
$type = $args[2];
$label = $args[1];
break;
default:
trigger_error(__('Incorrect parameter count for FireCake::fb()', true), E_USER_WARNING);
return false;
}
if (isset($_this->_levels[$type])) {
$type = $_this->_levels[$type];
} else {
$type = $_this->_levels['log'];
}
$meta = array();
$skipFinalObjectEncode = false;
if ($type == $_this->_levels['trace']) {
$trace = debug_backtrace();
if (!$trace) {
return false;
}
$message = $_this->_parseTrace($trace, $args[0]);
$skipFinalObjectEncode = true;
}
if ($_this->options['includeLineNumbers']) {
if (!isset($meta['file']) || !isset($meta['line'])) {
$trace = debug_backtrace();
for ($i = 0, $len = count($trace); $i < $len ; $i++) {
$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
$selfCall = ($keySet && $trace[$i]['class'] == 'FireCake' && in_array($trace[$i]['function'], $_this->_methodIndex));
if ($selfCall) {
$meta['File'] = isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '';
$meta['Line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
break;
}
}
}
}
$structureIndex = 1;
if ($type == $_this->_levels['dump']) {
$structureIndex = 2;
$_this->_sendHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
} else {
$_this->_sendHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
}
$_this->_sendHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
$_this->_sendHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'. $_this->_version);
if ($type == $_this->_levels['dump']) {
$dump = $_this->jsonEncode($message);
$msg = '{"' . $label .'":' . $dump .'}';
} else {
$meta['Type'] = $type;
if ($label !== null) {
$meta['Label'] = $label;
}
$msg = '[' . $_this->jsonEncode($meta) . ',' . $_this->jsonEncode($message, $skipFinalObjectEncode).']';
}
$lines = explode("\n", chunk_split($msg, 5000, "\n"));
foreach ($lines as $i => $line) {
if (empty($line)) {
continue;
}
$header = 'X-Wf-1-' . $structureIndex . '-1-' . $_this->_messageIndex;
if (count($lines) > 2) {
$first = ($i == 0) ? strlen($msg) : '';
$end = ($i < count($lines) - 2) ? '\\' : '';
$message = $first . '|' . $line . '|' . $end;
$_this->_sendHeader($header, $message);
} else {
$_this->_sendHeader($header, strlen($line) . '|' . $line . '|');
}
$_this->_messageIndex++;
if ($_this->_messageIndex > 99999) {
trigger_error(__('Maximum number (99,999) of messages reached!', true), E_USER_WARNING);
}
}
$_this->_sendHeader('X-Wf-1-Index', $_this->_messageIndex - 1);
return true;
}
/**
* Parse a debug backtrace
*
* @param array $trace Debug backtrace output
* @access protected
* @return array
**/
function _parseTrace($trace, $messageName) {
$message = array();
for ($i = 0, $len = count($trace); $i < $len ; $i++) {
$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
$selfCall = ($keySet && $trace[$i]['class'] == 'FireCake');
if (!$selfCall) {
$message = array(
'Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '',
'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '',
'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '',
'Message' => $messageName,
'File' => isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '',
'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '',
'Args' => isset($trace[$i]['args']) ? $this->stringEncode($trace[$i]['args']) : '',
'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1))
);
break;
}
}
return $message;
}
/**
* Fix a trace for use in output
*
* @param mixed $trace Trace to fix
* @access protected
* @static
* @return string
**/
function _escapeTrace($trace) {
for ($i = 0, $len = count($trace); $i < $len; $i++) {
if (isset($trace[$i]['file'])) {
$trace[$i]['file'] = Debugger::trimPath($trace[$i]['file']);
}
if (isset($trace[$i]['args'])) {
$trace[$i]['args'] = $this->stringEncode($trace[$i]['args']);
}
}
return $trace;
}
/**
* Encode non string objects to string.
* Filter out recursion, so no errors are raised by json_encode or $javascript->object()
*
* @param mixed $object Object or variable to encode to string.
* @param int $objectDepth Current Depth in object chains.
* @param int $arrayDepth Current Depth in array chains.
* @static
* @return void
**/
function stringEncode($object, $objectDepth = 1, $arrayDepth = 1) {
$_this = FireCake::getInstance();
$return = array();
if (is_resource($object)) {
return '** ' . (string)$object . '**';
}
if (is_object($object)) {
if ($objectDepth == $_this->options['maxObjectDepth']) {
return '** Max Object Depth (' . $_this->options['maxObjectDepth'] . ') **';
}
foreach ($_this->_encodedObjects as $encoded) {
if ($encoded === $object) {
return '** Recursion (' . get_class($object) . ') **';
}
}
$_this->_encodedObjects[] = $object;
$return['__className'] = $class = get_class($object);
$properties = (array) $object;
foreach ($properties as $name => $property) {
$return[$name] = FireCake::stringEncode($property, 1, $objectDepth + 1);
}
array_pop($_this->_encodedObjects);
}
if (is_array($object)) {
if ($arrayDepth == $_this->options['maxArrayDepth']) {
return '** Max Array Depth ('. $_this->options['maxArrayDepth'] . ') **';
}
foreach ($object as $key => $value) {
$return[$key] = FireCake::stringEncode($value, 1, $arrayDepth + 1);
}
}
if (is_string($object) || is_numeric($object) || is_bool($object) || is_null($object)) {
return $object;
}
return $return;
}
/**
* Encode an object into JSON
*
* @param mixed $object Object or array to json encode
* @param boolean $doIt
* @access public
* @static
* @return string
**/
function jsonEncode($object, $skipEncode = false) {
$_this = FireCake::getInstance();
if (!$skipEncode) {
$object = FireCake::stringEncode($object);
}
if (function_exists('json_encode') && $_this->options['useNativeJsonEncode']) {
return json_encode($object);
} else {
return FireCake::_jsonEncode($object);
}
}
/**
* jsonEncode Helper method for PHP4 compatibility
*
* @param mixed $object Something to encode
* @access protected
* @static
* @return string
**/
function _jsonEncode($object) {
if (!class_exists('JavascriptHelper')) {
App::import('Helper', 'Javascript');
}
$javascript = new JavascriptHelper();
$javascript->useNative = false;
return $javascript->object($object);
}
/**
* Send Headers - write headers.
*
* @access protected
* @return void
**/
function _sendHeader($name, $value) {
header($name . ': ' . $value);
}
}
?>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

-84
View File
@@ -1,84 +0,0 @@
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Javascript. jQuery 1.2.x compatible.
*
* Long description here.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
(function($) {
$(document).ready(function(){
DebugKit.Toolbar();
DebugKit.NeatArray();
});
var DebugKit = {};
/**
* Create all behaviors for neat array elements
*
*/
DebugKit.NeatArray = function() {
$('.neat-array').find('li:has(ul)').toggle(
function() {
$(this).toggleClass('expanded').removeClass('collapsed').find('ul:first').show();
},
function() {
$(this).toggleClass('expanded').addClass('collapsed').find('ul:first').hide();
}
).addClass('expandable').addClass('collapsed').find('ul').hide();
}
/**
* Add behavior for toolbar buttons
*
*/
DebugKit.Toolbar = function() {
var tabCollection = $('#debug-kit-toolbar li > div');
$('#debug-kit-toolbar .panel-tab > a').click(
function(e){
e.preventDefault();
var targetPanel = $(this.hash + '-tab');
if (targetPanel.hasClass('active')) {
tabCollection.hide().removeClass('active');
} else {
tabCollection
.hide().removeClass('active')
.filter(this.hash + '-tab').show().addClass('active');
}
$('#debug-kit-toolbar .panel-tab > a').removeClass('active');
$(this).addClass('active');
}
);
//enable hiding of toolbar.
var panelButtons = $('#debug-kit-toolbar .panel-tab:not(.panel-tab.icon)');
$('#debug-kit-toolbar #hide-toolbar').toggle(
function() {
panelButtons.hide();
},
function() {
panelButtons.show();
}
);
}
})(jQuery);
-212
View File
@@ -1,212 +0,0 @@
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Javascript.
*
* Long description here.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
var DebugKit = function(id) {
var undefined,
elements = {},
panels = {},
hidden = false;
this.initialize = function(id) {
elements.toolbar = document.getElementById(id || 'debug-kit-toolbar');
if (elements.toolbar === undefined) {
throw new Exception('Toolbar not found, make sure you loaded it.');
}
for (var i in elements.toolbar.childNodes) {
var element = elements.toolbar.childNodes[i];
if (element.nodeName && element.id === 'panel-tabs') {
elements.panel = element;
break;
}
}
for (var i in elements.panel.childNodes) {
var element = elements.panel.childNodes[i];
if (element.className && element.className.match(/panel-tab/)) {
this.addPanel(element);
}
}
var lists = document.getElementsByTagName('ul'), index = 0;
while (lists[index] !== undefined) {
var element = lists[index];
if (element.className && element.className.match(/neat-array/)) {
neatArray(element);
}
++index;
}
}
/**
* Add a panel to the toolbar
*/
this.addPanel = function(tab, callback) {
if (!tab.nodeName || tab.nodeName.toUpperCase() !== 'LI') {
throw new Exception('Toolbar not found, make sure you loaded it.');
}
var panel = {
id : false,
element : tab,
callback : callback,
button : undefined,
content : undefined,
active : false
};
for (var i in tab.childNodes) {
var element = tab.childNodes[i],
tag = element.nodeName? element.nodeName.toUpperCase(): false;
if (tag === 'A') {
panel.id = element.hash.replace(/^#/, '');
panel.button = element;
} else if (tag === 'DIV') {
panel.content = element;
}
}
if (!panel.id) {
throw new Exception('invalid element');
}
if (panel.button.id && panel.button.id === 'hide-toolbar') {
panel.callback = this.toggleToolbar;
}
if (panel.callback !== undefined) {
panel.button.onclick = function() { return panel.callback(); };
} else {
panel.button.onclick = function() { return window.DebugKit.togglePanel(panel.id); };
}
panels[panel.id] = panel;
return panel.id;
};
/**
* Hide/show the toolbar (minimize cake)
*/
this.toggleToolbar = function() {
for (var i in panels) {
var panel = panels[i],
display = hidden? 'block': 'none';
if (panel.content !== undefined) {
panel.element.style.display = display;
}
}
hidden = !hidden;
return true;
};
/**
* Toggle a panel
*/
this.togglePanel = function(id) {
if (panels[id] && panels[id].active) {
this.deactivatePanel(true);
} else {
this.deactivatePanel(true);
this.activatePanel(id);
}
}
/**
* Make a panel active.
*/
this.activatePanel = function(id, unique) {
if (panels[id] !== undefined && !panels[id].active) {
var panel = panels[id];
this.deactivatePanel(true);
if (panel.content !== undefined) {
panel.content.style.display = 'block';
}
panel.button.className = panel.button.className.replace(/^(.*)$/, '$1 active');
panel.active = true;
return true;
}
return false;
};
/**
* Deactivate a panel. use true to hide all panels.
*/
this.deactivatePanel = function(id) {
if (id === true) {
for (var i in panels) {
this.deactivatePanel(i);
}
return true;
}
if (panels[id] !== undefined && panels[id].active) {
var panel = panels[id];
if (panel.content !== undefined) {
panel.content.style.display = 'none';
}
panel.button.className = panel.button.className.replace(/ ?(active) ?/, '');
panel.active = false;
return true;
}
return false;
};
/**
* Add neat array functionality.
*/
function neatArray(list) {
if (!list.className.match(/depth-0/)) {
var item = list.parentNode;
list.style.display = 'none';
item.className = (item.className || '').replace(/^(.*)$/, '$1 expandable collapsed');
item.onclick = function(event) {
//var element = (event === undefined)? this: event.target;
var element = this,
event = event || window.event,
act = Boolean(item === element),
hide = Boolean(list.style.display === 'block');
if (act && hide) {
list.style.display = 'none';
item.className = item.className.replace(/expanded|$/, 'collapsed');
} else if (act) {
list.style.display = 'block';
item.className = item.className.replace('collapsed', 'expanded');
}
if (event.cancelBubble !== undefined) {
event.cancelBubble = true;
}
return false;
}
}
}
this.initialize(id);
}
DebugKit.install = function() {
var initializer = window.onload || function() {};
window.onload = function() {
initializer();
// makes DebugKit a singletone instance
window.DebugKit = new DebugKit();
}
}
DebugKit.install();
-95
View File
@@ -1,95 +0,0 @@
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Javascript. Mootools 1.2 compatible.
*
* Requires Class, Event, Element, and Selectors
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
window.addEvent('domready', function() {
new DebugKit();
});
var DebugKit = new Class({
initialize : function() {
this.neatArray();
this.toolbar();
},
/**
* Create all behaviors for neat array elements
*/
neatArray : function() {
$$('#debug-kit-toolbar .neat-array li').each(function(listItem) {
var subUl = listItem.getElement('ul');
if (subUl) {
listItem.addClass('expandable').addClass('collapsed');
subUl.setStyle('display', 'none').set('state', 'closed');
listItem.addEvent('click', function(event) {
event.stop();
this.toggleClass('expanded').toggleClass('collapsed');
if (subUl.get('state') == 'closed') {
subUl.setStyle('display', 'block').set('state', 'open');
} else {
subUl.setStyle('display', 'none').set('state', 'closed');
}
})
}
});
},
/**
* Add behavior for toolbar buttons
*/
toolbar : function() {
var tabCollection = $$('#debug-kit-toolbar li > div');
$$('#debug-kit-toolbar .panel-tab > a').addEvent('click', function(event) {
event.stop();
var buttonId = this.hash.substring(1, this.hash.length) + '-tab';
var targetPanel = $(buttonId);
if (!targetPanel) return;
$$('#debug-kit-toolbar .panel-tab > a').removeClass('active');
if (targetPanel.hasClass('active')) {
tabCollection.removeClass('active').setStyle('display', 'none');
} else {
tabCollection.setStyle('display', 'none').removeClass('active');
targetPanel.addClass('active').setStyle('display', 'block');
this.addClass('active');
}
});
//enable hiding of toolbar.
var panelButtons = $$('#debug-kit-toolbar .panel-tab:not(.panel-tab.icon)');
var toolbarHide = $('hide-toolbar').set('state', 'open');
toolbarHide.addEvent('click', function(event) {
event.stop();
var state = this.get('state');
if (state == 'open') {
panelButtons.setStyle('display', 'none');
this.set('state', 'closed')
} else {
panelButtons.setStyle('display');
this.set('state', 'open');
}
});
}
});
-95
View File
@@ -1,95 +0,0 @@
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Javascript. Prototype 1.6.x compatible.
*
* Long description here.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
document.observe('dom:loaded', function() {
new DebugKit();
});
var DebugKit = Class.create({
initialize: function(){
this.toolbar();
this.neatArray();
},
toolbar: function(){
var tabCollection = $('debug-kit-toolbar').select('li > div');
$('debug-kit-toolbar').select('.panel-tab > a').invoke('observe', 'click', function(e){
e.stop();
var targetPanel = $(e.element().hash.replace(/#/, '') + '-tab');
if (targetPanel.hasClassName('active')) {
tabCollection.each(function(ele){
ele.hide().removeClassName('active');
});
} else {
tabCollection.each(function(ele){
ele.hide().removeClassName('active');
if (targetPanel.id == ele.id) {
ele.setStyle({display: 'block'}).addClassName('active');
}
});
}
$('debug-kit-toolbar').select('.panel-tab > a').invoke('removeClassName', 'active');
e.element().addClassName('active');
});
// enable hiding of toolbar.
var panelButtons = $('debug-kit-toolbar').select('.panel-tab');
$('hide-toolbar').observe('click', function(eve){
eve.stop();
panelButtons.each(function(panel){
if (!panel.hasClassName('icon')) {
panel.toggle();
};
});
});
},
/**
* Create all behaviors for neat array elements
*/
neatArray: function() {
$('debug-kit-toolbar').select('.neat-array li').each(function(ele){
var sub = ele.select('ul');
if (sub.length > 0) {
ele.addClassName('collapsed').addClassName('expandable');
sub.invoke('hide');
ele.observe('click', function(eve){
if (eve.element() == ele || eve.element().up() == ele) {
if (sub.length > 0) {
ele.toggleClassName('expanded').toggleClassName('collapsed');
sub[0].toggle();
}
}
});
};
});
}
});
-126
View File
@@ -1,126 +0,0 @@
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Javascript. YUI 2.6 compatible.
*
* Long description here.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
YAHOO.namespace('CakePHP.DebugKit');
YAHOO.CakePHP.DebugKit = function() {
var Event = YAHOO.util.Event;
var Dom = YAHOO.util.Dom;
var Selector = YAHOO.util.Selector;
var toggle = function(el) {
Dom.setStyle(el, 'display', ((Dom.getStyle(el, 'display') == 'none') ? '' : 'none'));
};
var toggleClass = function(element, className) {
(Dom.hasClass(element, className)) ? Dom.removeClass(element, className) : Dom.addClass(element, className);
};
var toolbar = function() {
var tabCollection = Selector.query('#debug-kit-toolbar li > div');
Dom.batch(Selector.query('#debug-kit-toolbar .panel-tab > a'), function(el) {
Event.on(el, 'click', function(ev) {
Event.preventDefault(ev);
targetPanel =Dom.get(el.hash.replace(/#/, '') + '-tab');
if (Dom.hasClass(targetPanel, 'active')) {
Dom.batch(tabCollection, function(ele) {
toggle(ele);
Dom.removeClass(ele, 'active');
Dom.setStyle(ele, 'display', '');
});
} else {
Dom.batch(tabCollection, function(ele) {
toggle(ele);
Dom.removeClass(ele, 'active');
if (targetPanel && targetPanel.id == ele.id) {
Dom.setStyle(ele, 'display', 'block');
Dom.addClass(ele, 'active');
}
});
}
Dom.removeClass(Selector.query('#debug-kit-toolbar .panel-tab > a'), 'active');
Dom.addClass(el, 'active');
});
});
};
var neatArray = function() {
nodes = Selector.query('#debug-kit-toolbar .panel-content > ul.neat-array li > ul');
if (nodes.length > 0) {
Dom.batch(nodes, function(el) {
var parent = el.parentNode;
Dom.addClass(parent, 'collapsed');
Dom.addClass(parent, 'expandable');
toggle(nodes);
Event.on(parent, 'click', function(ev) {
sub = Selector.query('ul', parent);
toggleClass(parent, 'expanded');
toggleClass(parent, 'collapsed');
toggle(sub);
});
});
}
};
var panelButtons = function() {
Event.on('hide-toolbar', 'click', function(ev) {
Event.preventDefault(ev);
Dom.getElementsByClassName('panel-tab', 'li', 'debug-kit-toolbar', function (el) {
if (!Dom.hasClass(el, 'icon')) {
toggle(el);
}
});
});
};
return {
initialize: function() {
neatArray();
toolbar();
panelButtons();
}
};
}(); // Execute annonymous closure & return results
YAHOO.util.Event.onDOMReady(YAHOO.CakePHP.DebugKit.initialize);
-79
View File
@@ -1,79 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Benchmark Shell.
*
* Provides basic benchmarking of application requests
* functionally similar to Apache AB
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.vendors.shells
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class BenchmarkShell extends Shell {
function main() {
$url = $this->args[0];
$this->out(sprintf('-> Testing %s', $url));
$n = 100;
$t = $i = 0;
if (isset($this->params['n'])) {
$n = $this->params['n'];
}
if (isset($this->params['t'])) {
$t = $this->params['t'];
}
$start = microtime(true);
while (true) {
if ($t && $t <= floor(microtime(true) - $start)) {
break;
}
if ($n <= $i) {
break;
}
file_get_contents($url);
$i++;
}
$duration = microtime(true) - $start;
$this->out('Total Requests made: ' . $i);
$this->out('Total Time elapsed: ' . $duration . '(s)');
$this->out(round($n / $duration, 2).' req/sec');
}
function help() {
$out = <<<EOL
DebugKit Benchmark Shell
Test a fully qualified url to get avg requests per second.
By default it does 100 requests to the provided url.
Use:
cake benchmark [params] [url]
Params
-n The maximum number of iterations to do.
-t The maximum time to take. If a single request takes more
than this time. Only one request will be made.
EOL;
$this->out($out);
}
}
?>
-154
View File
@@ -1,154 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Debug View
*
* Custom Debug View class, helps with development.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.
* @since CakePHP v 1.2.0.4487
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Vendor', 'DebugKit.DebugKitDebugger');
App::import('Component', 'DebugKit.Toolbar');
/**
* DebugView used by DebugKit
*
* @package debug_kit.views
* @todo Remove workarounds.
*/
class DebugView extends DoppelGangerView {
/**
* The old extension of the current template.
*
* @var string
*/
var $_oldExtension = null;
/**
* Overload _render to capture filenames and time actual rendering of each view file
*
* @param string $___viewFn Filename of the view
* @param array $___dataForView Data to include in rendered view
* @return string Rendered output
* @access protected
*/
function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
/* pr(array('function' => 'DebugView::_render', */
/* 'args' => compact('__viewFn', '__dataForView', 'loadHelpers'), */
/* 'this-output-len' => strlen($this->output), */
/* )); */
if (isset($this->_oldExtension) && strstr($___viewFn, '.debug_view')) {
$___viewFn = substr($___viewFn, 0, -10) . $this->_oldExtension;
}
if (!isset($___dataForView['disableTimer'])) {
DebugKitDebugger::startTimer('render_' . basename($___viewFn), sprintf(__('Rendering %s', true), Debugger::trimPath($___viewFn)));
}
$out = parent::_render($___viewFn, $___dataForView, $loadHelpers, $cached);
if (!isset($___dataForView['disableTimer'])) {
DebugKitDebugger::stopTimer('render_' . basename($___viewFn));
}
/* pr(array('function' => 'DebugView::_render', */
/* 'out-len' => strlen($out), */
/* 'this-output-len' => strlen($this->output), */
/* 'return' => $out ? 'not-empty' : 'empty')); */
return $out;
}
/**
* Renders view for given action and layout. If $file is given, that is used
* for a view filename (e.g. customFunkyView.ctp).
* Adds timers, for all subsequent rendering, and injects the debugKit toolbar.
*
* @param string $action Name of action to render for
* @param string $layout Layout to use
* @param string $file Custom filename for view
* @return string Rendered Element
*/
function render($action = null, $layout = null, $file = null) {
/* pr(array('function' => 'DebugView::render', */
/* 'args' => compact('action', 'layout', 'file'), */
/* 'this-output-len' => strlen($this->output), */
/* )); */
DebugKitDebugger::startTimer('viewRender', __('Rendering View', true));
$out = parent::render($action, $layout, $file);
/* pr(array('function' => 'DebugView::render', */
/* 'checkpoint' => 'parent::render', */
/* 'out' => $out ? 'not-empty' : 'empty')); */
DebugKitDebugger::stopTimer('viewRender');
DebugKitDebugger::stopTimer('controllerRender');
if (isset($this->loaded['toolbar'])) {
/* pr(array('function' => 'DebugView::render', */
/* 'checkpoint' => 'toolbarLoaded')); */
$this->loaded['toolbar']->postRender();
}
//Temporary work around to hide the SQL dump at page bottom
Configure::write('debug', 0);
/* pr(array('function' => 'DebugView::render', */
/* 'out-len' => strlen($out), */
/* 'this-output-len' => strlen($this->output), */
/* 'return' => $this->output ? 'not-empty' : 'empty')); */
return $this->output;
}
/**
* Workaround _render() limitation in core. Which forces View::_render() for .ctp and .thtml templates
* Creates temporary extension to trick View::render() & View::renderLayout()
*
* @param string $name Action name.
* @return string
**/
function _getViewFileName($name = null) {
$filename = parent::_getViewFileName($name);
return $this->_replaceExtension($filename);
}
/**
* Workaround _render() limitation in core. Which forces View::_render() for .ctp and .thtml templates
* Creates temporary extension to trick View::render() & View::renderLayout()
*
* @param string $name Layout Name
* @return string
**/
function _getLayoutFileName($name = null) {
$filename = parent::_getLayoutFileName($name);
return $this->_replaceExtension($filename);
}
/**
* replace the Extension on a filename and set the temporary workaround extension.
*
* @param string $filename Filename to replace extension for.
* @return string
**/
function _replaceExtension($filename) {
if (substr($filename, -3) == 'ctp') {
$this->_oldExtension = 'ctp';
$filename = substr($filename, 0, strlen($filename) -3) . 'debug_view';
} elseif (substr($filename, -5) == 'thtml') {
$this->_oldExtension = 'thtml';
$filename = substr($filename, 0, strlen($filename) -5) . 'debug_view';
}
return $filename;
}
}
?>
@@ -1,52 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Debug Toolbar Element
*
* Renders all of the other panel elements.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<div id="debug-kit-toolbar">
<?php if (empty($debugToolbarPanels)) :?>
<p class="warning"><?php __('There are no active panels. You must enable a panel to see its output.'); ?></p>
<?php else: ?>
<ul id="panel-tabs">
<li class="panel-tab icon">
<a href="#hide" id="hide-toolbar">
<?php echo $html->image('/debug_kit/img/cake.icon.png', array('alt' => 'cakePHP')); ?>
</a>
</li>
<?php foreach ($debugToolbarPanels as $panelName => $panelInfo): ?>
<li class="panel-tab">
<a href="#<?php echo Inflector::underscore($panelName); ?>">
<?php echo Inflector::humanize(Inflector::underscore($panelName)); ?>
</a>
<div class="panel-content" id="<?php echo Inflector::underscore($panelName); ?>-tab">
<?php echo $this->element($panelInfo['elementName'], $panelInfo); ?>
</div>
</li>
<?php endforeach ?>
</ul>
<?php endif; ?>
</div>
@@ -1,48 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Log Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2><?php __('Logs') ?></h2>
<div class="code-table">
<?php foreach ($content as $logName => $logs): ?>
<h3><?php echo $logName ?></h3>
<?php
$len = count($logs);
if ($len > 0):
$headers = array(__('Time', true), __('Message', true));
$rows = array();
for ($i = 0; $i < $len; $i += 2):
$rows[] = array(
$logs[$i], $logs[$i + 1]
);
endfor;
echo $toolbar->table($rows, $headers, array('title' => $logName));
else: ?>
<p class="info"><?php __('There were no log entries made this request'); ?></p>
<?php endif; ?>
<?php endforeach; ?>
</div>
@@ -1,43 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Session Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2><?php __('Memory'); ?></h2>
<div class="current-mem-use">
<?php echo $toolbar->message(
__('Current Memory Use',true),
$number->toReadableSize(DebugKitDebugger::getMemoryUse())
);?>
</div>
<div class="peak-mem-use">
<?php
echo $toolbar->message(
__('Peak Memory Use', true),
$number->toReadableSize(DebugKitDebugger::getPeakMemoryUse())
);
?></div>
@@ -1,45 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Request Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2> <?php __('Request'); ?></h2>
<h4>Cake Params</h4>
<?php echo $toolbar->makeNeatArray($content['params']); ?>
<h4>$_GET</h4>
<?php echo $toolbar->makeNeatArray($content['get']); ?>
<h4>Cookie</h4>
<?php if (isset($content['cookie'])): ?>
<?php echo $toolbar->makeNeatArray($content['cookie']); ?>
<?php else: ?>
<p class="warning">To view Cookies, add CookieComponent to Controller
<?php endif; ?>
<h4><?php __('Current Route') ?></h4>
<?php echo $toolbar->makeNeatArray($content['currentRoute']); ?>
@@ -1,31 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Session Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2><?php __('Session'); ?></h2>
<?php echo $toolbar->makeNeatArray($content); ?>
@@ -1,40 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Session Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2><?php __('Sql Logs')?></h2>
<?php if (!empty($content)) : ?>
<?php foreach ($content as $dbName => $queryLog) : ?>
<div class="sql-log-panel-query-log">
<h4><?php echo $dbName ?></h4>
<?php echo $queryLog; ?>
</div>
<?php endforeach; ?>
<?php else: ?>
<p class="warning"><?php __('No active database connections'); ?>
<?php endif; ?>
@@ -1,44 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Timer Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
$timers = DebugKitDebugger::getTimers();
?>
<h2><?php __('Timers'); ?></h2>
<p class="request-time">
<?php $totalTime = sprintf(__('%s (seconds)', true), $number->precision(DebugKitDebugger::requestTime(), 6)); ?>
<?php echo $toolbar->message(__('Total Request Time:', true), $totalTime)?>
</p>
<?php foreach ($timers as $timerName => $timeInfo):
$rows[] = array(
$timeInfo['message'],
$number->precision($timeInfo['time'], 6)
);
$headers = array(__('Message', true), __('time in seconds', true));
endforeach;
echo $toolbar->table($rows, $headers, array('title' => 'Timers')); ?>
@@ -1,35 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* View Variables Panel Element
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.debug_kit.views.elements
* @since
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
?>
<h2> <?php __('View Variables'); ?></h2>
<?php
$vars = $this->viewVars;
unset($vars['debugToolbarPanels'], $vars['debugToolbarJavascript']);
?>
<?php echo $toolbar->makeNeatArray($vars); ?>
@@ -1,79 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* FirePHP Toolbar Helper
*
* Injects the toolbar elements into non-HTML layouts via FireCake.
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package debug_kit
* @subpackage debug_kit.views.helpers
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('helper', 'DebugKit.Toolbar');
App::import('Vendor', 'DebugKit.FireCake');
class FirePhpToolbarHelper extends ToolbarHelper {
/**
* send method
*
* @return void
* @access protected
*/
function _send() {
$view =& ClassRegistry::getObject('view');
$view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
Configure::write('debug', 1);
}
/**
* makeNeatArray.
*
* wraps FireCake::dump() allowing panel elements to continue functioning
*
* @param string $values
* @return void
*/
function makeNeatArray($values) {
FireCake::info($values);
}
/**
* Create a simple message
*
* @param string $label Label of message
* @param string $message Message content
* @return void
*/
function message($label, $message) {
FireCake::log($message, $label);
}
/**
* Generate a table with FireCake
*
* @param array $rows Rows to print
* @param array $headers Headers for table
* @param array $options Additional options and params
* @return void
*/
function table($rows, $headers, $options = array()) {
$title = $headers[0];
if (isset($options['title'])) {
$title = $options['title'];
}
array_unshift($rows, $headers);
FireCake::table($title, $rows);
}
}
?>
@@ -1,150 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Html Toolbar Helper
*
* Injects the toolbar elements into HTML layouts.
* Contains helper methods for
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package debug_kit
* @subpackage debug_kit.views.helpers
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('helper', 'DebugKit.Toolbar');
class HtmlToolbarHelper extends ToolbarHelper {
/**
* helpers property
*
* @var array
* @access public
*/
var $helpers = array('Html', 'Javascript');
/**
* settings property
*
* @var array
* @access public
*/
var $settings = array('format' => 'html');
/**
* Recursively goes through an array and makes neat HTML out of it.
*
* @param mixed $values Array to make pretty.
* @param int $openDepth Depth to add open class
* @param int $currentDepth current depth.
* @return string
**/
function makeNeatArray($values, $openDepth = 0, $currentDepth = 0) {
$className ="neat-array depth-$currentDepth";
if ($openDepth > $currentDepth) {
$className .= ' expanded';
}
$nextDepth = $currentDepth + 1;
$out = "<ul class=\"$className\">";
if (!is_array($values)) {
if (is_bool($values)) {
$values = array($values);
}
if (is_null($values)) {
$values = array(null);
}
}
foreach ($values as $key => $value) {
$out .= '<li><strong>' . $key . '</strong>';
if ($value === null) {
$value = '(null)';
}
if ($value === false) {
$value = '(false)';
}
if ($value === true) {
$value = '(true)';
}
if (empty($value) && $value != 0) {
$value = '(empty)';
}
if (is_object($value)) {
$value = Set::reverse($value, true);
}
if (is_array($value) && !empty($value)) {
$out .= $this->makeNeatArray($value, $openDepth, $nextDepth);
} else {
$out .= $value;
}
$out .= '</li>';
}
$out .= '</ul>';
return $out;
}
/**
* Create an HTML message
*
* @param string $label label content
* @param string $message message content
* @return string
*/
function message($label, $message) {
return sprintf('<p><strong>%s</strong> %s</p>', $label, $message);
}
/**
* Create a table.
*
* @param array $rows Rows to make.
* @param array $headers Optional header row.
* @return string
*/
function table($rows, $headers = array()) {
$out = '<table class="debug-table">';
if (!empty($headers)) {
$out .= $this->Html->tableHeaders($headers);
}
$out .= $this->Html->tableCells($rows, array('class' => 'odd'), array('class' => 'even'));
$out .= '</table>';
return $out;
}
/**
* send method
*
* @return void
* @access protected
*/
function _send() {
if (Configure::read('debug') == 0) {
return;
}
$view =& ClassRegistry::getObject('view');
$head = $this->Html->css('/debug_kit/css/debug_toolbar');
if (isset($view->viewVars['debugToolbarJavascript'])) {
foreach ($view->viewVars['debugToolbarJavascript'] as $script) {
if ($script) {
$head .= $this->Javascript->link($script);
}
}
}
if (preg_match('#</head>#', $view->output)) {
$view->output = preg_replace('#</head>#', $head . "\n</head>", $view->output, 1);
}
$toolbar = $view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
if (preg_match('#</body>#', $view->output)) {
$view->output = preg_replace('#</body>#', $toolbar . "\n</body>", $view->output, 1);
}
}
}
?>
@@ -1,90 +0,0 @@
<?php
/* SVN FILE: $Id$ */
/**
* Abstract Toolbar helper. Provides Base methods for content
* specific debug toolbar helpers. Acts as a facade for other toolbars helpers as well.
*
* helps with development.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package debug_kit
* @subpackage debug_kit.views.helpers
* @since v 1.0
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Vendor', 'DebugKit.DebugKitDebugger');
class ToolbarHelper extends AppHelper {
/**
* settings property to be overloaded. Subclasses should specify a format
*
* @var array
* @access public
*/
var $settings = array();
/**
* Construct the helper and make the backend helper.
*
* @param string $options
* @access public
* @return void
*/
function __construct($options = array()) {
$this->_myName = strtolower(get_class($this));
if ($this->_myName !== 'toolbarhelper') {
return;
}
if (!isset($options['output'])) {
$options['output'] = 'DebugKit.HtmlToolbar';
}
App::import('Helper', $options['output']);
$className = $options['output'];
if (strpos($options['output'], '.') !== false) {
list($plugin, $className) = explode('.', $options['output']);
}
$this->_backEndClassName = $className;
$this->helpers = array($options['output']);
}
/**
* call__
*
* Allows method calls on backend helper
*
* @param string $method
* @param mixed $params
* @access public
* @return void
*/
function call__($method, $params) {
if (method_exists($this->{$this->_backEndClassName}, $method)) {
return $this->{$this->_backEndClassName}->dispatchMethod($method, $params);
}
}
/**
* postRender method
*
* Custom Callback defined in DebugView to allow helpers to modify
* View output after all rendering is complete.
*
* @return void
* @access public
*/
function postRender() {
$this->_send();
}
}
+983
View File
@@ -0,0 +1,983 @@
#perl -w
use strict;
use DBI;
use Data::Dumper;
use File::Copy;
# Internally adjust all numbers coming from the database to
# be in inches. Not necessary to go to this detail, but the
# actual units used is irrelevant, provided everything is to
# scale, and this factor ensures that any fractional units
# become whole (e.g. 7.5 "feet" becomes 90 "units")
my $internal_adjustment_factor = 12;
my $schema_file = shift || die("Must specify schema file\n");
my $slink_file = shift || die("Must specify sitelink file\n");
my $slink_file = ";Data Source=$slink_file";
my $slink_pass = ";Jet OLEDB:Database Password=2web";
my $sdsn="Provider=Microsoft.Jet.OLEDB.4.0$slink_pass$slink_file";
my $sdbh = DBI->connect("dbi:ADO:$sdsn", undef, undef, {PrintError => 1,
RaiseError => 1});
# Connect to the database.
my($hostname, $database, $user, $password) = ('localhost',
'property_manager',
'pmgr', 'pmgruser');
my $db_handle = DBI->connect("DBI:mysql:database=$database;host=$hostname",
$user, $password,
{'RaiseError' => 1});
my ($query, $result, $nrows, $row);
my ($aicur_c_id, $aicur_ca_id, $aicur_cp_id, $aicur_ce_id) = (0, 0, 0, 0);
my ($aicur_g_id, $aicur_gp_id, $aicur_user_id) = (0, 0, 0);
my ($aicur_type_id, $aicur_size_id, $aicur_unit_id) = (0, 0, 0);
my ($aicur_site_id, $aicur_area_id) = (0, 0);
my ($aicur_lease_type_id, $aicur_lease_id) = (0, 0);
my ($aicur_charge_id, $aicur_receipt_id, $aicur_payment_id) = (0, 0, 0);
open(SCHEMA, "<$schema_file") || die ("Can't open schema ($!)\n");
my $schema_query = "";
while (<SCHEMA>) {
next if /^\s*-- /;
$schema_query .= $_;
query($db_handle, $schema_query), $schema_query = ""
if /;\s*$/;
}
close(SCHEMA);
++$aicur_c_id;
$query = "INSERT INTO pmgr_contacts
(`id`, `first_name`, `middle_name`, `last_name`, `display_name`) VALUES
($aicur_c_id, 'Abijah', 'M', 'Perkins', 'Perkins, Abijah')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ca_id;
$query = "INSERT INTO pmgr_contact_addresses
(`id`, `address`, `city`, `state`, `postcode`, `country`) VALUES
($aicur_ca_id, '1324 N Liberty Lake Rd\nPMB 263', 'Liberty Lake', 'WA', '99019', 'USA')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'POST', $aicur_ca_id, 'MAIN', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ca_id;
$query = "INSERT INTO pmgr_contact_addresses
(`id`, `address`, `city`, `state`, `postcode`, `country`) VALUES
($aicur_ca_id, '5221 W Myrtlewood Ct', 'Spokane', 'WA', '99208', 'USA')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'POST', $aicur_ca_id, 'HOME', 'ALTERNATE')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ca_id;
$query = "INSERT INTO pmgr_contact_addresses
(`id`, `address`, `city`, `state`, `postcode`, `country`) VALUES
($aicur_ca_id, 'PO Box 69', 'Granger', 'WA', '98932', 'USA')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'POST', $aicur_ca_id, 'HOME', 'ALTERNATE')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'MOBILE', '5098445573')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'MAIN', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'MOBILE', '5098445973')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'MAIN', 'ALTERNATE')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'VIRTUAL', '5095901112')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'BUSINESS', 'WORK')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'LANDLINE', '5098541491')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'HOME', 'ALTERNATE')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'VIRTUAL', '8774488664')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'BUSINESS', 'WORK')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_cp_id;
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`) VALUES
($aicur_cp_id, 'FAX', '8662960131')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'PHONE', $aicur_cp_id, 'BUSINESS', 'WORK')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ce_id;
$query = "INSERT INTO pmgr_contact_emails
(`id`, `email`) VALUES
($aicur_ce_id, 'abijah\@PerkinsHouse.com')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'EMAIL', $aicur_ce_id, 'HOME', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ce_id;
$query = "INSERT INTO pmgr_contact_emails
(`id`, `email`) VALUES
($aicur_ce_id, 'abijah\@PerkinsREI.com')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'EMAIL', $aicur_ce_id, 'HOME', 'WORK')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_ce_id;
$query = "INSERT INTO pmgr_contact_emails
(`id`, `email`) VALUES
($aicur_ce_id, 'abijah\@ValleyStorage.com')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($aicur_c_id, 'EMAIL', $aicur_ce_id, 'BUSINESS', 'WORK')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_g_id;
$query = "INSERT INTO pmgr_groups
(`id`, `code`, `name`)
VALUES
($aicur_g_id, 'Owner', 'Owner Group')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_gp_id;
$query = "INSERT INTO pmgr_group_permissions
(`group_id`, `name`, `access`)
VALUES
($aicur_gp_id, 'EVERYTHING', 'FORCED')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_user_id;
$query = "INSERT INTO pmgr_users
(`id`, `code`, `login`, `contact_id`)
VALUES
($aicur_user_id, 'AP', 'abijah', $aicur_c_id)";
query($db_handle, $query) || die("Unable to insert");
++$aicur_site_id;
$query = "INSERT INTO pmgr_sites
(`id`, `code`, `name`)
VALUES
($aicur_site_id, 'VSS', 'Valley Storage')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_site_memberships
(`site_id`, `user_id`, `group_id`)
VALUES
($aicur_site_id, $aicur_user_id, $aicur_g_id)";
query($db_handle, $query) || die("Unable to insert");
++$aicur_area_id;
$query = "INSERT INTO pmgr_site_areas
(`id`, `site_id`, `code`, `name`)
VALUES
($aicur_area_id, $aicur_site_id, 'Main', 'Main Facility Area')";
query($db_handle, $query) || die("Unable to insert");
++$aicur_lease_type_id;
$query = "INSERT INTO pmgr_lease_types
(`id`, `code`, `name`)
VALUES
($aicur_lease_type_id, 'SL', 'Storage Lease')";
query($db_handle, $query) || die("Unable to insert");
######################################################################
######################################################################
## query
sub query {
my ($dbh, $sql) = @_;
#print("$sql\n\n"); #return [ { 'id' => 7 } ];
#print("$sql\n\n") if $sql =~ /^\s*UPDATE/i;
#return 1 unless $sql =~ /^\s*SELECT/i;
my ($sth, $result);
if ($sql =~ /^\s*SELECT/i) {
$sth = $dbh->prepare($sql);
$sth->execute();
$result = $sth->fetchall_arrayref({});
} else {
$result = $dbh->do($sql);
}
#print("sth = " . Dumper($sth) . "\n");
#print("result = " . Dumper($result) . "\n");
return ($sth, $result);
}
sub sizeCode {
my ($width, $depth) = @_;
return "YARD"
if ($width == 12 && $depth == 40);
return "APARTMENT"
if ($width == 20 && $depth == 30);
return sprintf("%02dx%02d", $width, $depth);
}
sub datefmt {
my ($dt) = @_;
return undef unless $dt;
my @dt = split(/\/|\s/, $dt);
#print("$dt : " . sprintf("%04d-%02d-%02d", $dt[2], $dt[0], $dt[1]) . "\n");
return sprintf("%04d-%02d-%02d%s", $dt[2], $dt[0], $dt[1], $dt[3] ? ' '.$dt[3] : "");
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## UNITS
##
######################################################################
## Unit Types
$query = "SELECT * FROM UnitType ORDER BY TypeID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Unit Types\n");
foreach $row (@$result) {
$query = "INSERT INTO pmgr_unit_types
(`id`, `code`, `name`)
VALUES
($row->{'TypeID'}, 'xxx', '$row->{'UnitType'}')";
query($db_handle, $query) || die("Unable to insert");
}
######################################################################
## Unit Sizes
$query = "SELECT * FROM UnitInfo WHERE UnitID <> 'POS\$' ORDER BY UnitID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Units\n");
my (%unit_size_map);
foreach $row (@$result) {
my $sz = sizeCode($row->{'Width'}, $row->{'Depth'});
next if defined $unit_size_map{$sz};
$unit_size_map{$sz} = { 'id' => ++$aicur_size_id };
$unit_size_map{$sz}{'rent'} = $row->{'StdRent'};
$unit_size_map{$sz}{'dep'} = $row->{'StdSecDep'};
my $szid = $unit_size_map{$sz}{'id'};
$query = "INSERT INTO pmgr_unit_sizes
(`id`, `unit_type_id`, `code`, `name`, `width`, `depth`,
`deposit`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($szid, $row->{'Type'}, $sz, $sz,
$internal_adjustment_factor * $row->{'Width'},
$internal_adjustment_factor * $row->{'Depth'},
$row->{'StdSecDep'}, $row->{'StdRent'})
)) . ")";
query($db_handle, $query) || die("Unable to insert");
}
######################################################################
## Units
my (%unit_map);
foreach $row (@$result) {
my $sz = sizeCode($row->{'Width'}, $row->{'Depth'});
my $szid = $unit_size_map{$sz}{'id'};
$unit_map{$row->{'UnitID'}} = ++$aicur_unit_id;
my $uid = $unit_map{$row->{'UnitID'}};
$query = "INSERT INTO pmgr_units
(`id`, `unit_size_id`, `code`, `name`,
`status`,
`sort_order`, `walk_order`, `deposit`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($uid, $szid, $row->{'UnitID'}, $row->{'UnitID'},
$row->{'Rented'} ?'OCCUPIED' :($row->{'Rentable'} ?'VACANT' :'UNAVAILABLE'),
$uid, $uid, $row->{'StdSecDep'}, $row->{'StdRent'})
)) . ")";
query($db_handle, $query) || die("Unable to insert");
}
######################################################################
## Map
my %info = ('extents' => {}, 'units' => {});
# Get the overall site limits
$query = "SELECT MIN(M.Top) AS mintop, MIN(M.Left) AS minlft,";
$query .= " MAX(M.Top + IIF(M.reverseWL, U.Width, U.Depth)) AS bot,";
$query .= " MAX(M.Left + IIF(M.reverseWL, U.Depth, U.Width)) AS rgt";
$query .= ' FROM UnitInfo U INNER JOIN mapUnitsV2 M ON M.unitID = U.UnitID';
$result = query($sdbh, $query);
# Fetch and verify the result
my $row = shift(@$result);
die("MIN query failed!") unless $row;
# Compute the actual boundaries, adjusting for a (0,0) origin
my $top_adjustment = 0 - $row->{'mintop'};
my $left_adjustment = 0 - $row->{'minlft'};
$info{'extents'}{'top'} = 0;
$info{'extents'}{'left'} = 0;
$info{'extents'}{'bottom'} = $internal_adjustment_factor * ($top_adjustment + $row->{'bot'} + 0);
$info{'extents'}{'right'} = $internal_adjustment_factor * ($left_adjustment + $row->{'rgt'} + 0);
$query =
"INSERT INTO pmgr_maps (id, name, site_area_id, width, depth) VALUES\n" .
" (1, 'Main Facility Map', $aicur_area_id," .
($info{'extents'}{'right'} - $info{'extents'}{'left'}) . ", " .
($info{'extents'}{'bottom'} - $info{'extents'}{'top'}) . ")";
query($db_handle, $query) || die("Unable to insert");
# Get list of units and positions
$query = "SELECT U.UnitID, U.UnitID as name,";
$query .= " ($top_adjustment + M.Top) AS pt_t,";
$query .= " ($left_adjustment + M.Left) AS pt_l,";
$query .= " IIF(M.reverseWL, U.Depth, U.Width) AS Width,";
$query .= " IIF(M.reverseWL, U.Width, U.Depth) AS Depth,";
$query .= " M.reverseWL, U.Rented, U.Rentable";
$query .= " FROM UnitInfo U INNER JOIN mapUnitsV2 M ON M.unitID = U.UnitID";
$result = query($sdbh, $query);
# Go through each one, calculating the map location
foreach $row (@$result) {
my $uid = $unit_map{$row->{'UnitID'}};
$query = # pt_bottom, pt_right,
"INSERT INTO pmgr_maps_units (map_id, unit_id,
pt_top, pt_left,
transpose) VALUES
(" . join(", ",
1, $uid,
$internal_adjustment_factor * ($row->{'pt_t'}),
$internal_adjustment_factor * ($row->{'pt_l'}),
$row->{'reverseWL'}) . ")";
query($db_handle, $query) || die("Unable to insert");
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## TENANTS
##
######################################################################
## Tenants
$query = "SELECT * FROM TenantInfo WHERE FirstName <> 'POS' ORDER BY TenantID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Tenants\n");
my %stmap = ( 1=>'AK', 14=>'ID', 48=>'WA' );
my (%tenant_map);
foreach $row (@$result) {
$tenant_map{$row->{'TenantID'}} = { 'id' => ++$aicur_c_id };
my $cid = $tenant_map{$row->{'TenantID'}}{'id'};
$query = "INSERT INTO pmgr_contacts
(`id`, `first_name`, `middle_name`, `last_name`, `display_name`, `id_local`, `id_local_state`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($cid, $row->{'FirstName'}, $row->{'MiddleName'}, $row->{'LastName'},
"$row->{'LastName'}, $row->{'FirstName'}",
$row->{'IDNum'} || undef, $row->{'IDNum'} ? $stmap{$row->{'DLStateID'}} : undef)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
if ($row->{'City'}) {
$query = "INSERT INTO pmgr_contact_addresses
(`id`, `address`, `city`, `state`, `postcode`, `country`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(++$aicur_ca_id,
#$row->{'HomeAddress'}
$row->{'HomeAddress'} . ($row->{'HomeAddr2'} ? "\n".$row->{'HomeAddr2'} : "") || undef,
$row->{'City'}, $stmap{$row->{'StateID'}}, $row->{'Zip'} || undef, 'USA')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($cid, 'POST', $aicur_ca_id, 'HOME', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
}
foreach ({'type' => 'LANDLINE', 'preference' => 'PRIMARY', 'phone' => $row->{'Phone'}},
{'type' => 'LANDLINE', 'preference' => 'WORK',
'phone' => $row->{'BusinessPhone'}, 'ext' => $row->{'BusinessExt'}},
{'type' => 'FAX', 'preference' => 'PRIMARY', 'phone' => $row->{'FAX'}},
{'type' => 'PAGER', 'preference' => 'PRIMARY', 'phone' => $row->{'Pager'}},
{'type' => 'MOBILE', 'preference' => 'ALTERNATE', 'phone' => $row->{'CellPhone'}})
{
if ($_->{'phone'}) {
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`, `ext`) VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(++$aicur_cp_id, $_->{'type'}, $_->{'phone'}, $_->{'ext'})))
. ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($cid, 'PHONE', $aicur_cp_id, 'MAIN', $_->{'preference'})))
. ")";
query($db_handle, $query) || die("Unable to insert");
}
}
if ($row->{'Email'}) {
$query = "INSERT INTO pmgr_contact_emails
(`id`, `email`) VALUES
(".++$aicur_ce_id.", '$row->{'Email'}')";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUE
($cid, 'EMAIL', $aicur_ce_id, 'MAIN', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
}
next unless $row->{'AltFirstName'} || $row->{'AltLastName'} || $row->{'AltAddress'} || $row->{'AltPhone'};
$tenant_map{$row->{'TenantID'}}{'alt'} = ++$aicur_c_id;
$cid = $tenant_map{$row->{'TenantID'}}{'alt'};
$query = "INSERT INTO pmgr_contacts
(`id`, `first_name`, `middle_name`, `last_name`, `display_name`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($cid,
$row->{'AltFirstName'} || undef,
$row->{'AltMI'} || undef,
$row->{'AltLastName'} || undef,
($row->{'AltLastName'} && $row->{'AltFirstName'}
? "$row->{'AltLastName'}, $row->{'AltFirstName'}"
: ($row->{'AltLastName'} || $row->{'AltFirstName'} || undef)))
)) . ")";
query($db_handle, $query) || die("Unable to insert");
if ($row->{'AltCity'}) {
$query = "INSERT INTO pmgr_contact_addresses
(`id`, `address`, `city`, `state`, `postcode`, `country`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(++$aicur_ca_id,
$row->{'AltAddress'} . ($row->{'AltAddr2'} ? "\n".$row->{'AltAddr2'} : ""),
$row->{'AltCity'}, $stmap{$row->{'AltStateID'}}, $row->{'AltZip'}, 'USA')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($cid, 'POST', $aicur_ca_id, 'MAIN', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
}
if ($row->{'AltPhone'}) {
$query = "INSERT INTO pmgr_contact_phones
(`id`, `type`, `phone`, `ext`) VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(++$aicur_cp_id, 'LANDLINE', $row->{'AltPhone'}, undef)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_methods
(`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES
($cid, 'PHONE', $aicur_cp_id, 'MAIN', 'PRIMARY')";
query($db_handle, $query) || die("Unable to insert");
}
}
######################################################################
## Tenant Leases
$query = "SELECT L.*, A.TenantID FROM TenantLedger L LEFT JOIN `Access` A ON A.LedgerID = L.LedgerID WHERE L.UnitID <> 'POS\$' ORDER BY L.LedgerID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Tenant Ledgers\n");
my (%ledger_map);
foreach $row (@$result) {
$ledger_map{$row->{'LedgerID'}} = ++$aicur_lease_id;
my $cid = $tenant_map{$row->{'TenantID'}}{'id'};
my $uid = $unit_map{$row->{'UnitID'}};
my $lid = $ledger_map{$row->{'LedgerID'}};
$query = "INSERT INTO pmgr_leases
(`id`, `number`, `lease_type_id`, `unit_id`,
`lease_date`, `movein_date`,
`moveout_date`, `close_date`,
`amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($lid, $row->{'LedgerID'}, $aicur_lease_type_id, $uid,
datefmt($row->{'DateIn'}), datefmt($row->{'DateIn'}),
datefmt($row->{'DateOut'}), datefmt($row->{'DateClosed'}),
$row->{'Rent'})
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_contacts_leases
(`lease_id`, `contact_id`, `type`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($lid, $cid, 'TENANT')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$cid = $tenant_map{$row->{'TenantID'}}{'alt'};
next unless $cid;
$query = "INSERT INTO pmgr_contacts_leases
(`lease_id`, `contact_id`, `type`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($lid, $cid, 'ALTERNATE')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
}
######################################################################
## Security Deposits
$query = "SELECT L.LedgerID, L.UnitID, C.ChargeAmount FROM TenantLedger L INNER JOIN Charges C ON C.LedgerID = L.LedgerID WHERE L.UnitID <> 'POS\$' AND C.ChargeDescription = 'Security Deposit' ORDER BY UnitID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Security Deposits\n");
foreach $row (@$result) {
my $uid = $unit_map{$row->{'UnitID'}};
$query = "UPDATE pmgr_leases
SET deposit = $row->{'ChargeAmount'}
WHERE `number` = '$row->{'LedgerID'}'";
query($db_handle, $query) || die("Unable to update");
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## TRANSACTIONS
##
######################################################################
## Charges
$query = "SELECT * FROM Charges ORDER BY ChargeID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Charges\n");
my %charge_type_map = ('Rent' => 2, 'Security Deposit' => 1, 'Late Fee' => 3);
my %charge_map;
foreach $row (@$result) {
$charge_map{$row->{'ChargeID'}} = ++$aicur_charge_id;
my $lid = $ledger_map{$row->{'LedgerID'}};
my $chid = $charge_map{$row->{'ChargeID'}};
$query = "INSERT INTO pmgr_charges
(`id`, `charge_type_id`, `lease_id`,
`charge_date`, `charge_to_date`,
`amount`, `tax`, `total`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($chid, $charge_type_map{$row->{'ChargeDescription'}}, $lid,
datefmt($row->{'ChargeDate'}), datefmt($row->{'EndDate'}),
$row->{'ChargeAmount'}, $row->{'TaxAmount'},
$row->{'ChargeAmount'} + $row->{'TaxAmount'},
undef)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "UPDATE pmgr_charges";
$query .= " SET due_date = DATE_ADD(charge_date, INTERVAL IF(charge_type_id=2,10,0) DAY)";
query($db_handle, $query) || die("Unable to update");
}
######################################################################
## Receipts
$query = "SELECT * FROM Receipts ORDER BY ReceiptNum";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Receipts\n");
my %receipt_map;
foreach $row (@$result) {
$receipt_map{$row->{'ReceiptNum'}} = ++$aicur_receipt_id;
my $lid = $ledger_map{$row->{'LedgerID'}};
my $rid = $receipt_map{$row->{'ReceiptNum'}};
$query = "INSERT INTO pmgr_receipts
(`id`, `stamp`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($rid, datefmt($row->{'ReceiptDate'}), undef)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
}
# $query = "SELECT * FROM Receipts R INNER JOIN Payments P ON P.ReceiptNum = R.ReceiptNum" .
# " WHERE P.PaymentDate <> R.ReceiptDate";
# $result = query($sdbh, $query);
# $nrows = @$result;
# print(" $nrows Mismatches\n");
# foreach $row (@$result) {
# my @keys = qw(PaymentID P.ReceiptNum PaymentDate ReceiptDate);
# print("Payment Date Mismatch:\n");
# print(" ",
# join("\n ", map({sprintf("%-12s => %s", $_, $row->{$_})} @keys)),
# "\n");
# }
######################################################################
## Payments
$query = "SELECT * FROM Payments ORDER BY PaymentID";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Payments\n");
my %payment_map;
foreach $row (@$result) {
$payment_map{$row->{'PaymentID'}} = ++$aicur_payment_id;
my $pid = $payment_map{$row->{'PaymentID'}};
my $rid = $receipt_map{$row->{'ReceiptNum'}};
my $chid = $charge_map{$row->{'ChargeID'}};
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($pid, $rid,
$row->{'PaymentDate'} =~ m%3/25/2009% ? 8 : $row->{'PaymentType'},
$row->{'PaymentAmount'}, undef)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($chid, $rid, $row->{'PaymentAmount'})
)) . ")";
query($db_handle, $query) || die("Unable to insert");
if ($row->{'Memo'}) {
$query =
"UPDATE pmgr_receipts SET `comment` = '$row->{'Memo'}'" .
" WHERE `id` = $rid";
query($db_handle, $query) || die("Unable to update");
}
}
$query = "INSERT INTO pmgr_charges
(`id`, `charge_type_id`, `lease_id`,
`charge_date`, `charge_to_date`,
`amount`, `tax`, `total`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1000, $charge_type_map{'Security Deposit'}, 17,
'2009-05-05', undef,
10, 0, 10,
'Fake security deposit for testing purposes')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges
(`id`, `charge_type_id`, `lease_id`,
`charge_date`, `charge_to_date`,
`amount`, `tax`, `total`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1001, $charge_type_map{'Rent'}, 17,
'2009-05-01', '2009-05-31',
100, 5, 105,
'Fake charge for testing purposes')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges
(`id`, `charge_type_id`, `lease_id`,
`charge_date`, `charge_to_date`,
`amount`, `tax`, `total`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1002, $charge_type_map{'Late Fee'}, 17,
'2009-05-11', undef,
25, 0, 25,
'Fake late charge for testing purposes')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_receipts
(`id`, `stamp`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(2000, '2009-05-15', 'Fake receipt #1')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3000, 2000, 1, 15, 'Fake receipt #1 payment #1')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3001, 2000, 2, 10, 'Fake receipt #1 payment #2')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3002, 2000, 3, 5, 'Fake receipt #1 payment #3')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1000, 2000, 10)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1001, 2000, 20)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_receipts
(`id`, `stamp`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(2100, '2009-05-18', 'Fake receipt #2')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3100, 2100, 5, 30, 'Fake receipt #2 payment #1')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3101, 2100, 6, 20, 'Fake receipt #2 payment #2')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1001, 2100, 50)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_receipts
(`id`, `stamp`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(2200, '2009-05-22', 'Fake receipt #3')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3200, 2200, 1, 10, 'Fake receipt #3 payment #1')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3201, 2200, 2, 5, 'Fake receipt #3 payment #2')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3202, 2200, 7, 20, 'Fake receipt #3 payment #3')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_payments
(`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(3203, 2200, 8, 15, 'Fake receipt #3 payment #4')
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1001, 2200, 35)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
(1002, 2200, 15)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
__END__
######################################################################
## Reconciliations
# $query = "SELECT ReceiptNum, SUM(PaymentAmount) AS 'rTot'";
# $query .= " FROM Payments GROUP BY ReceiptNum, ORDER BY ReceiptNum";
$query = "SELECT ChargeID, ReceiptNum";
$query .= " FROM Payments GROUP BY ChargeID, ReceiptNum ORDER BY ChargeID, ReceiptNum";
$result = query($sdbh, $query);
$nrows = @$result;
print(" $nrows Reconciliations\n");
foreach $row (@$result) {
my $chid = $charge_map{$row->{'ChargeID'}};
my $rid = $receipt_map{$row->{'ReceiptNum'}};
$query = "INSERT INTO pmgr_charges_receipts
(`charge_id`, `receipt_id`, `amount`)
VALUES (" .
join(", ", map({defined $_ ? "'$_'" : "NULL"}
($chid, $rid, 0)
)) . ")";
query($db_handle, $query) || die("Unable to insert");
}
$query ="UPDATE pmgr_charges_receipts R
JOIN (SELECT P.receipt_id AS rid,
IF(COALESCE(Ch.total, 0)<SUM(P.amount),
COALESCE(Ch.total, 0),
SUM(P.amount)) AS rtot
FROM pmgr_payments P
LEFT JOIN pmgr_charges_receipts Rl ON Rl.receipt_id = P.receipt_id
LEFT JOIN pmgr_charges Ch ON Ch.id = Rl.charge_id
GROUP BY P.receipt_id) Rx ON Rx.rid = R.receipt_id
SET R.amount = Rx.rtot";
query($db_handle, $query) || die("Unable to update");
$query ="UPDATE pmgr_charges_receipts R
JOIN (SELECT P.receipt_id AS rid, P.total AS total
FROM pmgr_payments P
LEFT JOIN pmgr_charges_receipts Rl ON Rl.receipt_id = P.receipt_id
GROUP BY P.receipt_id) Rx ON Rx.rid = R.receipt_id
SET R.amount = Rx.rtot";
query($db_handle, $query) || die("Unable to update");
# SELECT Rs.receipt_id, Rs.rsum, Ps.psum, rids, pids
# FROM
# (SELECT receipt_id, SUM(R.amount) AS rsum, CAST(GROUP_CONCAT(id) AS CHAR) AS rids
# FROM pmgr_charges_receipts R
# GROUP BY receipt_id) Rs
# LEFT JOIN
# (SELECT receipt_id, SUM(P.amount) AS psum, CAST(GROUP_CONCAT(id) AS CHAR) AS pids
# FROM pmgr_payments P
# GROUP BY receipt_id) Ps ON Ps.receipt_id = Rs.receipt_id
# Disconnect from the database.
$db_handle->disconnect();
View File
+54
View File
@@ -0,0 +1,54 @@
<?php
/* SVN FILE: $Id: app_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
/**
* Short description for file.
*
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.app
* @since CakePHP(tm) v 0.2.9
* @version $Revision: 7945 $
* @modifiedby $LastChangedBy: gwoo $
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Short description for class.
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @package cake
* @subpackage cake.app
*/
class AppController extends Controller {
var $helpers = array('Html', 'Number', 'Time');
function sideMenuLinks() {
return array(
array('name' => 'Common', 'header' => true),
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
array('name' => 'Tenants', 'url' => array('controller' => 'contacts', 'action' => 'index')),
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
);
}
function beforeRender() {
$this->set('sidemenu', $this->sideMenuLinks());
}
}
?>
+24 -40
View File
@@ -38,7 +38,8 @@
*/
class AppModel extends Model {
var $actsAs = array('Containable', 'Linkable');
//var $actsAs = array('Containable');
var $actsAs = array('Linkable');
/**
* Get Enum Values
@@ -77,49 +78,32 @@ class AppModel extends Model {
} //end getEnumValues
// Overriding pagination, since the stupid count mechanism blows.
// This is also a crappy solution, especially if the query returns
// a really large number of rows. However, trying to untagle this
// without changing a bunch of core code is near impossible.
/**************************************************************************
**************************************************************************
**************************************************************************
* function: statMerge
* - Merges summary data from $b into $a
*/
function statsMerge (&$a, $b) {
if (!isset($b))
return;
if (!isset($a)) {
$a = $b;
}
elseif (!is_array($a) && !is_array($b)) {
$a += $b;
}
elseif (is_array($a) && is_array($b)) {
foreach (array_intersect_key($a, $b) AS $k => $v)
{
if (preg_match("/^sp\./", $k))
$a[$k] .= '; ' . $b[$k];
else
$this->statsMerge($a[$k], $b[$k]);
}
$a = array_merge($a, array_diff_key($b, $a));
}
else {
die ("Can't yet merge array and non-array stats");
}
var $paginate_rows_save;
function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = null) {
/* pr("paginate"); */
/* pr(array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'extra'))); */
if ($page > 1 && isset($limit))
$offset = ($page - 1) * $limit;
else
$offset = 0;
return array_slice($this->paginate_rows_save, $offset, $limit);
}
function paginateCount($conditions = null, $recursive = null, $extra = null) {
/* pr("paginateCount"); */
/* pr(array_merge(compact('conditions', 'recursive', 'extra'))); */
if (!isset($recursive))
$recursive = $this->recursive;
$parameters = array_merge(compact('conditions', 'recursive'), $extra);
$results = $this->find('all', $parameters);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: dateFormatBeforeSave
* - convert dates to database format
*/
function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString));
$this->paginate_rows_save = $results;
return count($this->paginate_rows_save);
}
}
+127
View File
@@ -0,0 +1,127 @@
<?php
class ChargesController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Charge.id',
'order' => array('Charge.charge_date' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Charges', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'charges', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'charges', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all charges
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared charges
*/
function cleared() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved charges
*/
function unresolved() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all charges
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'ChargeType',
'Receipt',
'Lease' => array('fields' => array('number'))
),
));
$title = 'All Charges';
$this->set('title', $title); $this->set('heading', $title);
$this->set('charges', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific charge
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Charge->Behaviors->attach('Containable');
$this->Charge->contain
(array(// Models
'ChargeType',
'Receipt',
'Lease' => array('fields' => array('number')),
)
);
$charge = $this->Charge->read(null, $id);
//pr($charge);
$payment_amount = 0;
foreach($charge['Receipt'] AS $receipt)
$payment_amount += $receipt['ChargesReceipt']['amount'];
$balance_amount = $charge['Charge']['total'] - $payment_amount;
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'charges', 'action' => 'move-out')); */
$title = 'Charge #' . $charge['Charge']['id'];
$this->set(compact('charge', 'title',
'payment_amount',
'balance_amount'));
}
}
+203
View File
@@ -0,0 +1,203 @@
<?php
class ContactsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Contact.id',
'order' => array('Contact.last_name' => 'ASC',
'Contact.first_name' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Tenants', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')),
array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')),
array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')),
array('name' => 'All Contacts', 'url' => array('controller' => 'contacts', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all current tenants
*/
function index() {
$this->current();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: past
* - Lists all tenants, past and present
*/
function tenants() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Lease' =>
array('fields' => array(),
'type' => 'INNER',
),
),
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE')
));
$title = 'All Tenants';
$this->set('title', $title); $this->set('heading', $title);
$this->set('contacts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: current
* - Lists all current tenants
*/
function current() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Lease' =>
array('fields' => array(),
'type' => 'INNER',
),
),
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE',
'Lease.close_date IS NULL')
));
$title = 'Current Tenants';
$this->set('title', $title); $this->set('heading', $title);
$this->set('contacts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: past
* - Lists all past tenants
*/
function past() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Lease' =>
array('fields' => array(),
'type' => 'INNER',
),
),
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE',
'Lease.close_date IS NOT NULL')
));
$title = 'Past Tenants';
$this->set('title', $title); $this->set('heading', $title);
$this->set('contacts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all contacts, including non-tenants
*/
function all() {
$title = 'All Contacts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('contacts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific contact
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Contact->Behaviors->attach('Containable');
$this->Contact->contain
(array(// Models
'ContactPhone',
'ContactEmail',
'ContactAddress',
'Lease' =>
array('order' => 'movein_date',
'conditions' => array('Lease.lease_date IS NOT NULL',
'ContactsLease.type !=' => 'ALTERNATE'),
// Models
'Unit' =>
array('order' => array('sort_order'),
'fields' => array('id', 'name'),
),
'Charge' =>
array('order' => array('charge_date'),
// Models
'ChargeType',
'Receipt',
)
)
)
);
$contact = $this->Contact->read(null, $id);
$outstanding_deposit = 0;
$outstanding_balance = 0;
foreach($contact['Lease'] AS $lease) {
foreach($lease['Charge'] AS $charge) {
$outstanding_balance += $charge['total'];
foreach ($charge['Receipt'] AS $receipt) {
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
// REVISIT <AP> 20090530:
// Using hardcoded value for security deposit...
// That can't be good!
if ($charge['charge_type_id'] == 1)
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
}
}
}
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
$title = $contact['Contact']['display_name'];
$this->set(compact('contact', 'title',
'outstanding_balance',
'outstanding_deposit'));
}
}
@@ -2,44 +2,22 @@
class MapsController extends AppController {
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index / all
* - Generate a listing of maps
* action: index
* - Generates a list of all site maps
*
* REVISIT <AP> 20090528:
* We'll need to present only those site area maps that correspond
* to the users particular site.
*/
function index() { $this->all(); }
function all() { $this->jqGridView('All Maps', 'all'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* virtuals: jqGridData
* - With the application controller handling the jqGridData action,
* these virtual functions ensure that the correct data is passed
* to jqGrid.
*/
function jqGridDataTables(&$params, &$model) {
return array
('link' => array('SiteArea' => array('fields' => array('SiteArea.id', 'SiteArea.name')),
),
);
function index() {
$this->Map->recursive = 0;
$this->set('maps', $this->paginate());
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Map'] = array('id');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -233,13 +211,9 @@ class MapsController extends AppController {
*/
function image($info, $legend = false) {
$debug = false;
if (!$debug) {
$this->layout = null;
$this->autoLayout = false;
Configure::write('debug', '0');
}
$this->layout = null;
$this->autoLayout = false;
Configure::write('debug', '0');
// Define our color palate
// REVISIT <AP>: 20090513
@@ -280,7 +254,9 @@ class MapsController extends AppController {
$code['fg'] = $component;
}
$this->set(compact('info', 'debug'));
//pr($info);
$this->set(compact('info'));
$this->render('image');
}
+118
View File
@@ -0,0 +1,118 @@
<?php
class PaymentsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Payment.id',
'order' => array('Payment.id' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Payments', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'payments', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'payments', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all payments
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared payments
*/
function cleared() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved payments
*/
function unresolved() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all payments
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'PaymentType',
'Receipt',
),
));
$title = 'All Payments';
$this->set('title', $title); $this->set('heading', $title);
$this->set('payments', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific payment
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Payment->Behaviors->attach('Containable');
$this->Payment->contain
(array(// Models
'PaymentType',
'Receipt',
)
);
$payment = $this->Payment->read(null, $id);
//pr($payment);
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'payments', 'action' => 'move-out')); */
$title = 'Payment #' . $payment['Payment']['id'];
$this->set(compact('payment', 'title'));
}
}
+131
View File
@@ -0,0 +1,131 @@
<?php
class ReceiptsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Receipt.id',
'order' => array('Receipt.stamp' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Receipts', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'receipts', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'receipts', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all receipts
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared receipts
*/
function cleared() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved receipts
*/
function unresolved() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all receipts
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Charge',
'Payment'
),
));
$title = 'All Receipts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('receipts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific receipt
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Receipt->Behaviors->attach('Containable');
$this->Receipt->contain
(array(// Models
'Charge' => array(// Models
'Lease' => array('fields' => array('number')),
'ChargesReceipt',
'ChargeType'),
'Payment' => array(// Models
'PaymentType'),
)
);
$receipt = $this->Receipt->read(null, $id);
//pr($receipt);
$charge_amount = 0;
$payment_amount = 0;
foreach($receipt['Charge'] AS $charge)
$charge_amount += $charge['ChargesReceipt']['amount'];
foreach($receipt['Payment'] AS $payment)
$payment_amount += $payment['amount'];
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'receipts', 'action' => 'move-out')); */
$title = 'Receipt #' . $receipt['Receipt']['id'];
$this->set(compact('receipt', 'title',
'charge_amount',
'payment_amount'));
}
}
+212
View File
@@ -0,0 +1,212 @@
<?php
class UnitsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Unit.id',
'order' => array('Unit.sort_order' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Units', 'header' => true),
array('name' => 'Occupied', 'url' => array('controller' => 'units', 'action' => 'occupied')),
array('name' => 'Vacant', 'url' => array('controller' => 'units', 'action' => 'vacant')),
array('name' => 'Unavailable', 'url' => array('controller' => 'units', 'action' => 'unavailable')),
array('name' => 'All', 'url' => array('controller' => 'units', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all units
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unavailable
* - Lists unavailable units
*/
function unavailable() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
),
'conditions' => $this->Unit->conditionUnavailable()
));
$title = 'Unavailable Units';
$this->set('title', $title); $this->set('heading', $title);
$this->set('units', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: vacant
* - Lists vacant units
*/
function vacant() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
),
'conditions' => $this->Unit->conditionVacant()
));
$title = 'Vacant Units';
$this->set('title', $title); $this->set('heading', $title);
$this->set('units', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: occupied
* - Lists occupied units
*/
function occupied() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
'Lease' => array('fields' => array(),
// Models
'Contact' => array('fields' => array('display_name'),
//'type' => 'LEFT',
),
),
),
'conditions' => $this->Unit->conditionOccupied()
));
$title = 'Occupied Units';
$this->set('title', $title); $this->set('heading', $title);
$this->set('units', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all units
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
),
));
$title = 'All Units';
$this->set('title', $title); $this->set('heading', $title);
$this->set('units', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific unit
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>''));
}
$this->Unit->Behaviors->attach('Containable');
$this->Unit->contain
(array(// Models
'UnitSize',
'Lease' =>
array('order' => 'movein_date',
'conditions' => array('Lease.lease_date IS NOT NULL',
),
// Models
'Contact' =>
array(//'order' => array('sort_order'),
'fields' => array('id', 'display_name'),
),
'Charge' =>
array('order' => array('charge_date'),
// Models
'ChargeType',
'Receipt' => array(// Models
'Payment'
),
)
)
)
);
$unit = $this->Unit->read(null, $id);
//pr($unit);
$outstanding_deposit = 0;
$outstanding_balance = 0;
foreach($unit['Lease'] AS $lease) {
foreach($lease['Charge'] AS $charge) {
$outstanding_balance += $charge['total'];
foreach ($charge['Receipt'] AS $receipt) {
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
/* foreach($receipt['Payment'] AS $payment) */
/* $outstanding_balance -= $payment['amount']; */
// REVISIT <AP> 20090530:
// Using hardcoded value for security deposit...
// That can't be good!
if ($charge['charge_type_id'] == 1)
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
}
}
}
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
$title = 'Unit ' . $unit['Unit']['name'];
$this->set(compact('unit', 'title',
'outstanding_balance',
'outstanding_deposit'));
}
}
View File
+29
View File
@@ -0,0 +1,29 @@
<?php
class Account extends AppModel {
var $name = 'Account';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'external_name' => array('notempty')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'ChargeType' => array(
'className' => 'ChargeType',
'foreignKey' => 'account_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>
+193
View File
@@ -0,0 +1,193 @@
<?php
/*
* LinkableBehavior
* Light-weight approach for data mining on deep relations between models.
* Join tables based on model relations to easily enable right to left find operations.
*
* Can be used as a alternative to the ContainableBehavior:
* - On data fetching only in right to left operations,
* wich means that in "one to many" relations (hasMany, hasAndBelongsToMany)
* should only be used from the "many to one" tables. i.e:
* To fetch all Users assigneds to a Project with ProjectAssignment,
* $Project->find('all', array('link' => 'User', 'conditions' => 'project_id = 1'))
* - Won't produce the desired result as data came from users table will be lost.
* $User->find('all', array('link' => 'Project', 'conditions' => 'project_id = 1'))
* - Will fetch all users related to the specified project in one query
*
* - On data mining as a much lighter approach - can reduce 300+ query find operations
* in one single query with joins; "or your money back!" ;-)
*
* - Has the 'fields' param enabled to make it easy to replace Containable usage,
* only change the 'contain' param to 'link'.
*
* Linkable Behavior. Taking it easy in your DB.
* RafaelBandeira <rafaelbandeira3(at)gmail(dot)com>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @version 1.0;
*/
class LinkableBehavior extends ModelBehavior {
protected $_key = 'link';
protected $_options = array(
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
'conditions' => true, 'fields' => true, 'reference' => true,
'class' => true, 'defaults' => true
);
protected $_defaults = array('type' => 'LEFT');
public function beforeFind(&$Model, $query) {
/* pr("Linkable::beforeFind() begin"); pr($query); */
if (isset($query[$this->_key])) {
$optionsDefaults = $this->_defaults + array('reference' => $Model->alias, $this->_key => array());
$optionsKeys = $this->_options + array($this->_key => true);
if (!isset($query['fields']) || $query['fields'] === true) {
//$query['fields'] = array_keys($Model->_schema);
$query['fields'] = $Model->getDataSource()->fields($Model);
} elseif (!is_array($query['fields'])) {
$query['fields'] = array($query['fields']);
}
$query = am(array('joins' => array()), $query, array('recursive' => -1));
$iterators[] = $query[$this->_key];
$cont = 0;
do {
$iterator = $iterators[$cont];
$defaults = $optionsDefaults;
if (isset($iterator['defaults'])) {
$defaults = array_merge($defaults, $iterator['defaults']);
unset($iterator['defaults']);
}
$iterations = Set::normalize($iterator);
foreach ($iterations as $alias => $options) {
if (is_null($options)) {
$options = array();
}
$options = am($defaults, compact('alias'), $options);
if (empty($options['alias'])) {
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
}
if (empty($options['table']) && empty($options['class'])) {
$options['class'] = $options['alias'];
} elseif (!empty($options['table']) && empty($options['class'])) {
$options['class'] = Inflector::classify($options['table']);
}
$_Model =& ClassRegistry::init($options['class']); // the incoming model to be linked in query
$Reference =& ClassRegistry::init($options['reference']); // the already in query model that links to $_Model
/* pr("_Model: $options[class] : $_Model->name ($_Model->alias)"); */
/* pr("Reference: $options[reference] : $Reference->name ($Reference->alias)"); */
$db =& $_Model->getDataSource();
$associations = $_Model->getAssociated();
if (isset($associations[$Reference->alias])) {
$type = $associations[$Reference->alias];
$association = $_Model->{$type}[$Reference->alias];
} else {
$_Model->bind($Reference->alias);
$type = 'belongsTo';
$association = $_Model->{$type}[$Reference->alias];
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
}
if (empty($options['conditions'])) {
if ($type === 'belongsTo') {
$modelKey = $_Model->escapeField($association['foreignKey']);
$referenceKey = $Reference->escapeField($Reference->primaryKey);
$options['conditions'] = "{$referenceKey} = {$modelKey}";
} elseif ($type === 'hasAndBelongsToMany') {
if (isset($association['with']))
$Link =& $_Model->{$association['with']};
else
$Link =& $_Model->{Inflector::classify($association['joinTable'])};
$linkAlias = $Link->alias;
//$linkAlias = $Link->alias . $options['alias'];
// Get the foreign key fields (for the link table) directly from
// the defined model associations, if they exists. This is the
// users direct specification, and therefore definitive if present.
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
$referenceLink = $Link->escapeField($association['associationForeignKey'], $linkAlias);
// If we haven't figured out the foreign keys, see if there is a
// model for the link table, and if it has the appropriate
// associations with the two tables we're trying to join.
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
// We're running quite thin here. None of the models spell
// out the appropriate linkages. We'll have to SWAG it.
if (empty($modelLink))
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
if (empty($referenceLink))
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
// Get the primary key from the tables we're joining.
$referenceKey = $Reference->escapeField();
$modelKey = $_Model->escapeField();
// Join the linkage table to our model. We'll use an inner join,
// as the whole purpose of the linkage table is to make this
// connection. As we are embedding this join, the INNER will not
// cause any problem with the overall query, should the user not
// be concerned with whether or not the join has any results.
// They control that with the 'type' parameter which will be at
// the top level join.
$options['joins'][] = array('type' => 'INNER',
'alias' => $options['alias'],
'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true));
// The user may have specified conditions directly in the model
// for this join. Make sure to adhere to those conditions.
if (isset($association['conditions']) && is_array($association['conditions']))
$options['conditions'] = $association['conditions'];
elseif (!empty($association['conditions']))
$options['conditions'] = array($association['conditions']);
// Now for the top level join. This will be added into the list
// of joins down below, outside of the HABTM specific code.
$options['alias'] = $linkAlias;
$options['table'] = $Link->getDataSource()->fullTableName($Link);
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
} else {
$referenceKey = $Reference->escapeField($association['foreignKey']);
$modelKey = $_Model->escapeField($_Model->primaryKey);
$options['conditions'] = "{$modelKey} = {$referenceKey}";
}
}
if (empty($options['table'])) {
$options['table'] = $db->fullTableName($_Model, true);
}
if (!isset($options['fields']) || !is_array($options['fields']))
$options['fields'] = $db->fields($_Model);
elseif (!empty($options['fields']))
$options['fields'] = $db->fields($_Model, null, $options['fields']);
$query['fields'] = array_merge($query['fields'], $options['fields'],
(empty($association['fields'])
? array() : $db->fields($_Model, null, $association['fields'])));
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
$options = array_intersect_key($options, $optionsKeys);
if (!empty($options[$this->_key])) {
$iterators[] = $options[$this->_key] + array('defaults' => array_merge($defaults, array('reference' => $options['class'])));
}
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
}
++$cont;
$notDone = isset($iterators[$cont]);
} while ($notDone);
}
/* pr("Linkable::beforeFind() end"); pr($query); */
return $query;
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
class Charge extends AppModel {
var $name = 'Charge';
var $validate = array(
'id' => array('numeric'),
'charge_type_id' => array('numeric'),
'lease_id' => array('numeric'),
'charge_date' => array('date'),
'charge_to_date' => array('date'),
'due_date' => array('date'),
'amount' => array('money'),
'tax' => array('money'),
'total' => array('money')
);
var $belongsTo = array(
'ChargeType' => array(
'className' => 'ChargeType',
'foreignKey' => 'charge_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Lease' => array(
'className' => 'Lease',
'foreignKey' => 'lease_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasAndBelongsToMany = array(
'Receipt' => array(
'className' => 'Receipt',
'joinTable' => 'charges_receipts',
'foreignKey' => 'charge_id',
'associationForeignKey' => 'receipt_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}
?>
+39
View File
@@ -0,0 +1,39 @@
<?php
class ChargeType extends AppModel {
var $name = 'ChargeType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'account_id' => array('numeric')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/* var $belongsTo = array( */
/* 'Account' => array( */
/* 'className' => 'Account', */
/* 'foreignKey' => 'account_id', */
/* 'conditions' => '', */
/* 'fields' => '', */
/* 'order' => '' */
/* ) */
/* ); */
var $hasMany = array(
'Charge' => array(
'className' => 'Charge',
'foreignKey' => 'charge_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>
+76
View File
@@ -0,0 +1,76 @@
<?php
class Contact extends AppModel {
var $name = 'Contact';
var $validate = array(
'id' => array('numeric'),
'display_name' => array('notempty'),
'id_federal' => array('ssn'),
'id_exp' => array('date')
);
var $hasAndBelongsToMany = array(
'Lease' => array(
'className' => 'Lease',
'joinTable' => 'contacts_leases',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'lease_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'ContactAddress' => array(
'className' => 'ContactAddress',
'joinTable' => 'contacts_methods',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'POST'",
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'ContactPhone' => array(
'className' => 'ContactPhone',
'joinTable' => 'contacts_methods',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'PHONE'",
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'ContactEmail' => array(
'className' => 'ContactEmail',
'joinTable' => 'contacts_methods',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'method_id',
'unique' => true,
'conditions' => "method = 'EMAIL'",
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
);
}
?>
@@ -15,6 +15,13 @@ class ContactAddress extends AppModel {
'associationForeignKey' => 'contact_id',
'unique' => true,
'conditions' => "method = 'POST'",
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}

Some files were not shown because too many files have changed in this diff Show More