Updated libraries to latest version
This commit is contained in:
parent
8b4eacd1e1
commit
baad9f58c1
|
@ -1,4 +1,6 @@
|
||||||
configuration.inc
|
configuration.inc
|
||||||
|
site_config.inc
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
data/sessions/*
|
data/sessions/*
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
[submodule "html/js/yui3"]
|
[submodule "html/js/yui3"]
|
||||||
path = html/js/yui3
|
path = html/js/yui3
|
||||||
url = https://github.com/yui/yui3.git
|
url = https://github.com/yui/yui3.git
|
||||||
|
[submodule "libraries/phpCAS"]
|
||||||
|
path = libraries/phpCAS
|
||||||
|
url = https://github.com/Jasig/phpCAS.git
|
||||||
|
[submodule "libraries/zf2"]
|
||||||
|
path = libraries/zf2
|
||||||
|
url = https://github.com/zendframework/zf2.git
|
||||||
|
|
|
@ -1,45 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Used to keep sessions on the same webserver seperate;
|
|
||||||
*/
|
|
||||||
define('APPLICATION_NAME','application_name');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where on the filesystem this application is installed
|
* Where on the filesystem this application is installed
|
||||||
*/
|
*/
|
||||||
define('APPLICATION_HOME','/var/www/sites/application_name');
|
define('APPLICATION_HOME', __DIR__);
|
||||||
|
define('BLOSSOM', APPLICATION_HOME.'/libraries/Blossom');
|
||||||
|
define('ZEND', APPLICATION_HOME.'/libraries/zf2/library/Zend');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where on the filesystem the framework is installed.
|
* Multi-Site support
|
||||||
*/
|
|
||||||
define('FRAMEWORK',APPLICATION_HOME.'/libraries/framework');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This needs to point to the library directory inside your
|
|
||||||
* installation of the ZendFramework
|
|
||||||
* http://framework.zend.com
|
|
||||||
*/
|
|
||||||
define('ZEND',APPLICATION_HOME.'/libraries/ZendFramework/library');
|
|
||||||
ini_set('include_path','.'.PATH_SEPARATOR.ZEND);
|
|
||||||
require_once 'Zend/Loader/Autoloader.php';
|
|
||||||
Zend_Loader_Autoloader::getInstance();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL to get to this site
|
|
||||||
* Do NOT use a trailing slash
|
|
||||||
*/
|
|
||||||
define('BASE_URL','http://localhost/application_name');
|
|
||||||
define('BASE_URI', '/application_name');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used when there's an error on the site. The Framework will
|
|
||||||
* print out a nice error message, encouraging users to report any problems
|
|
||||||
* See: FRAMEWORK/ITSFunctions.inc
|
|
||||||
*
|
*
|
||||||
* This is also the default Admin user information that gets added to the database
|
* To allow multiple sites to use this same install base,
|
||||||
|
* define the SITE_HOME variable in the Apache config for each
|
||||||
|
* site you want to host.
|
||||||
|
*
|
||||||
|
* SITE_HOME is the directory where all site-specific data and
|
||||||
|
* configuration are stored. For backup purposes, backing up this
|
||||||
|
* directory would be sufficient for an easy full restore.
|
||||||
*/
|
*/
|
||||||
define('ADMINISTRATOR_NAME','Site Admin');
|
define('SITE_HOME', !empty($_SERVER['SITE_HOME']) ? $_SERVER['SITE_HOME'] : __DIR__.'/data');
|
||||||
define('ADMINISTRATOR_EMAIL','admin@servername.com');
|
include SITE_HOME.'/site_config.inc';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set how we want to handle errors
|
* Set how we want to handle errors
|
||||||
|
@ -47,7 +26,7 @@ define('ADMINISTRATOR_EMAIL','admin@servername.com');
|
||||||
*
|
*
|
||||||
* If you do not define error handling to PHP_DEFAULT
|
* If you do not define error handling to PHP_DEFAULT
|
||||||
* the custom error handlers kick in. All of the custom error display
|
* the custom error handlers kick in. All of the custom error display
|
||||||
* frunctions are in FRAMEWORK/globalFunctions.inc. The custom error
|
* frunctions are in BLOSSOM/Classes/Error.php. The custom error
|
||||||
* function decide what to do based on $ERROR_REPORING array values
|
* function decide what to do based on $ERROR_REPORING array values
|
||||||
*
|
*
|
||||||
* PRETTY_PRINT - Display a message in the browser
|
* PRETTY_PRINT - Display a message in the browser
|
||||||
|
@ -58,6 +37,7 @@ define('ADMINISTRATOR_EMAIL','admin@servername.com');
|
||||||
define('ERROR_REPORTING','PHP_DEFAULT');
|
define('ERROR_REPORTING','PHP_DEFAULT');
|
||||||
//define('ERROR_REPORTING','CUSTOM');
|
//define('ERROR_REPORTING','CUSTOM');
|
||||||
//$ERROR_REPORTING = array('PRETTY_PRINT','SKIDDER');
|
//$ERROR_REPORTING = array('PRETTY_PRINT','SKIDDER');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skidder is a web service for error notifications. Error reporting supports
|
* Skidder is a web service for error notifications. Error reporting supports
|
||||||
* posting errors to a Skidder server. You must register for an application_id
|
* posting errors to a Skidder server. You must register for an application_id
|
||||||
|
@ -66,46 +46,24 @@ define('ERROR_REPORTING','PHP_DEFAULT');
|
||||||
//define('SKIDDER_URL','http://localhost/skidder/home.php');
|
//define('SKIDDER_URL','http://localhost/skidder/home.php');
|
||||||
//define('SKIDDER_APPLICATION_ID',);
|
//define('SKIDDER_APPLICATION_ID',);
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Bootstrap code
|
||||||
|
// No editing is usually needed after this point
|
||||||
|
//-------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Database Setup
|
* Enable autoloading for the PHP libraries
|
||||||
* Refer to the PDO documentation for DSN sytnax for your database type
|
|
||||||
* http://www.php.net/manual/en/pdo.drivers.php
|
|
||||||
*/
|
*/
|
||||||
define('DB_ADAPTER','Pdo_Mysql');
|
require_once ZEND.'/Loader/AutoloaderFactory.php';
|
||||||
define('DB_HOST','localhost');
|
$config = [
|
||||||
define('DB_NAME',APPLICATION_NAME);
|
'Zend\Loader\StandardAutoloader' => [
|
||||||
define('DB_USER',APPLICATION_NAME);
|
'namespaces' => [
|
||||||
define('DB_PASS','password');
|
'Application' => APPLICATION_HOME,
|
||||||
|
'Blossom' => BLOSSOM,
|
||||||
/**
|
'Zend' => ZEND
|
||||||
* Directory Configuration
|
]
|
||||||
*
|
]
|
||||||
* This is required in order to use the LDAP or ADS authentication
|
];
|
||||||
* If you do not want to use external authentication, you can comment this out
|
Zend\Loader\AutoloaderFactory::factory($config);
|
||||||
*/
|
|
||||||
// Example for ADS style authentication
|
|
||||||
define('DIRECTORY_SERVER','ldaps://example.org:636');
|
|
||||||
define('DIRECTORY_BASE_DN','OU=Department,DC=example,DC=org');
|
|
||||||
define('DIRECTORY_USERNAME_ATTRIBUTE', 'CN');
|
|
||||||
define('DIRECTORY_USER_BINDING','{username}@bloomington.in.gov');
|
|
||||||
define('DIRECTORY_ADMIN_BINDING', 'admin@bloomington.in.gov');
|
|
||||||
define('DIRECTORY_ADMIN_PASS','password');
|
|
||||||
// Example for LDAP style authentication
|
|
||||||
//define('DIRECTORY_SERVER','ldaps://example.org:636');
|
|
||||||
//define('DIRECTORY_BASE_DN','ou=people,o=ldap.domain.somewhere');
|
|
||||||
//define('DIRECTORY_USERNAME_ATTRIBUTE', 'uid');
|
|
||||||
//define('DIRECTORY_USER_BINDING','uid={username},'.DIRECTORY_BASE_DN);
|
|
||||||
//define('DIRECTORY_ADMIN_BINDING', 'uid=admin,'.DIRECTORY_BASE_DN);
|
|
||||||
//define('DIRECTORY_ADMIN_PASS','password');
|
|
||||||
|
|
||||||
define('YUI', BASE_URI.'/js/yui3/build');
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import global functions that we use for many applications we write
|
|
||||||
*/
|
|
||||||
include FRAMEWORK.'/globalFunctions.php';
|
|
||||||
spl_autoload_register('autoload');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session Startup
|
* Session Startup
|
||||||
|
@ -113,27 +71,21 @@ spl_autoload_register('autoload');
|
||||||
* We only want sessions when PHP code is executed from the webserver
|
* We only want sessions when PHP code is executed from the webserver
|
||||||
*/
|
*/
|
||||||
if (!defined('STDIN')) {
|
if (!defined('STDIN')) {
|
||||||
ini_set('session.save_path',APPLICATION_HOME.'/data/sessions');
|
ini_set('session.save_path', SITE_HOME.'/sessions');
|
||||||
session_start();
|
session_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
||||||
* CAS authentication http://www.jasig.org/cas
|
set_error_handler ('Blossom\Classes\Error::customErrorHandler');
|
||||||
*
|
set_exception_handler('Blossom\Classes\Error::customExceptionHandler');
|
||||||
* https://wiki.jasig.org/display/CASC/phpCAS
|
}
|
||||||
*
|
|
||||||
* phpCAS is a PHP library for handling the calls to the CAS service
|
|
||||||
* It is the official library, part of the Jasig CAS project
|
|
||||||
*/
|
|
||||||
define('CAS', APPLICATION_HOME.'/libraries/phpCAS');
|
|
||||||
define('CAS_SERVER','cas.somewhere.org');
|
|
||||||
define('CAS_URI','cas');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the Zend_Acl
|
* Load the Zend_Acl
|
||||||
* Access control is going to handled using the Zend_Acl
|
|
||||||
* We only need to load it, if someone is logged in
|
|
||||||
*/
|
*/
|
||||||
if (isset($_SESSION['USER'])) {
|
include APPLICATION_HOME.'/access_control.inc';
|
||||||
include APPLICATION_HOME.'/access_control.inc';
|
|
||||||
}
|
/**
|
||||||
|
* Grab a timestamp for calculating process time
|
||||||
|
*/
|
||||||
|
$startTime = microtime(1);
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
define('APPLICATION_NAME','application');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to get to this site
|
||||||
|
* Do NOT use a trailing slash
|
||||||
|
*/
|
||||||
|
define('BASE_URL','http://localhost/application');
|
||||||
|
define('BASE_URI','/application');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when there's an error on the site. The Framework will
|
||||||
|
* print out a nice error message, encouraging users to report any problems
|
||||||
|
* See: Blossom\Classes\Error
|
||||||
|
*/
|
||||||
|
define('ADMINISTRATOR_NAME','Site Admin');
|
||||||
|
define('ADMINISTRATOR_EMAIL','admin@servername.com');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Setup
|
||||||
|
* Refer to the PDO documentation for DSN sytnax for your database type
|
||||||
|
* http://www.php.net/manual/en/pdo.drivers.php
|
||||||
|
*/
|
||||||
|
define('DB_ADAPTER','Pdo_Mysql');
|
||||||
|
define('DB_HOST','localhost');
|
||||||
|
define('DB_NAME','application');
|
||||||
|
define('DB_USER','application');
|
||||||
|
define('DB_PASS','password');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory Configuration
|
||||||
|
*
|
||||||
|
* This supports doing user authentication from multiple external
|
||||||
|
* directories, such as LDAP or ADS. This is required since city staff
|
||||||
|
* are in a seperate LDAP directory from public user accounts.
|
||||||
|
* Classes that implement ExternalIdentity should have an entry here.
|
||||||
|
*
|
||||||
|
* See: ExternalIdentity
|
||||||
|
*/
|
||||||
|
// Example for ADS style authentication
|
||||||
|
$DIRECTORY_CONFIG = array(
|
||||||
|
// 'Employee'=>array(
|
||||||
|
// 'DIRECTORY_SERVER'=>'ldaps://example.org:636',
|
||||||
|
// 'DIRECTORY_BASE_DN'=>'OU=Department,DC=example,DC=org',
|
||||||
|
// 'DIRECTORY_USERNAME_ATTRIBUTE'=>'CN',
|
||||||
|
// 'DIRECTORY_USER_BINDING'=>'{username}@example.org',
|
||||||
|
// 'DIRECTORY_ADMIN_BINDING'=>'admin@example.org',
|
||||||
|
// 'DIRECTORY_ADMIN_PASS'=>'password'
|
||||||
|
// )
|
||||||
|
);
|
||||||
|
// Example for LDAP style authentication
|
||||||
|
//$DIRECTORY_CONFIG = array(
|
||||||
|
// 'Employee'=>array(
|
||||||
|
// 'DIRECTORY_SERVER'=>'ldaps://example.org:636');
|
||||||
|
// 'DIRECTORY_BASE_DN'=>'ou=people,o=ldap.domain.somewhere');
|
||||||
|
// 'DIRECTORY_USERNAME_ATTRIBUTE'=>'uid');
|
||||||
|
// 'DIRECTORY_USER_BINDING'=>'uid={username},'.DIRECTORY_BASE_DN);
|
||||||
|
// 'DIRECTORY_ADMIN_BINDING'=>'uid=admin,'.DIRECTORY_BASE_DN);
|
||||||
|
// 'DIRECTORY_ADMIN_PASS'=>'password');
|
||||||
|
// )
|
||||||
|
//);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CAS authentication http://www.jasig.org/cas
|
||||||
|
*
|
||||||
|
* https://wiki.jasig.org/display/CASC/phpCAS
|
||||||
|
*
|
||||||
|
* phpCAS is a PHP library for handling the calls to the CAS service
|
||||||
|
* It is the official library, part of the Jasig CAS project
|
||||||
|
*/
|
||||||
|
//define('CAS',APPLICATION_HOME.'/libraries/phpCAS');
|
||||||
|
//define('CAS_SERVER','cas.somewhere.org');
|
||||||
|
//define('CAS_URI','cas');
|
||||||
|
|
||||||
|
define('DATE_FORMAT', 'n/j/Y H:i:s');
|
||||||
|
define('YUI', BASE_URI.'/js/yui3/build');
|
|
@ -0,0 +1,212 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2011-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
use Zend\Db\Sql\Sql;
|
||||||
|
|
||||||
|
abstract class ActiveRecord
|
||||||
|
{
|
||||||
|
protected $tablename;
|
||||||
|
protected $data = array();
|
||||||
|
|
||||||
|
const MYSQL_DATE_FORMAT = 'Y-m-d H:i:s';
|
||||||
|
|
||||||
|
abstract public function validate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from TableGateway
|
||||||
|
*/
|
||||||
|
public function exchangeArray($data)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the database back to the database
|
||||||
|
*/
|
||||||
|
protected function save()
|
||||||
|
{
|
||||||
|
$this->validate();
|
||||||
|
$zend_db = Database::getConnection();
|
||||||
|
$sql = new Sql($zend_db, $this->tablename);
|
||||||
|
if ($this->getId()) {
|
||||||
|
$update = $sql->update()
|
||||||
|
->set($this->data)
|
||||||
|
->where(array('id'=>$this->getId()));
|
||||||
|
$sql->prepareStatementForSqlObject($update)->execute();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$insert = $sql->insert()->values($this->data);
|
||||||
|
$sql->prepareStatementForSqlObject($insert)->execute();
|
||||||
|
$this->data['id'] = $zend_db->getDriver()->getLastGeneratedValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this record from the database
|
||||||
|
*/
|
||||||
|
protected function delete()
|
||||||
|
{
|
||||||
|
if ($this->getId()) {
|
||||||
|
$sql = new Sql(Database::getConnection(), $this->tablename);
|
||||||
|
$delete = $sql->delete()->where(['id'=>$this->getId()]);
|
||||||
|
$sql->prepareStatementForSqlObject($delete)->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns any field stored in $data
|
||||||
|
*
|
||||||
|
* @param string $fieldname
|
||||||
|
*/
|
||||||
|
protected function get($fieldname)
|
||||||
|
{
|
||||||
|
if (isset($this->data[$fieldname])) {
|
||||||
|
return $this->data[$fieldname];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fieldname
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
protected function set($fieldname, $value)
|
||||||
|
{
|
||||||
|
$value = trim($value);
|
||||||
|
$this->data[$fieldname] = $value ? $value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date/time in the desired format
|
||||||
|
*
|
||||||
|
* Format is specified using PHP's date() syntax
|
||||||
|
* http://www.php.net/manual/en/function.date.php
|
||||||
|
* If no format is given, the database's raw data is returned
|
||||||
|
*
|
||||||
|
* @param string $field
|
||||||
|
* @param string $format
|
||||||
|
* @param DateTimeZone $timezone
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getDateData($dateField, $format=null, \DateTimeZone $timezone=null)
|
||||||
|
{
|
||||||
|
if (isset($this->data[$dateField])) {
|
||||||
|
if ($format) {
|
||||||
|
$date = new \DateTime($this->data[$dateField]);
|
||||||
|
if ($timezone) { $date->setTimezone($timezone); }
|
||||||
|
return $date->format($format);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $this->data[$dateField];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a date
|
||||||
|
*
|
||||||
|
* Dates should be in DATE_FORMAT, set in configuration.inc
|
||||||
|
* If we cannot parse the string using DATE_FORMAT, we will
|
||||||
|
* fall back to trying something strtotime() understands
|
||||||
|
* http://www.php.net/manual/en/function.strtotime.php
|
||||||
|
*
|
||||||
|
* @param string $dateField
|
||||||
|
* @param string $date
|
||||||
|
*/
|
||||||
|
protected function setDateData($dateField, $date)
|
||||||
|
{
|
||||||
|
$date = trim($date);
|
||||||
|
if ($date) {
|
||||||
|
$d = \DateTime::createFromFormat(DATE_FORMAT, $date);
|
||||||
|
if (!$d) {
|
||||||
|
try {
|
||||||
|
$d = new \DateTime($date);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
throw new \Exception('unknownDateFormat');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->data[$dateField] = $d->format(self::MYSQL_DATE_FORMAT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->data[$dateField] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and returns an object for a foreign key _id field
|
||||||
|
*
|
||||||
|
* Will cache the object in a protected variable to avoid multiple database
|
||||||
|
* lookups. Make sure to declare a protected variable matching the class
|
||||||
|
*
|
||||||
|
* @param string $class Fully namespaced classname
|
||||||
|
* @param string $field
|
||||||
|
*/
|
||||||
|
protected function getForeignKeyObject($class, $field)
|
||||||
|
{
|
||||||
|
$var = preg_replace('/_id$/', '', $field);
|
||||||
|
if (!$this->$var && isset($this->data[$field])) {
|
||||||
|
$this->$var = new $class($this->data[$field]);
|
||||||
|
}
|
||||||
|
return $this->$var;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies and saves the ID for a foreign key field
|
||||||
|
*
|
||||||
|
* Loads the object record for the foreign key and caches
|
||||||
|
* the object in a private variable
|
||||||
|
*
|
||||||
|
* @param string $class Fully namespaced classname
|
||||||
|
* @param string $field Name of field to set
|
||||||
|
* @param string $id The value to set
|
||||||
|
*/
|
||||||
|
protected function setForeignKeyField($class, $field, $id)
|
||||||
|
{
|
||||||
|
$id = trim($id);
|
||||||
|
$var = preg_replace('/_id$/', '', $field);
|
||||||
|
if ($id) {
|
||||||
|
$this->$var = new $class($id);
|
||||||
|
$this->data[$field] = $this->$var->getId();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->$field = null;
|
||||||
|
$this->data[$field] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies and saves the ID for a foreign key object
|
||||||
|
*
|
||||||
|
* Caches the object in a private variable and sets
|
||||||
|
* the ID value in the data
|
||||||
|
*
|
||||||
|
* @param string $class Fully namespaced classname
|
||||||
|
* @param string $field Name of field to set
|
||||||
|
* @param Object $object Value to set
|
||||||
|
*/
|
||||||
|
protected function setForeignKeyObject($class, $field, $object)
|
||||||
|
{
|
||||||
|
if ($object instanceof $class) {
|
||||||
|
$var = preg_replace('/_id$/', '', $field);
|
||||||
|
$this->data[$field] = $object->getId();
|
||||||
|
$this->$var = $object;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('Object does not match the given class');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the value can be an ID for a record
|
||||||
|
*
|
||||||
|
* return @bool
|
||||||
|
*/
|
||||||
|
public static function isId($id)
|
||||||
|
{
|
||||||
|
return ((is_int($id) && $id>0) || (is_string($id) && ctype_digit($id)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Represents a block of content in a template
|
||||||
|
*
|
||||||
|
* Blocks are partial view scripts.
|
||||||
|
* They are contained in APPLICATION/blocks
|
||||||
|
* They are organized by $outputFormat
|
||||||
|
* APPLICATION_HOME/blocks/html/...
|
||||||
|
* APPLICATION_HOME/blocks/xml/...
|
||||||
|
* APPLICATION_HOME/blocks/json/..
|
||||||
|
*
|
||||||
|
* @copyright 2006-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class Block extends View
|
||||||
|
{
|
||||||
|
private $file;
|
||||||
|
private $template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establishes the block script to use for rendering
|
||||||
|
*
|
||||||
|
* Blocks are files contained in the base path of:
|
||||||
|
* APPLICATION_HOME/blocks/$outpuform
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param array $vars An associative array of variables to set
|
||||||
|
*/
|
||||||
|
public function __construct($file,array $vars=null)
|
||||||
|
{
|
||||||
|
parent::__construct($vars);
|
||||||
|
|
||||||
|
$this->file = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes the block script and returns the output as a string
|
||||||
|
*
|
||||||
|
* We allow for passing the Template that this block is being rendered in.
|
||||||
|
* This allows the blocks to update information in the template on the fly.
|
||||||
|
* This is most commonly used in adding script urls to the Template
|
||||||
|
*
|
||||||
|
* @param string $outputFormat
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render($outputFormat='html', Template $template=null)
|
||||||
|
{
|
||||||
|
$block = "/blocks/$outputFormat/{$this->file}";
|
||||||
|
$this->template = $template;
|
||||||
|
|
||||||
|
if (is_file(SITE_HOME.$block)) {
|
||||||
|
$file = SITE_HOME.$block;
|
||||||
|
}
|
||||||
|
elseif (is_file(APPLICATION_HOME.$block)) {
|
||||||
|
$file = APPLICATION_HOME.$block;
|
||||||
|
}
|
||||||
|
elseif (is_file(BLOSSOM.$block)) {
|
||||||
|
$file = BLOSSOM.$block;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('unknownBlock/'.$this->file);
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include $file;
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFile()
|
||||||
|
{
|
||||||
|
return $this->file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes the given filename.
|
||||||
|
*
|
||||||
|
* Supports SITE_HOME overriding.
|
||||||
|
* Specify a relative path starting from /blocks/
|
||||||
|
* $file paths should not start with a slash.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*/
|
||||||
|
public function _include($file)
|
||||||
|
{
|
||||||
|
if (is_file(SITE_HOME."/blocks/$file")) {
|
||||||
|
include SITE_HOME."/blocks/$file";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
include APPLICATION_HOME."/blocks/$file";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2012-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
abstract class Controller
|
||||||
|
{
|
||||||
|
protected $template;
|
||||||
|
|
||||||
|
abstract public function index();
|
||||||
|
|
||||||
|
public function __construct(Template &$template)
|
||||||
|
{
|
||||||
|
$this->template = $template;
|
||||||
|
$this->template->controller = get_class($this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,13 @@
|
||||||
/**
|
/**
|
||||||
* Singleton for the Database connection
|
* Singleton for the Database connection
|
||||||
*
|
*
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
* @copyright 2006-2013 City of Bloomington, Indiana
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
*/
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
use Zend\Db\Adapter\Adapter;
|
||||||
|
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
private static $connection;
|
private static $connection;
|
||||||
|
@ -21,13 +24,13 @@ class Database
|
||||||
}
|
}
|
||||||
if (!self::$connection) {
|
if (!self::$connection) {
|
||||||
try {
|
try {
|
||||||
$parameters = array('host'=>DB_HOST,
|
$parameters = array('driver' =>DB_ADAPTER,
|
||||||
|
'hostname'=>DB_HOST,
|
||||||
'username'=>DB_USER,
|
'username'=>DB_USER,
|
||||||
'password'=>DB_PASS,
|
'password'=>DB_PASS,
|
||||||
'dbname'=>DB_NAME,
|
'database' =>DB_NAME,
|
||||||
'options'=>array(Zend_Db::AUTO_QUOTE_IDENTIFIERS=>false));
|
'charset' =>'utf8');
|
||||||
self::$connection = Zend_Db::factory(DB_ADAPTER,$parameters);
|
self::$connection = new Adapter($parameters);
|
||||||
self::$connection->getConnection();
|
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
die($e->getMessage());
|
die($e->getMessage());
|
|
@ -0,0 +1,122 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* A class for working with entries in LDAP.
|
||||||
|
*
|
||||||
|
* This class is written specifically for the City of Bloomington's
|
||||||
|
* LDAP layout. If you are going to be doing LDAP authentication
|
||||||
|
* with your own LDAP server, you will probably need to customize
|
||||||
|
* the fields used in this class.
|
||||||
|
*
|
||||||
|
* @copyright 2011-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class Employee implements ExternalIdentity
|
||||||
|
{
|
||||||
|
private static $connection;
|
||||||
|
private $config;
|
||||||
|
private $entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $config
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function authenticate($username,$password)
|
||||||
|
{
|
||||||
|
global $DIRECTORY_CONFIG;
|
||||||
|
$config = $DIRECTORY_CONFIG['Employee'];
|
||||||
|
|
||||||
|
$bindUser = sprintf(str_replace('{username}','%s',$config['DIRECTORY_USER_BINDING']),$username);
|
||||||
|
|
||||||
|
$connection = ldap_connect($config['DIRECTORY_SERVER']) or die("Couldn't connect to ADS");
|
||||||
|
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||||
|
if (ldap_bind($connection,$bindUser,$password)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an entry from the LDAP server for the given user
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
public function __construct($username)
|
||||||
|
{
|
||||||
|
global $DIRECTORY_CONFIG;
|
||||||
|
|
||||||
|
$this->config = $DIRECTORY_CONFIG['Employee'];
|
||||||
|
$this->openConnection();
|
||||||
|
|
||||||
|
$result = ldap_search(
|
||||||
|
self::$connection,
|
||||||
|
$this->config['DIRECTORY_BASE_DN'],
|
||||||
|
$this->config['DIRECTORY_USERNAME_ATTRIBUTE']."=$username"
|
||||||
|
);
|
||||||
|
if (ldap_count_entries(self::$connection,$result)) {
|
||||||
|
$entries = ldap_get_entries(self::$connection, $result);
|
||||||
|
$this->entry = $entries[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('ldap/unknownUser');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the connection to the LDAP server
|
||||||
|
*/
|
||||||
|
private function openConnection()
|
||||||
|
{
|
||||||
|
if (!self::$connection) {
|
||||||
|
if (self::$connection = ldap_connect($this->config['DIRECTORY_SERVER'])) {
|
||||||
|
ldap_set_option(self::$connection, LDAP_OPT_PROTOCOL_VERSION,3);
|
||||||
|
ldap_set_option(self::$connection, LDAP_OPT_REFERRALS, 0);
|
||||||
|
if (!empty($this->config['DIRECTORY_ADMIN_BINDING'])) {
|
||||||
|
if (!ldap_bind(
|
||||||
|
self::$connection,
|
||||||
|
$this->config['DIRECTORY_ADMIN_BINDING'],
|
||||||
|
$this->config['DIRECTORY_ADMIN_PASS']
|
||||||
|
)) {
|
||||||
|
throw new \Exception(ldap_error(self::$connection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!ldap_bind(self::$connection)) {
|
||||||
|
throw new \Exception(ldap_error(self::$connection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception(ldap_error(self::$connection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUsername() { return $this->get('cn'); }
|
||||||
|
public function getFirstname() { return $this->get('givenname'); }
|
||||||
|
public function getLastname() { return $this->get('sn'); }
|
||||||
|
public function getEmail() { return $this->get('mail'); }
|
||||||
|
public function getPhone() { return $this->get('telephonenumber'); }
|
||||||
|
public function getAddress() { return $this->get('postaladdress'); }
|
||||||
|
public function getCity() { return $this->get('l'); }
|
||||||
|
public function getState() { return $this->get('st'); }
|
||||||
|
public function getZip() { return $this->get('postalcode'); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first scalar value from the entry's field
|
||||||
|
*
|
||||||
|
* @param string $field
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function get($field) {
|
||||||
|
return isset($this->entry[$field][0]) ? $this->entry[$field][0] : '';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class for custom error handling
|
||||||
|
*
|
||||||
|
* Applications need to do more with errors than just display or log the error.
|
||||||
|
* Error handling should be configurable in the configuration.inc
|
||||||
|
* The $ERROR_REPORTING variable declared in configuration.inc controls the
|
||||||
|
* various possibile things to do with errors.
|
||||||
|
*
|
||||||
|
* @copyright 2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class Error
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Provide nicely formatted error messages when PHP bombs out.
|
||||||
|
*/
|
||||||
|
public static function customErrorHandler($errno, $errstr, $errfile, $errline)
|
||||||
|
{
|
||||||
|
global $ERROR_REPORTING;
|
||||||
|
|
||||||
|
if (isset($ERROR_REPORTING)) {
|
||||||
|
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
||||||
|
echo "
|
||||||
|
<div id=\"errorMessages\">
|
||||||
|
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
||||||
|
There is an error in the code on this page that is through no fault of your own.
|
||||||
|
Errors of this sort need to be fixed immediately, though.
|
||||||
|
Please help us out by copying and pasting the following error message into an email and sending it to me at
|
||||||
|
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
||||||
|
</p>
|
||||||
|
<p><strong>Code Error:</strong> Error on line $errline of file $errfile:</p>
|
||||||
|
<p>$errstr</p>
|
||||||
|
</div>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
||||||
|
$subject = APPLICATION_NAME.' Error';
|
||||||
|
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
||||||
|
&& isset($_SESSION['USER'])
|
||||||
|
&& $_SESSION['USER']->getEmail()) {
|
||||||
|
$subject = APPLICATION_NAME.' Error';
|
||||||
|
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
mail($_SESSION['USER']->getEmail(),
|
||||||
|
$subject,
|
||||||
|
$message,
|
||||||
|
"From: apache@$_SERVER[SERVER_NAME]");
|
||||||
|
}
|
||||||
|
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
||||||
|
$script = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['SCRIPT_NAME'];
|
||||||
|
$message = "$script\nError on line $errline of file $errfile:\n$errstr\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
|
||||||
|
$skidder = curl_init(SKIDDER_URL);
|
||||||
|
curl_setopt($skidder,CURLOPT_POST,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_HEADER,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($skidder,
|
||||||
|
CURLOPT_POSTFIELDS,
|
||||||
|
array('application_id'=>SKIDDER_APPLICATION_ID,
|
||||||
|
'script'=>$script,
|
||||||
|
'type'=>$errstr,
|
||||||
|
'message'=>$message));
|
||||||
|
curl_exec($skidder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object oriented exceptions are handled differently from other PHP errors.
|
||||||
|
*/
|
||||||
|
public static function customExceptionHandler($exception)
|
||||||
|
{
|
||||||
|
global $ERROR_REPORTING;
|
||||||
|
|
||||||
|
if (isset($ERROR_REPORTING)) {
|
||||||
|
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
||||||
|
echo "
|
||||||
|
<div id=\"errorMessages\">
|
||||||
|
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
||||||
|
There is an error in the code on this page that is through no fault of your own.
|
||||||
|
Errors of this sort need to be fixed immediately, though.
|
||||||
|
Please help me out by copying and pasting the following error message into an email and sending it to me at
|
||||||
|
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
||||||
|
</p>
|
||||||
|
<p><strong>Uncaught exception:</strong>
|
||||||
|
Exception on line {$exception->getLine()} of file {$exception->getFile()}:
|
||||||
|
</p>
|
||||||
|
<p>{$exception->getMessage()}</p>
|
||||||
|
</div>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
||||||
|
$subject = APPLICATION_NAME.' Exception';
|
||||||
|
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
||||||
|
}
|
||||||
|
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
||||||
|
&& isset($_SESSION['USER'])
|
||||||
|
&& $_SESSION['USER']->getEmail()) {
|
||||||
|
$subject = APPLICATION_NAME.' Exception';
|
||||||
|
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
mail($_SESSION['USER']->getEmail(),
|
||||||
|
$subject,
|
||||||
|
$message,
|
||||||
|
"From: apache@$_SERVER[SERVER_NAME]");
|
||||||
|
}
|
||||||
|
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
||||||
|
$script = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['SCRIPT_NAME'];
|
||||||
|
$message = "Error on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n";
|
||||||
|
$message.= print_r(debug_backtrace(),true);
|
||||||
|
|
||||||
|
$skidder = curl_init(SKIDDER_URL);
|
||||||
|
curl_setopt($skidder,CURLOPT_POST,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_HEADER,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
||||||
|
curl_setopt($skidder,CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($skidder,
|
||||||
|
CURLOPT_POSTFIELDS,
|
||||||
|
array('application_id'=>SKIDDER_APPLICATION_ID,
|
||||||
|
'script'=>$script,
|
||||||
|
'type'=>'Uncaught Exception',
|
||||||
|
'message'=>$message));
|
||||||
|
curl_exec($skidder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright 20011 City of Bloomington, Indiana
|
* @copyright 2011-2013 City of Bloomington, Indiana
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
*/
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
interface ExternalIdentity
|
interface ExternalIdentity
|
||||||
{
|
{
|
||||||
|
@ -25,15 +26,11 @@ interface ExternalIdentity
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFirstname();
|
public function getFirstname();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getLastname();
|
public function getLastname();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEmail();
|
public function getEmail();
|
||||||
|
public function getPhone();
|
||||||
}
|
public function getAddress();
|
||||||
|
public function getCity();
|
||||||
|
public function getState();
|
||||||
|
public function getZip();
|
||||||
|
}
|
|
@ -2,10 +2,12 @@
|
||||||
/**
|
/**
|
||||||
* Takes an array and splits it up into pages (an array of arrays)
|
* Takes an array and splits it up into pages (an array of arrays)
|
||||||
*
|
*
|
||||||
* @copyright 2008-2009 City of Bloomington, Indiana
|
* @copyright 2008-2013 City of Bloomington, Indiana
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
*/
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
class Paginator implements ArrayAccess,SeekableIterator,Countable
|
class Paginator implements ArrayAccess,SeekableIterator,Countable
|
||||||
{
|
{
|
||||||
private $pageSize;
|
private $pageSize;
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2012-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class SolrPaginatorAdapter implements \Zend\Paginator\Adapter\AdapterInterface
|
||||||
|
{
|
||||||
|
private $solrObject;
|
||||||
|
|
||||||
|
public function __construct(\Apache_Solr_Response $solrObject)
|
||||||
|
{
|
||||||
|
$this->solrObject = $solrObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return $this->solrObject->response->numFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItems($offset, $itemCountPerPage)
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* A base class that streamlines creation of ZF2 TableGateway
|
||||||
|
*
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
use Zend\Db\TableGateway\TableGateway as ZendTableGateway;
|
||||||
|
use Zend\Db\ResultSet\ResultSet;
|
||||||
|
use Zend\Db\Sql\Select;
|
||||||
|
use Zend\Paginator\Adapter\DbSelect;
|
||||||
|
use Zend\Paginator\Paginator;
|
||||||
|
|
||||||
|
abstract class TableGateway
|
||||||
|
{
|
||||||
|
protected $resultSetPrototype;
|
||||||
|
protected $tableGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $table The name of the database table
|
||||||
|
* @param string $class The class model to use as a resultSetPrototype
|
||||||
|
*
|
||||||
|
* You must pass in the fully namespaced classname. We do not assume
|
||||||
|
* any particular namespace for the models.
|
||||||
|
*/
|
||||||
|
public function __construct($table, $class)
|
||||||
|
{
|
||||||
|
$this->resultSetPrototype = new ResultSet();
|
||||||
|
$this->resultSetPrototype->setArrayObjectPrototype(new $class());
|
||||||
|
$this->tableGateway = new ZendTableGateway(
|
||||||
|
$table,
|
||||||
|
Database::getConnection(),
|
||||||
|
null,
|
||||||
|
$this->resultSetPrototype
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple, default implementation for find
|
||||||
|
*
|
||||||
|
* This will allow you to do queries for rows in the table,
|
||||||
|
* where you provide field=>values for the where clause.
|
||||||
|
* Only fields actually in the table can be included this way.
|
||||||
|
*
|
||||||
|
* You generally want to override this implementation with your own
|
||||||
|
* However, this basic implementation will allow you to get up and
|
||||||
|
* running quicker.
|
||||||
|
*
|
||||||
|
* @param array $fields Key value pairs to select on
|
||||||
|
* @param string $order The default ordering to use for select
|
||||||
|
* @param boolean $paginated If set to true, will return a paginator
|
||||||
|
* @param int $limit
|
||||||
|
*/
|
||||||
|
public function find($fields=null, $order=null, $paginated=false, $limit=null)
|
||||||
|
{
|
||||||
|
$select = new Select($this->tableGateway->getTable());
|
||||||
|
if (count($fields)) {
|
||||||
|
foreach ($fields as $key=>$value) {
|
||||||
|
$select->where([$key=>$value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->performSelect($select, $order, $paginated, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Zend\Db\Sql\Select $select
|
||||||
|
* @return Zend\Db\ResultSet
|
||||||
|
*/
|
||||||
|
public function performSelect(Select $select, $order, $paginated=false, $limit=null)
|
||||||
|
{
|
||||||
|
if ($order) { $select->order($order); }
|
||||||
|
if ($limit) { $select->limit($limit); }
|
||||||
|
|
||||||
|
if ($paginated) {
|
||||||
|
$adapter = new DbSelect($select, $this->tableGateway->getAdapter(), $this->resultSetPrototype);
|
||||||
|
$paginator = new Paginator($adapter);
|
||||||
|
return $paginator;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $this->tableGateway->selectWith($select);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the generated sql
|
||||||
|
*
|
||||||
|
* @param Zend\Db\Sql\Select
|
||||||
|
*/
|
||||||
|
public function getSqlForSelect(Select $select)
|
||||||
|
{
|
||||||
|
return $select->getSqlString($this->tableGateway->getAdapter()->getPlatform());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Zend\Db\ResultSet
|
||||||
|
*/
|
||||||
|
public static function getSqlForResult(ResultSet $result)
|
||||||
|
{
|
||||||
|
return $result->getDataSource()->getResource()->queryString;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Defines the overall page layout
|
||||||
|
*
|
||||||
|
* The template collects all the blocks from the controller
|
||||||
|
*
|
||||||
|
* @copyright 2006-2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class Template extends View
|
||||||
|
{
|
||||||
|
private $path;
|
||||||
|
private $filename;
|
||||||
|
|
||||||
|
public $outputFormat = 'html';
|
||||||
|
public $blocks = array();
|
||||||
|
private $assets = array();
|
||||||
|
private $helpers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @param string $outputFormat
|
||||||
|
* @param array $vars
|
||||||
|
*/
|
||||||
|
public function __construct($filename='default',$outputFormat='html',array $vars=null)
|
||||||
|
{
|
||||||
|
parent::__construct($vars);
|
||||||
|
|
||||||
|
$this->filename = $filename;
|
||||||
|
$this->outputFormat = preg_replace('/[^a-zA-Z]/','',$outputFormat);
|
||||||
|
|
||||||
|
// Check for a SITE_HOME override
|
||||||
|
$this->path = is_file(SITE_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc")
|
||||||
|
? SITE_HOME.'/templates'
|
||||||
|
: APPLICATION_HOME.'/templates';
|
||||||
|
|
||||||
|
// Make sure the output format exists
|
||||||
|
if (!is_file("{$this->path}/{$this->outputFormat}/{$this->filename}.inc")) {
|
||||||
|
$this->filename = 'default';
|
||||||
|
$this->outputFormat = 'html';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
*/
|
||||||
|
public function setFilename($filename)
|
||||||
|
{
|
||||||
|
if ( is_file(SITE_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc")) {
|
||||||
|
$this->path = SITE_HOME.'/templates';
|
||||||
|
}
|
||||||
|
elseif ( is_file(APPLICATION_HOME."/templates/{$this->outputFormat}/$filename.inc")) {
|
||||||
|
$this->path = APPLICATION_HOME.'/templates';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('unknownTemplate');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->filename = $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $format
|
||||||
|
*/
|
||||||
|
public function setOutputFormat($format)
|
||||||
|
{
|
||||||
|
$format = preg_replace('/[^a-zA-Z]/','',$format);
|
||||||
|
|
||||||
|
if ( is_file(SITE_HOME."/templates/$format/{$this->filename}.inc")) {
|
||||||
|
$this->path = SITE_HOME.'/templates';
|
||||||
|
}
|
||||||
|
elseif ( is_file(APPLICATION_HOME."/templates/$format/{$this->filename}.inc")) {
|
||||||
|
$this->path = APPLICATION_HOME.'/templates';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('unknownOutputFormat');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->outputFormat = $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the rendered content of the template
|
||||||
|
*
|
||||||
|
* Template files must include a call to $this->includeBlocks(),
|
||||||
|
* when they're ready for content
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
include "{$this->path}/{$this->outputFormat}/{$this->filename}.inc";
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function for template files
|
||||||
|
*
|
||||||
|
* Renders blocks for the main content area, unless $panel is given. If $panel is given
|
||||||
|
* it will render any blocks that the controllers have assigned to that panel.
|
||||||
|
*
|
||||||
|
* Template files make calls to this function to render all the blocks that the controller
|
||||||
|
* has loaded for this Template. Controllers will populate the blocks array with content.
|
||||||
|
* If a template file can render content in a panel that is not the main content panel,
|
||||||
|
* the template file will need to include the panel's name in the includeBlocks() call.
|
||||||
|
*
|
||||||
|
* $this->blocks is a multi-dimensional array. The top level elements, non-array elements
|
||||||
|
* are for the default, main content area. Other panels will be arrays in $this->blocks with
|
||||||
|
* the panel name as the key.
|
||||||
|
*
|
||||||
|
* Panels are nothing but a name on a div, the $panel string can be whatever the template
|
||||||
|
* author thinks makes sense. Controllers are expected to know what the template authors
|
||||||
|
* have written.
|
||||||
|
*
|
||||||
|
* $this->blocks[] = "main content block one";
|
||||||
|
* $this->blocks[] = "main content block two";
|
||||||
|
* $this->blocks['panel-one'][] = "left sidebar block one";
|
||||||
|
* $this->blocks['panel-one'][] = "left sidebar block two";
|
||||||
|
* $this->blocks['panel-two'][] = "right sidebar block one";
|
||||||
|
*
|
||||||
|
* @param string $panel
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function includeBlocks($target=null)
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
if ($target) {
|
||||||
|
// Render any blocks for the given panel
|
||||||
|
if (isset($this->blocks[$target]) && is_array($this->blocks[$target])) {
|
||||||
|
foreach ($this->blocks[$target] as $block) {
|
||||||
|
echo $block->render($this->outputFormat,$this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Go through the template looking for what they asked for
|
||||||
|
foreach ($this->blocks as $key=>$value) {
|
||||||
|
// If we find a block that matches, render that block
|
||||||
|
if ($value instanceof Block) {
|
||||||
|
if ($value->getFile() == $target) {
|
||||||
|
echo $value->render($this->outputFormat,$this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The block they asked for might be inside a panel
|
||||||
|
else {
|
||||||
|
foreach ($value as $block) {
|
||||||
|
if ($block->getFile() == $target
|
||||||
|
|| $block->title == $target) {
|
||||||
|
echo $block->render($this->outputFormat,$this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Render only the blocks for the main content area
|
||||||
|
foreach ($this->blocks as $block) {
|
||||||
|
if (!is_array($block)) {
|
||||||
|
echo $block->render($this->outputFormat,$this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds data to an asset, making sure to not duplicate existing data
|
||||||
|
*
|
||||||
|
* @param string $name The name of the asset
|
||||||
|
* @param mixed $data
|
||||||
|
*/
|
||||||
|
public function addToAsset($name,$data)
|
||||||
|
{
|
||||||
|
if (!isset($this->assets[$name]) || !is_array($this->assets[$name])) {
|
||||||
|
$this->assets[$name] = array();
|
||||||
|
}
|
||||||
|
if (!in_array($data,$this->assets[$name])) {
|
||||||
|
$this->assets[$name][] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and returns a helper object
|
||||||
|
*/
|
||||||
|
public function getHelper($functionName)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($functionName, $this->helpers)) {
|
||||||
|
$class = ucfirst($functionName);
|
||||||
|
$file = "/templates/{$this->outputFormat}/helpers/$class.php";
|
||||||
|
|
||||||
|
if ( is_file(SITE_HOME.$file)) {
|
||||||
|
require_once SITE_HOME.$file;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
require_once APPLICATION_HOME.$file;
|
||||||
|
}
|
||||||
|
$class = "Application\\Templates\\Helpers\\$class";
|
||||||
|
$this->helpers[$functionName] = new $class($this);
|
||||||
|
}
|
||||||
|
return $this->helpers[$functionName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes the given filename.
|
||||||
|
*
|
||||||
|
* Supports SITE_HOME overriding.
|
||||||
|
* Specify a relative path starting from /templates/
|
||||||
|
* $file paths should not start with a slash.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*/
|
||||||
|
public function _include($file)
|
||||||
|
{
|
||||||
|
if (is_file(SITE_HOME."/templates/{$this->outputFormat}/$file")) {
|
||||||
|
include SITE_HOME."/templates/{$this->outputFormat}/$file";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
include APPLICATION_HOME."/templates/{$this->outputFormat}/$file";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,11 +7,13 @@
|
||||||
* $url->somevar = $somevar;
|
* $url->somevar = $somevar;
|
||||||
* echo $url->getURL();
|
* echo $url->getURL();
|
||||||
*
|
*
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana.
|
* @copyright 2006-2013 City of Bloomington, Indiana.
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
*/
|
*/
|
||||||
class URL
|
namespace Blossom\Classes;
|
||||||
|
|
||||||
|
class Url
|
||||||
{
|
{
|
||||||
private $scheme;
|
private $scheme;
|
||||||
private $host;
|
private $host;
|
||||||
|
@ -20,26 +22,43 @@ class URL
|
||||||
|
|
||||||
public $parameters = array();
|
public $parameters = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an HTTP GET and returns response string
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function get($url)
|
||||||
|
{
|
||||||
|
$request = curl_init($url);
|
||||||
|
curl_setopt($request, CURLOPT_RETURNTRANSFER,true);
|
||||||
|
curl_setopt($request, CURLOPT_FOLLOWLOCATION, true);
|
||||||
|
|
||||||
|
if (substr($url, 0, 5) == 'https://') {
|
||||||
|
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($request, CURLOPT_SSLVERSION, 3);
|
||||||
|
}
|
||||||
|
return curl_exec($request);
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct($script)
|
public function __construct($script)
|
||||||
{
|
{
|
||||||
$script = urldecode($script);
|
$script = urldecode($script);
|
||||||
|
|
||||||
// If scheme wasn't provided add one to the start of the string
|
// If scheme wasn't provided add one to the start of the string
|
||||||
if (!preg_match('|://|',$script)) {
|
if (!strpos(substr($script,0,20),'://')) {
|
||||||
$scheme = $_SERVER['SERVER_PORT']==443 ? 'https://' : 'http://';
|
$scheme = (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']==443)
|
||||||
|
? 'https://'
|
||||||
|
: 'http://';
|
||||||
$script = $scheme.$script;
|
$script = $scheme.$script;
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = parse_url($script);
|
$url = parse_url($script);
|
||||||
$this->scheme = $url['scheme'];
|
$this->scheme = $url['scheme'];
|
||||||
$this->host = $url['host'];
|
if (isset($url['host'])) { $this->host = $url['host']; }
|
||||||
$this->path = $url['path'];
|
if (isset($url['path'])) { $this->path = $url['path']; }
|
||||||
if (isset($url['fragment'])) {
|
if (isset($url['fragment'])) { $this->anchor = $url['fragment']; }
|
||||||
$this->anchor = $url['fragment'];
|
if (isset($url['query'])) { parse_str($url['query'],$this->parameters); }
|
||||||
}
|
|
||||||
if (isset($url['query'])) {
|
|
||||||
parse_str($url['query'],$this->parameters);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +102,7 @@ class URL
|
||||||
*/
|
*/
|
||||||
public function getScheme() {
|
public function getScheme() {
|
||||||
if (!$this->scheme) {
|
if (!$this->scheme) {
|
||||||
$this->scheme = 'http://';
|
$this->scheme = 'http';
|
||||||
}
|
}
|
||||||
return $this->scheme;
|
return $this->scheme;
|
||||||
}
|
}
|
||||||
|
@ -94,9 +113,7 @@ class URL
|
||||||
*/
|
*/
|
||||||
public function setScheme($string)
|
public function setScheme($string)
|
||||||
{
|
{
|
||||||
if (!preg_match('|://|',$string)) {
|
$string = preg_replace('|://|', '', $string);
|
||||||
$string .= '://';
|
|
||||||
}
|
|
||||||
$this->scheme = $string;
|
$this->scheme = $string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2006-2013 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Blossom\Classes;
|
||||||
|
use Zend\I18n\Translator\Translator;
|
||||||
|
|
||||||
|
abstract class View
|
||||||
|
{
|
||||||
|
protected $vars = array();
|
||||||
|
private static $translator;
|
||||||
|
|
||||||
|
abstract public function render();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the Zend Translator
|
||||||
|
*
|
||||||
|
* See: ZendFramework documentation for full information
|
||||||
|
* http://framework.zend.com/manual/2.2/en/modules/zend.i18n.translating.html
|
||||||
|
* @see http://framework.zend.com/manual/2.2/en/modules/zend.i18n.translating.html
|
||||||
|
*/
|
||||||
|
public function __construct(array $vars=null)
|
||||||
|
{
|
||||||
|
if (count($vars)) {
|
||||||
|
foreach ($vars as $name=>$value) {
|
||||||
|
$this->vars[$name] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self::$translator) {
|
||||||
|
self::$translator = new Translator();
|
||||||
|
self::$translator->addTranslationFilePattern(
|
||||||
|
'gettext',
|
||||||
|
APPLICATION_HOME.'/language',
|
||||||
|
'%s.mo'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic Method for setting object properties
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function __set($key,$value) {
|
||||||
|
$this->vars[$key] = $value;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Magic method for getting object properties
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
if (isset($this->vars[$key])) {
|
||||||
|
return $this->vars[$key];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function __isset($key) {
|
||||||
|
return array_key_exists($key,$this->vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans strings for output
|
||||||
|
*
|
||||||
|
* There are more bad characters than htmlspecialchars deals with. We just want
|
||||||
|
* to add in some other characters to clean. While here, we might as well
|
||||||
|
* have it trim out the whitespace too.
|
||||||
|
*
|
||||||
|
* @param array|string $string
|
||||||
|
* @param CONSTANT $quotes Optional, the desired constant to use for the htmlspecidalchars call
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function escape($input,$quotes=ENT_QUOTES)
|
||||||
|
{
|
||||||
|
if (is_array($input)) {
|
||||||
|
foreach ($input as $key=>$value) {
|
||||||
|
$input[$key] = self::escape($value,$quotes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$input = htmlspecialchars(trim($input), $quotes, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the gettext translation of msgid
|
||||||
|
*
|
||||||
|
* For entries in the PO that are plurals, you must pass msgid as an array
|
||||||
|
* $this->translate(array('msgid', 'msgid_plural', $num))
|
||||||
|
*
|
||||||
|
* See: ZendFramework documentation for full information
|
||||||
|
* http://framework.zend.com/manual/2.2/en/modules/zend.i18n.translating.html
|
||||||
|
*
|
||||||
|
* @see http://framework.zend.com/manual/2.2/en/modules/zend.i18n.translating.html
|
||||||
|
* @param mixed $msgid String or Array
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function translate($msgid)
|
||||||
|
{
|
||||||
|
if (is_array($msgid)) {
|
||||||
|
return self::$translator->translatePlural($msgid[0], $msgid[1], $msgid[2]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return self::$translator->translate($msgid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias of $this->translate()
|
||||||
|
*/
|
||||||
|
public function _($msgid)
|
||||||
|
{
|
||||||
|
return $this->translate($msgid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,38 +1,44 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
* Displays page navigation for any list that has pagination turned on
|
||||||
|
*
|
||||||
|
* @copyright 2007-2013 City of Bloomington, Indiana
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
* @param Zend_Paginator $this->pages
|
* @param Zend\Paginator $this->paginator
|
||||||
*/
|
*/
|
||||||
if ($this->pages->pageCount > 1) {
|
use Blossom\Classes\Url;
|
||||||
$url = new URL($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
|
|
||||||
|
if ($this->paginator->count() > 1) {
|
||||||
|
$pages = $this->paginator->getPages();
|
||||||
|
|
||||||
|
$url = new Url($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
|
||||||
$url->purgeEmptyParameters();
|
$url->purgeEmptyParameters();
|
||||||
|
|
||||||
echo '<ul class="pageNavigation">';
|
echo '<ul class="pageNavigation">';
|
||||||
|
|
||||||
// Show the Back button
|
// Show the Back button
|
||||||
if (isset($this->pages->previous)) {
|
if (isset($pages->previous)) {
|
||||||
$url->page = $this->pages->first;
|
$url->page = $pages->first;
|
||||||
echo "<li><a href=\"$url\" class=\"first\">First</a></li>";
|
echo "<li><a href=\"$url\" class=\"first\">First</a></li>";
|
||||||
|
|
||||||
$url->page = $this->pages->previous;
|
$url->page = $pages->previous;
|
||||||
echo "<li><a href=\"$url\" class=\"previous\">Back</a></li>";
|
echo "<li><a href=\"$url\" class=\"previous\">Back</a></li>";
|
||||||
}
|
}
|
||||||
// Show the page number links
|
// Show the page number links
|
||||||
// Show only $maxNumLinks pages at a time
|
// Show only $maxNumLinks pages at a time
|
||||||
foreach ($this->pages->pagesInRange as $page) {
|
foreach ($pages->pagesInRange as $page) {
|
||||||
$url->page = $page;
|
$url->page = $page;
|
||||||
$class = ($page == $this->pages->current) ? 'class="current"' : '';
|
$class = ($page == $pages->current) ? 'class="current"' : '';
|
||||||
echo "<li><a href=\"$url\" $class>$page</a></li>";
|
echo "<li><a href=\"$url\" $class>$page</a></li>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the Next button
|
// Show the Next button
|
||||||
if (isset($this->pages->next)) {
|
if (isset($pages->next)) {
|
||||||
$url->page = $this->pages->next;
|
$url->page = $pages->next;
|
||||||
echo "<li><a href=\"$url\" class=\"next\">Next</a></li>";
|
echo "<li><a href=\"$url\" class=\"next\">Next</a></li>";
|
||||||
|
|
||||||
$url->page = $this->pages->last;
|
$url->page = $pages->last;
|
||||||
echo "<li><a href=\"$url\" class=\"last\">Last</a></li>";
|
echo "<li><a href=\"$url\" class=\"last\">Last</a></li>";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
* @copyright 2007-2013 City of Bloomington, Indiana
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
*/
|
*/
|
||||||
|
use Blossom\Classes\Block;
|
||||||
|
|
||||||
if (isset($_SESSION['errorMessages'])) {
|
if (isset($_SESSION['errorMessages'])) {
|
||||||
$errorBlock = new Block('errorMessages.inc',array('errorMessages'=>$_SESSION['errorMessages']));
|
$errorBlock = new Block('errorMessages.inc',array('errorMessages'=>$_SESSION['errorMessages']));
|
||||||
echo $errorBlock->render($this->outputFormat);
|
echo $errorBlock->render($this->outputFormat);
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
class ActiveRecordTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
private $testModel;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->testModel = new TestModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAndSet()
|
||||||
|
{
|
||||||
|
$this->testModel->set('testField', 'testValue');
|
||||||
|
$this->assertEquals('testValue', $this->testModel->get('testField'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAndSetDate()
|
||||||
|
{
|
||||||
|
$dateString = '2012-01-01 01:23:43';
|
||||||
|
$this->testModel->setDateData('testField', $dateString);
|
||||||
|
$this->assertEquals($dateString, $this->testModel->getDateData('testField'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDateFormat()
|
||||||
|
{
|
||||||
|
$dateString = '1/3/2013 01:23:43';
|
||||||
|
$this->testModel->setDateData('testField', $dateString);
|
||||||
|
$this->assertEquals('Jan 3rd 2013', $this->testModel->getDateData('testField', 'M jS Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRawDateDataIsMySQLFormat()
|
||||||
|
{
|
||||||
|
$dateString = '1/3/2013 01:23:43';
|
||||||
|
$mysqlDate = '2013-01-03 01:23:43';
|
||||||
|
|
||||||
|
$this->testModel->setDateData('testField', $dateString);
|
||||||
|
$this->assertEquals($mysqlDate, $this->testModel->getDateData('testField'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testForeignKeyObject()
|
||||||
|
{
|
||||||
|
$this->testModel->setTestModel(new TestModel(1));
|
||||||
|
$o = $this->testModel->getTestModel();
|
||||||
|
$this->assertEquals(1, $o->get('id'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestModel extends Blossom\Classes\ActiveRecord
|
||||||
|
{
|
||||||
|
protected $foreignkey;
|
||||||
|
|
||||||
|
public function __construct($id=null)
|
||||||
|
{
|
||||||
|
if ($id) { parent::set('id', $id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate() { }
|
||||||
|
|
||||||
|
public function getId() { return parent::get('id'); }
|
||||||
|
|
||||||
|
public function get($field) { return parent::get($field); }
|
||||||
|
public function set($field, $value) { parent::set($field, $value); }
|
||||||
|
|
||||||
|
|
||||||
|
public function getDateData($field, $format=null, \DateTimeZone $timezone=null)
|
||||||
|
{
|
||||||
|
return parent::getDateData($field, $format, $timezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDateData($field, $date) { parent::setDateData($field, $date); }
|
||||||
|
|
||||||
|
public function getTestModel()
|
||||||
|
{
|
||||||
|
return parent::getForeignKeyObject('TestModel', 'foreignkey_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTestModel(TestModel $o)
|
||||||
|
{
|
||||||
|
parent::setForeignKeyObject('TestModel', 'foreignkey_id', $o);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
use Blossom\Classes\Block;
|
||||||
|
use Blossom\Classes\Template;
|
||||||
|
|
||||||
|
class BlockTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testVars()
|
||||||
|
{
|
||||||
|
$block = new Block('test', ['test'=>'something']);
|
||||||
|
$this->assertEquals('something', $block->test);
|
||||||
|
|
||||||
|
$block->one = 'another';
|
||||||
|
$this->assertEquals('another', $block->one);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SITE_HOME should be able to override any block
|
||||||
|
*/
|
||||||
|
public function testSiteOverrides()
|
||||||
|
{
|
||||||
|
$template = new Template('test', 'test');
|
||||||
|
$block = new Block('test.inc');
|
||||||
|
|
||||||
|
$expectedOutput = file_get_contents(__DIR__.'/blocks/test/test.inc');
|
||||||
|
$this->assertEquals($expectedOutput, $block->render('test', $template));
|
||||||
|
|
||||||
|
$block = new Block('includes.inc');
|
||||||
|
$this->assertEquals($expectedOutput, $block->render('test', $template));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testSiteConfigLoaded()
|
||||||
|
{
|
||||||
|
$this->assertEquals('testApp', APPLICATION_NAME);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
use Blossom\Classes\Template;
|
||||||
|
|
||||||
|
class TemplateTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testVars()
|
||||||
|
{
|
||||||
|
$template = new Template('default', 'html', ['test'=>'something']);
|
||||||
|
$this->assertEquals('something', $template->test);
|
||||||
|
|
||||||
|
$template->one = 'another';
|
||||||
|
$this->assertEquals('another', $template->one);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SITE_HOME sites should be able to override any template
|
||||||
|
*/
|
||||||
|
public function testSiteOverrides()
|
||||||
|
{
|
||||||
|
$template = new Template('test', 'test');
|
||||||
|
|
||||||
|
$expectedOutput = file_get_contents(__DIR__.'/templates/test/test.inc');
|
||||||
|
$this->assertEquals($expectedOutput, $template->render());
|
||||||
|
|
||||||
|
$helper = $template->getHelper('test');
|
||||||
|
$this->assertEquals('something', $helper->test('something'));
|
||||||
|
|
||||||
|
$template = new Template('partials', 'test');
|
||||||
|
$expectedOutput = file_get_contents(__DIR__.'/templates/test/partials/testPartial.inc');
|
||||||
|
$this->assertEquals($expectedOutput, $template->render());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
use Blossom\Classes\Url;
|
||||||
|
|
||||||
|
class UrlTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
public function testUrlOutput()
|
||||||
|
{
|
||||||
|
$testUrl = 'http://www.somewhere.com/test';
|
||||||
|
|
||||||
|
$url = new Url($testUrl);
|
||||||
|
$this->assertEquals($testUrl, "$url");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testChangeScheme()
|
||||||
|
{
|
||||||
|
$url = new Url('http://www.somewhere.com');
|
||||||
|
$url->setScheme('webcal://');
|
||||||
|
$this->assertEquals('webcal://www.somewhere.com', "$url");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlWithoutScheme()
|
||||||
|
{
|
||||||
|
$url = new Url('bloomington.in.gov/test');
|
||||||
|
$this->assertEquals('http', $url->getScheme());
|
||||||
|
$this->assertEquals('http://bloomington.in.gov/test', "$url");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
$_SERVER['SITE_HOME'] = __DIR__;
|
||||||
|
require_once realpath(__DIR__.'/../../../configuration.inc');
|
||||||
|
|
||||||
|
use Blossom\Classes\View;
|
||||||
|
|
||||||
|
class ViewTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testVars()
|
||||||
|
{
|
||||||
|
$view = new ViewStub(['test'=>'something']);
|
||||||
|
$this->assertEquals('something', $view->test);
|
||||||
|
|
||||||
|
$view->one = 'another test';
|
||||||
|
$this->assertEquals('another test', $view->one);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewStub extends View
|
||||||
|
{
|
||||||
|
public function __construct($vars=null)
|
||||||
|
{
|
||||||
|
parent::__construct($vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() { return 'test content'; }
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?php
|
||||||
|
$this->_include('test/test.inc');
|
|
@ -0,0 +1 @@
|
||||||
|
This is a custom block override
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
define('APPLICATION_NAME','testApp');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to get to this site
|
||||||
|
* Do NOT use a trailing slash
|
||||||
|
*/
|
||||||
|
define('BASE_URL','http://localhost/testApp');
|
||||||
|
define('BASE_URI','/testApp');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when there's an error on the site. The Framework will
|
||||||
|
* print out a nice error message, encouraging users to report any problems
|
||||||
|
* See: Blossom\Classes\Error
|
||||||
|
*/
|
||||||
|
define('ADMINISTRATOR_NAME','Site Admin');
|
||||||
|
define('ADMINISTRATOR_EMAIL','admin@localhost');
|
||||||
|
|
||||||
|
define('DATE_FORMAT', 'n/j/Y H:i:s');
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Test Helper
|
||||||
|
*
|
||||||
|
* @copyright 2014 City of Bloomington, Indiana
|
||||||
|
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
||||||
|
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
|
*/
|
||||||
|
namespace Application\Templates\Helpers;
|
||||||
|
|
||||||
|
use Blossom\Classes\Template;
|
||||||
|
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
private $template;
|
||||||
|
|
||||||
|
public function __construct(Template $template)
|
||||||
|
{
|
||||||
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test($string)
|
||||||
|
{
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?php
|
||||||
|
$this->_include('partials/testPartial.inc');
|
|
@ -0,0 +1 @@
|
||||||
|
This is a test partial
|
|
@ -0,0 +1 @@
|
||||||
|
This is a customized site template
|
|
@ -1,62 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Represents a block of main content in a template
|
|
||||||
*
|
|
||||||
* Blocks are partial view scripts.
|
|
||||||
* They are contained in APPLICATION/blocks
|
|
||||||
* They are organized by $outputFormat
|
|
||||||
* APPLICATION_HOME/blocks/html/...
|
|
||||||
* APPLICATION_HOME/blocks/xml/...
|
|
||||||
* APPLICATION_HOME/blocks/json/..
|
|
||||||
*
|
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
class Block extends View
|
|
||||||
{
|
|
||||||
private $file;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establishes the block script to use for rendering
|
|
||||||
*
|
|
||||||
* Blocks are files contained in the base path of:
|
|
||||||
* APPLICATION_HOME/blocks/$outpuform
|
|
||||||
*
|
|
||||||
* @param string $file
|
|
||||||
* @param array $vars An associative array of variables to set
|
|
||||||
*/
|
|
||||||
public function __construct($file,array $vars=null)
|
|
||||||
{
|
|
||||||
$this->file = $file;
|
|
||||||
if (count($vars)) {
|
|
||||||
foreach ($vars as $name=>$value) {
|
|
||||||
$this->vars[$name] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Includes the block script and returns the output as a string
|
|
||||||
*
|
|
||||||
* @param string $outputFormat
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function render($outputFormat='html')
|
|
||||||
{
|
|
||||||
$block = "/blocks/$outputFormat/{$this->file}";
|
|
||||||
|
|
||||||
if (file_exists(APPLICATION_HOME.$block)) {
|
|
||||||
ob_start();
|
|
||||||
include APPLICATION_HOME.$block;
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
elseif (file_exists(FRAMEWORK.$block)) {
|
|
||||||
ob_start();
|
|
||||||
include FRAMEWORK.$block;
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception('unknownBlock');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright 2009 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
class Date extends DateTime
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Handles array dates passed in the constructor.
|
|
||||||
*
|
|
||||||
* Wrapper for DateTime constructor. If arrays are passed, they will be
|
|
||||||
* handled here. Anything else will be passed to the DateTime constructor.
|
|
||||||
* Arrays should be in the form of PHP's getdate() array
|
|
||||||
*
|
|
||||||
* @param array $date
|
|
||||||
*/
|
|
||||||
public function __construct($date=null)
|
|
||||||
{
|
|
||||||
if (is_array($date)) {
|
|
||||||
if ($date['year'] && $date['mon'] && $date['mday']) {
|
|
||||||
$dateString = "$date[year]-$date[mon]-$date[mday]";
|
|
||||||
|
|
||||||
if (isset($date['hours']) || isset($date['minutes']) || isset($date['seconds'])) {
|
|
||||||
$time = (isset($date['hours']) && $date['hours']) ? "$date[hours]:" : '00:';
|
|
||||||
$time.= (isset($date['minutes']) && $date['minutes']) ? "$date[minutes]:" : '00:';
|
|
||||||
$time.= (isset($date['seconds']) && $date['seconds']) ? $date['seconds'] : '00';
|
|
||||||
|
|
||||||
$dateString.= " $time";
|
|
||||||
}
|
|
||||||
$date = $dateString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_int($date)) {
|
|
||||||
$date = date('Y-m-d',$date);
|
|
||||||
}
|
|
||||||
if (!$date instanceof DateTime) {
|
|
||||||
parent::__construct($date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return $this->format('n/j/Y');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* A class for working with entries in LDAP.
|
|
||||||
*
|
|
||||||
* This class is written specifically for the City of Bloomington's
|
|
||||||
* LDAP layout. If you are going to be doing LDAP authentication
|
|
||||||
* with your own LDAP server, you will probably need to customize
|
|
||||||
* the fields used in this class.
|
|
||||||
*
|
|
||||||
* @copyright 2011 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
class Employee implements ExternalIdentity
|
|
||||||
{
|
|
||||||
private static $connection;
|
|
||||||
private $entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $username
|
|
||||||
* @param string $password
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static function authenticate($username,$password)
|
|
||||||
{
|
|
||||||
$bindUser = sprintf(str_replace('{username}','%s',DIRECTORY_USER_BINDING),$username);
|
|
||||||
|
|
||||||
$connection = ldap_connect(DIRECTORY_SERVER) or die("Couldn't connect to ADS");
|
|
||||||
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
|
||||||
if (ldap_bind($connection,$bindUser,$password)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads an entry from the LDAP server for the given user
|
|
||||||
*
|
|
||||||
* @param string $username
|
|
||||||
*/
|
|
||||||
public function __construct($username)
|
|
||||||
{
|
|
||||||
$this->openConnection();
|
|
||||||
|
|
||||||
$result = ldap_search(
|
|
||||||
self::$connection,
|
|
||||||
DIRECTORY_BASE_DN,
|
|
||||||
DIRECTORY_USERNAME_ATTRIBUTE."=$username"
|
|
||||||
);
|
|
||||||
if (ldap_count_entries(self::$connection,$result)) {
|
|
||||||
$entries = ldap_get_entries(self::$connection, $result);
|
|
||||||
$this->entry = $entries[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUsername()
|
|
||||||
{
|
|
||||||
return $this->entry['uid'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFirstname()
|
|
||||||
{
|
|
||||||
return $this->entry['givenname'][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getLastname()
|
|
||||||
{
|
|
||||||
return $this->entry['sn'][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEmail()
|
|
||||||
{
|
|
||||||
return $this->entry['mail'][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the connection to the LDAP server
|
|
||||||
*/
|
|
||||||
private function openConnection()
|
|
||||||
{
|
|
||||||
if (!self::$connection) {
|
|
||||||
if (self::$connection = ldap_connect(DIRECTORY_SERVER)) {
|
|
||||||
ldap_set_option(self::$connection,LDAP_OPT_PROTOCOL_VERSION,3);
|
|
||||||
if (defined('DIRECTORY_ADMIN_BINDING') && DIRECTORY_ADMIN_BINDING) {
|
|
||||||
if (!ldap_bind(self::$connection,DIRECTORY_ADMIN_BINDING,DIRECTORY_ADMIN_PASS)) {
|
|
||||||
throw new Exception(ldap_error(self::$connection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!ldap_bind(self::$connection)) {
|
|
||||||
throw new Exception(ldap_error(self::$connection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Exception(ldap_error(self::$connection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,332 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pluralize and singularize English words.
|
|
||||||
*
|
|
||||||
* Orinally written by the CakePHP Project
|
|
||||||
* CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2005-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 2005-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs
|
|
||||||
* @since CakePHP(tm) v 0.2.9
|
|
||||||
* @version $Revision: 6311 $
|
|
||||||
* @modifiedby $LastChangedBy: phpnut $
|
|
||||||
* @lastmodified $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*
|
|
||||||
* Modified to work in City of Bloomington's Framework
|
|
||||||
* Relicensed under GPL
|
|
||||||
* Redistributions must retain all copyright notices
|
|
||||||
* @copyright 2006-2008 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
*/
|
|
||||||
class Inflector
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Return $word in plural form.
|
|
||||||
*
|
|
||||||
* @param string $word Word in singular
|
|
||||||
* @return string Word in plural
|
|
||||||
*/
|
|
||||||
public static function pluralize($word) {
|
|
||||||
$corePluralRules = array('/(s)tatus$/i' => '\1\2tatuses',
|
|
||||||
'/(quiz)$/i' => '\1zes',
|
|
||||||
'/^(ox)$/i' => '\1\2en',
|
|
||||||
'/([m|l])ouse$/i' => '\1ice',
|
|
||||||
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
|
|
||||||
'/(x|ch|ss|sh)$/i' => '\1es',
|
|
||||||
'/([^aeiouy]|qu)y$/i' => '\1ies',
|
|
||||||
'/(hive)$/i' => '\1s',
|
|
||||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
|
|
||||||
'/sis$/i' => 'ses',
|
|
||||||
'/([ti])um$/i' => '\1a',
|
|
||||||
'/(p)erson$/i' => '\1eople',
|
|
||||||
'/(m)an$/i' => '\1en',
|
|
||||||
'/(c)hild$/i' => '\1hildren',
|
|
||||||
'/(buffal|tomat)o$/i' => '\1\2oes',
|
|
||||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
|
|
||||||
'/us$/' => 'uses',
|
|
||||||
'/(alias)$/i' => '\1es',
|
|
||||||
'/(ax|cri|test)is$/i' => '\1es',
|
|
||||||
'/s$/' => 's',
|
|
||||||
'/$/' => 's',);
|
|
||||||
|
|
||||||
$coreUninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'Amoyese',
|
|
||||||
'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
|
|
||||||
'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
|
|
||||||
'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
|
||||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
|
|
||||||
'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
|
|
||||||
'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
|
|
||||||
'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
|
|
||||||
'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
|
|
||||||
'whiting', 'wildebeest', 'Yengeese',);
|
|
||||||
|
|
||||||
$coreIrregularPlural = array('atlas' => 'atlases',
|
|
||||||
'beef' => 'beefs',
|
|
||||||
'brother' => 'brothers',
|
|
||||||
'child' => 'children',
|
|
||||||
'corpus' => 'corpuses',
|
|
||||||
'cow' => 'cows',
|
|
||||||
'ganglion' => 'ganglions',
|
|
||||||
'genie' => 'genies',
|
|
||||||
'genus' => 'genera',
|
|
||||||
'graffito' => 'graffiti',
|
|
||||||
'hoof' => 'hoofs',
|
|
||||||
'loaf' => 'loaves',
|
|
||||||
'man' => 'men',
|
|
||||||
'money' => 'monies',
|
|
||||||
'mongoose' => 'mongooses',
|
|
||||||
'move' => 'moves',
|
|
||||||
'mythos' => 'mythoi',
|
|
||||||
'numen' => 'numina',
|
|
||||||
'occiput' => 'occiputs',
|
|
||||||
'octopus' => 'octopuses',
|
|
||||||
'opus' => 'opuses',
|
|
||||||
'ox' => 'oxen',
|
|
||||||
'penis' => 'penises',
|
|
||||||
'person' => 'people',
|
|
||||||
'sex' => 'sexes',
|
|
||||||
'soliloquy' => 'soliloquies',
|
|
||||||
'testis' => 'testes',
|
|
||||||
'trilby' => 'trilbys',
|
|
||||||
'turf' => 'turfs',);
|
|
||||||
|
|
||||||
$pluralRules = $corePluralRules;
|
|
||||||
$uninflected = $coreUninflectedPlural;
|
|
||||||
$irregular = $coreIrregularPlural;
|
|
||||||
|
|
||||||
if (file_exists(FRAMEWORK.'/includes/inflections.inc')) {
|
|
||||||
include(FRAMEWORK.'/includes/inflections.inc');
|
|
||||||
$pluralRules = array_merge($pluralRules, $corePluralRules);
|
|
||||||
$uninflected = array_merge($uninflectedPlural, $coreUninflectedPlural);
|
|
||||||
$irregular = array_merge($irregularPlural, $coreIrregularPlural);
|
|
||||||
}
|
|
||||||
$regexUninflected = self::enclose(join( '|', $uninflected));
|
|
||||||
$regexIrregular = self::enclose(join( '|', array_keys($irregular)));
|
|
||||||
|
|
||||||
if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
|
|
||||||
return $regs[1] . $irregular[strtolower($regs[2])];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($pluralRules as $rule => $replacement) {
|
|
||||||
if (preg_match($rule, $word)) {
|
|
||||||
$replace = preg_replace($rule, $replacement, $word);
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Return $word in singular form.
|
|
||||||
*
|
|
||||||
* @param string $word Word in plural
|
|
||||||
* @return string Word in singular
|
|
||||||
*/
|
|
||||||
public static function singularize($word) {
|
|
||||||
$coreSingularRules = array('/(s)tatuses$/i' => '\1\2tatus',
|
|
||||||
'/^(.*)(menu)s$/i' => '\1\2',
|
|
||||||
'/(quiz)zes$/i' => '\\1',
|
|
||||||
'/(matr)ices$/i' => '\1ix',
|
|
||||||
'/(vert|ind)ices$/i' => '\1ex',
|
|
||||||
'/^(ox)en/i' => '\1',
|
|
||||||
'/(alias)(es)*$/i' => '\1',
|
|
||||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
|
|
||||||
'/(cris|ax|test)es$/i' => '\1is',
|
|
||||||
'/(shoe)s$/i' => '\1',
|
|
||||||
'/(o)es$/i' => '\1',
|
|
||||||
'/ouses$/' => 'ouse',
|
|
||||||
'/uses$/' => 'us',
|
|
||||||
'/([m|l])ice$/i' => '\1ouse',
|
|
||||||
'/(x|ch|ss|sh)es$/i' => '\1',
|
|
||||||
'/(m)ovies$/i' => '\1\2ovie',
|
|
||||||
'/(s)eries$/i' => '\1\2eries',
|
|
||||||
'/([^aeiouy]|qu)ies$/i' => '\1y',
|
|
||||||
'/([lr])ves$/i' => '\1f',
|
|
||||||
'/(tive)s$/i' => '\1',
|
|
||||||
'/(hive)s$/i' => '\1',
|
|
||||||
'/(drive)s$/i' => '\1',
|
|
||||||
'/([^f])ves$/i' => '\1fe',
|
|
||||||
'/(^analy)ses$/i' => '\1sis',
|
|
||||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
|
|
||||||
'/([ti])a$/i' => '\1um',
|
|
||||||
'/(p)eople$/i' => '\1\2erson',
|
|
||||||
'/(m)en$/i' => '\1an',
|
|
||||||
'/(c)hildren$/i' => '\1\2hild',
|
|
||||||
'/(n)ews$/i' => '\1\2ews',
|
|
||||||
'/^(.*us)$/' => '\\1',
|
|
||||||
'/s$/i' => '');
|
|
||||||
|
|
||||||
$coreUninflectedSingular = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'Amoyese',
|
|
||||||
'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
|
|
||||||
'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
|
|
||||||
'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
|
||||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
|
|
||||||
'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
|
|
||||||
'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
|
|
||||||
'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
|
|
||||||
'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
|
|
||||||
'whiting', 'wildebeest', 'Yengeese',);
|
|
||||||
|
|
||||||
$coreIrregularSingular = array('atlases' => 'atlas',
|
|
||||||
'beefs' => 'beef',
|
|
||||||
'brothers' => 'brother',
|
|
||||||
'children' => 'child',
|
|
||||||
'corpuses' => 'corpus',
|
|
||||||
'cows' => 'cow',
|
|
||||||
'ganglions' => 'ganglion',
|
|
||||||
'genies' => 'genie',
|
|
||||||
'genera' => 'genus',
|
|
||||||
'graffiti' => 'graffito',
|
|
||||||
'hoofs' => 'hoof',
|
|
||||||
'loaves' => 'loaf',
|
|
||||||
'men' => 'man',
|
|
||||||
'monies' => 'money',
|
|
||||||
'mongooses' => 'mongoose',
|
|
||||||
'moves' => 'move',
|
|
||||||
'mythoi' => 'mythos',
|
|
||||||
'numina' => 'numen',
|
|
||||||
'occiputs' => 'occiput',
|
|
||||||
'octopuses' => 'octopus',
|
|
||||||
'opuses' => 'opus',
|
|
||||||
'oxen' => 'ox',
|
|
||||||
'penises' => 'penis',
|
|
||||||
'people' => 'person',
|
|
||||||
'sexes' => 'sex',
|
|
||||||
'soliloquies' => 'soliloquy',
|
|
||||||
'testes' => 'testis',
|
|
||||||
'trilbys' => 'trilby',
|
|
||||||
'turfs' => 'turf',);
|
|
||||||
|
|
||||||
$singularRules = $coreSingularRules;
|
|
||||||
$uninflected = $coreUninflectedSingular;
|
|
||||||
$irregular = $coreIrregularSingular;
|
|
||||||
|
|
||||||
if (file_exists(FRAMEWORK.'/includes/inflections.inc')) {
|
|
||||||
include(FRAMEWORK.'/includes/inflections.inc');
|
|
||||||
$singularRules = array_merge($singularRules, $coreSingularRules);
|
|
||||||
$uninflected = array_merge($uninflectedSingular, $coreUninflectedSingular);
|
|
||||||
$irregular = array_merge($irregularSingular, $coreIrregularSingular);
|
|
||||||
}
|
|
||||||
$regexUninflected = self::enclose(join( '|', $uninflected));
|
|
||||||
$regexIrregular = self::enclose(join( '|', array_keys($irregular)));
|
|
||||||
|
|
||||||
if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
|
|
||||||
return $regs[1] . $irregular[strtolower($regs[2])];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($singularRules as $rule => $replacement) {
|
|
||||||
if (preg_match($rule, $word)) {
|
|
||||||
$replace = preg_replace($rule, $replacement, $word);
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns given $lower_case_and_underscored_word as a camelCased word.
|
|
||||||
*
|
|
||||||
* @param string $lower_case_and_underscored_word Word to camelize
|
|
||||||
* @return string Camelized word. likeThis.
|
|
||||||
*/
|
|
||||||
public static function camelize($lowerCaseAndUnderscoredWord) {
|
|
||||||
$replace = str_replace(" ", "", ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord)));
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns an underscore-syntaxed ($like_this_dear_reader) version of the $camel_cased_word.
|
|
||||||
*
|
|
||||||
* @param string $camel_cased_word Camel-cased word to be "underscorized"
|
|
||||||
* @return string Underscore-syntaxed version of the $camel_cased_word
|
|
||||||
*/
|
|
||||||
public static function underscore($camelCasedWord) {
|
|
||||||
$replace = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns a human-readable string from $lower_case_and_underscored_word,
|
|
||||||
* by replacing underscores with a space, and by upper-casing the initial characters.
|
|
||||||
*
|
|
||||||
* @param string $lower_case_and_underscored_word String to be made more readable
|
|
||||||
* @return string Human-readable string
|
|
||||||
*/
|
|
||||||
public static function humanize($lowerCaseAndUnderscoredWord) {
|
|
||||||
$replace = ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord));
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns corresponding table name for given $class_name. ("posts" for the model class "Post").
|
|
||||||
*
|
|
||||||
* @param string $class_name Name of class to get database table name for
|
|
||||||
* @return string Name of the database table for given class
|
|
||||||
*/
|
|
||||||
public static function tableize($className) {
|
|
||||||
$replace = self::pluralize(self::underscore($className));
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns Cake model class name ("Post" for the database table "posts".) for given database table.
|
|
||||||
*
|
|
||||||
* @param string $tableName Name of database table to get class name for
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function classify($tableName) {
|
|
||||||
$replace = self::camelize(self::singularize($tableName));
|
|
||||||
return $replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns camelBacked version of a string.
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
* @return string
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
public static function variable($string) {
|
|
||||||
$string = self::camelize(self::underscore($string));
|
|
||||||
$replace = strtolower(substr($string, 0, 1));
|
|
||||||
$variable = preg_replace('/\\w/', $replace, $string, 1);
|
|
||||||
return $variable;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns a string with all spaces converted to $replacement and non word characters removed.
|
|
||||||
*
|
|
||||||
* @param string $string
|
|
||||||
* @param string $replacement
|
|
||||||
* @return string
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
public static function slug($string, $replacement = '_') {
|
|
||||||
$string = preg_replace(array('/[^\w\s]/', '/\\s+/') , array(' ', $replacement), $string);
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enclose a string for preg matching.
|
|
||||||
*
|
|
||||||
* @param string $string String to enclose
|
|
||||||
* @return string Enclosed string
|
|
||||||
*/
|
|
||||||
public static function enclose($string) {
|
|
||||||
return '(?:' . $string . ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
|
@ -1,90 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Handles authentication and password handling for all city LDAP people.
|
|
||||||
*
|
|
||||||
* Applications should extend this class for their own users. That way,
|
|
||||||
* a city employee will have the same username and password on all applications.
|
|
||||||
* Applications should use these public functions for their own users.
|
|
||||||
*
|
|
||||||
* @copyright 2006-2012 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
abstract class SystemUser
|
|
||||||
{
|
|
||||||
abstract public function getId();
|
|
||||||
abstract public function getUsername();
|
|
||||||
abstract public function getAuthenticationMethod();
|
|
||||||
abstract public function getRoles();
|
|
||||||
|
|
||||||
abstract public function hasRole($roles);
|
|
||||||
|
|
||||||
abstract public function setAuthenticationMethod($method);
|
|
||||||
abstract public function setRoles($roles);
|
|
||||||
abstract public function setUsername($username);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passwords are set in clear text. The only times you would want to set a password
|
|
||||||
* is when you're adding a new password or changing a person's password.
|
|
||||||
* Either way, it's up to the individual save routines to handle encrypting the new password
|
|
||||||
* before storing it. Passwords should not be loaded in the constructor - they're
|
|
||||||
* supposed to be encrypted, so what's the point?
|
|
||||||
*/
|
|
||||||
abstract public function setPassword($password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to hand authentication off to the application
|
|
||||||
*/
|
|
||||||
abstract protected function authenticateDatabase($password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to hand password saving off to the application
|
|
||||||
*/
|
|
||||||
abstract protected function saveLocalPassword();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines which authentication scheme to use for the user and calls the appropriate method
|
|
||||||
*
|
|
||||||
* @param string $password
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authenticate($password)
|
|
||||||
{
|
|
||||||
switch($this->getAuthenticationMethod()) {
|
|
||||||
case "local":
|
|
||||||
return $this->authenticateDatabase($password);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$type = $this->getAuthenticationMethod();
|
|
||||||
return $type::authenticate($this->getUsername(),$password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establishes a new Session and loads the default information for the user
|
|
||||||
*/
|
|
||||||
public function startNewSession()
|
|
||||||
{
|
|
||||||
session_destroy();
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
$_SESSION['USER'] = $this;
|
|
||||||
$_SESSION['IP_ADDRESS'] = $_SERVER['REMOTE_ADDR'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to save passwords to the database
|
|
||||||
*
|
|
||||||
* Only local passwords should be saved. External Identities should have
|
|
||||||
* their own methods for users to change passwords
|
|
||||||
*/
|
|
||||||
public function savePassword()
|
|
||||||
{
|
|
||||||
switch($this->getAuthenticationMethod()) {
|
|
||||||
case "local":
|
|
||||||
$this->saveLocalPassword();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Defines the overall page layout
|
|
||||||
*
|
|
||||||
* The template collects all the blocks from the controller
|
|
||||||
*
|
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
class Template extends View
|
|
||||||
{
|
|
||||||
private $filename;
|
|
||||||
public $outputFormat = 'html';
|
|
||||||
public $blocks = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $filename
|
|
||||||
* @param string $outputFormat
|
|
||||||
* @param array $vars
|
|
||||||
*/
|
|
||||||
public function __construct($filename='default',$outputFormat='html',array $vars=null)
|
|
||||||
{
|
|
||||||
$this->filename = $filename;
|
|
||||||
$this->outputFormat = preg_replace('/[^a-zA-Z]/','',$outputFormat);
|
|
||||||
|
|
||||||
// Make sure the output format exists
|
|
||||||
if (!is_file(APPLICATION_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc")) {
|
|
||||||
$this->filename = 'default';
|
|
||||||
$this->outputFormat = 'html';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($vars)) {
|
|
||||||
foreach ($vars as $name=>$value) {
|
|
||||||
$this->vars[$name] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all the rendered content of the template
|
|
||||||
*
|
|
||||||
* Template files must include a call to $this->includeBlocks(),
|
|
||||||
* when they're ready for content
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
ob_start();
|
|
||||||
include APPLICATION_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc";
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback function for template files
|
|
||||||
*
|
|
||||||
* Renders blocks for the main content area, unless $panel is given. If $panel is given
|
|
||||||
* it will render any blocks that the controllers have assigned to that panel.
|
|
||||||
*
|
|
||||||
* Template files make calls to this function to render all the blocks that the controller
|
|
||||||
* has loaded for this Template. Controllers will populate the blocks array with content.
|
|
||||||
* If a template file can render content in a panel that is not the main content panel,
|
|
||||||
* the template file will need to include the panel's name in the includeBlocks() call.
|
|
||||||
*
|
|
||||||
* $this->blocks is a multi-dimensional array. The top level elements, non-array elements
|
|
||||||
* are for the default, main content area. Other panels will be arrays in $this->blocks with
|
|
||||||
* the panel name as the key.
|
|
||||||
*
|
|
||||||
* Panels are nothing but a name on a div, the $panel string can be whatever the template
|
|
||||||
* author thinks makes sense. Controllers are expected to know what the template authors
|
|
||||||
* have written.
|
|
||||||
*
|
|
||||||
* $this->blocks[] = "main content block one";
|
|
||||||
* $this->blocks[] = "main content block two";
|
|
||||||
* $this->blocks['panel-one'][] = "left sidebar block one";
|
|
||||||
* $this->blocks['panel-one'][] = "left sidebar block two";
|
|
||||||
* $this->blocks['panel-two'][] = "right sidebar block one";
|
|
||||||
*
|
|
||||||
* @param string $panel
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function includeBlocks($panel=null)
|
|
||||||
{
|
|
||||||
ob_start();
|
|
||||||
if ($panel) {
|
|
||||||
// Render any blocks for the given panel
|
|
||||||
if (isset($this->blocks[$panel]) && is_array($this->blocks[$panel])) {
|
|
||||||
foreach ($this->blocks[$panel] as $block) {
|
|
||||||
echo $block->render($this->outputFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Render only the blocks for the main content area
|
|
||||||
foreach ($this->blocks as $block) {
|
|
||||||
if (!is_array($block)) {
|
|
||||||
echo $block->render($this->outputFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*/
|
|
||||||
abstract class View
|
|
||||||
{
|
|
||||||
protected $vars = array();
|
|
||||||
|
|
||||||
abstract public function render();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Magic Method for setting object properties
|
|
||||||
* @param string $key
|
|
||||||
* @param mixed $value
|
|
||||||
*/
|
|
||||||
public function __set($key,$value) {
|
|
||||||
$this->vars[$key] = $value;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Magic method for getting object properties
|
|
||||||
* @param string $key
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function __get($key)
|
|
||||||
{
|
|
||||||
if (isset($this->vars[$key])) {
|
|
||||||
return $this->vars[$key];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $key
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function __isset($key) {
|
|
||||||
return array_key_exists($key,$this->vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans strings for output
|
|
||||||
*
|
|
||||||
* There are more bad characters than htmlspecialchars deals with. We just want
|
|
||||||
* to add in some other characters to clean. While here, we might as well
|
|
||||||
* have it trim out the whitespace too.
|
|
||||||
*
|
|
||||||
* @param array|string $string
|
|
||||||
* @param CONSTANT $quotes Optional, the desired constant to use for the htmlspecidalchars call
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function escape($input,$quotes=ENT_QUOTES)
|
|
||||||
{
|
|
||||||
if (is_array($input)) {
|
|
||||||
foreach ($input as $key=>$value) {
|
|
||||||
$input[$key] = self::escape($value,$quotes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$input = htmlspecialchars(trim($input),$quotes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $input;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the first $n words of the given string
|
|
||||||
*
|
|
||||||
* @param string $string Source string
|
|
||||||
* @param int $numWords Number of words
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function limitWords($string,$numWords)
|
|
||||||
{
|
|
||||||
$output = '';
|
|
||||||
$words = preg_split('/\s+/',$string);
|
|
||||||
$c = 0;
|
|
||||||
foreach ($words as $word) {
|
|
||||||
$output.= "$word ";
|
|
||||||
$c++;
|
|
||||||
if ($c >= $numWords) {
|
|
||||||
$output.= '...';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright 2009 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
abstract class ZendDbResultIterator implements ArrayAccess,SeekableIterator,Countable
|
|
||||||
{
|
|
||||||
protected $zend_db;
|
|
||||||
protected $select;
|
|
||||||
protected $result = array();
|
|
||||||
|
|
||||||
protected $paginator = null;
|
|
||||||
protected $itemsPerPage = null;
|
|
||||||
protected $currentPage = 1;
|
|
||||||
|
|
||||||
private $valid = false;
|
|
||||||
private $cacheEnabled = true;
|
|
||||||
private $cache = array();
|
|
||||||
private $key;
|
|
||||||
|
|
||||||
|
|
||||||
abstract public function find($fields=null,$order='',$limit=null,$groupBy=null);
|
|
||||||
abstract protected function loadResult($key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an empty collection
|
|
||||||
*
|
|
||||||
* Setting itemsPerPage turns on pagination mode
|
|
||||||
* In pagination mode, this will only load the results for one page
|
|
||||||
*/
|
|
||||||
public function __construct($itemsPerPage=null,$currentPage=null)
|
|
||||||
{
|
|
||||||
$this->zend_db = Database::getConnection();
|
|
||||||
$this->select = new Zend_Db_Select($this->zend_db);
|
|
||||||
|
|
||||||
if ($itemsPerPage) {
|
|
||||||
$this->itemsPerPage = (integer)$itemsPerPage;
|
|
||||||
|
|
||||||
if ($currentPage && $currentPage > 1) {
|
|
||||||
$this->currentPage = $currentPage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the query and stores the results
|
|
||||||
*
|
|
||||||
* In pagination mode, this will only load the results for one page
|
|
||||||
*/
|
|
||||||
protected function populateList()
|
|
||||||
{
|
|
||||||
$this->result = array();
|
|
||||||
if (!$this->itemsPerPage) {
|
|
||||||
$this->result = $this->zend_db->fetchAll($this->select);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Only load the results for one page
|
|
||||||
$this->paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbSelect($this->select));
|
|
||||||
$this->paginator->setItemCountPerPage($this->itemsPerPage);
|
|
||||||
$this->paginator->setCurrentPageNumber($this->currentPage);
|
|
||||||
foreach ($this->paginator as $row) {
|
|
||||||
$this->result[] = $row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getSQL()
|
|
||||||
{
|
|
||||||
return $this->select->__toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Zend_Paginator
|
|
||||||
*/
|
|
||||||
public function getPaginator()
|
|
||||||
{
|
|
||||||
return $this->paginator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array Access section
|
|
||||||
/**
|
|
||||||
* @param int $offset
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function offsetExists($offset) {
|
|
||||||
return array_key_exists($offset,$this->result);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Unimplemented stub requried for interface compliance
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
public function offsetSet($offset,$value) { } // Read-only for now
|
|
||||||
/**
|
|
||||||
* Unimplemented stub requried for interface compliance
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
public function offsetUnset($offset) { } // Read-only for now
|
|
||||||
/**
|
|
||||||
* @param int $offset
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function offsetGet($offset)
|
|
||||||
{
|
|
||||||
if ($this->offsetExists($offset)) {
|
|
||||||
return $this->loadResult($offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new OutOfBoundsException('Invalid seek position');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// SPLIterator Section
|
|
||||||
/**
|
|
||||||
* Reset the pionter to the first element
|
|
||||||
*/
|
|
||||||
public function rewind() {
|
|
||||||
$this->key = 0;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Advance to the next element
|
|
||||||
*/
|
|
||||||
public function next() {
|
|
||||||
$this->key++;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Return the index of the current element
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function key() {
|
|
||||||
return $this->key;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function valid() {
|
|
||||||
return array_key_exists($this->key,$this->result);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function current()
|
|
||||||
{
|
|
||||||
return $this->loadResult($this->key);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param int $index
|
|
||||||
*/
|
|
||||||
public function seek($index)
|
|
||||||
{
|
|
||||||
if (isset($this->result[$index])) {
|
|
||||||
$this->key = $index;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new OutOfBoundsException('Invalid seek position');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Iterator
|
|
||||||
*/
|
|
||||||
public function getIterator()
|
|
||||||
{
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Countable Section
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function count()
|
|
||||||
{
|
|
||||||
return count($this->result);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Global, shared functions for all PHP web applications
|
|
||||||
* @copyright 2006-2009 City of Bloomington, Indiana.
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
|
||||||
* @package GlobalFunctions
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Load classes on the fly as needed
|
|
||||||
* @param string $class
|
|
||||||
*/
|
|
||||||
function autoload($class)
|
|
||||||
{
|
|
||||||
if (file_exists(APPLICATION_HOME."/classes/$class.php")) {
|
|
||||||
require_once(APPLICATION_HOME."/classes/$class.php");
|
|
||||||
}
|
|
||||||
elseif (file_exists(FRAMEWORK."/classes/$class.php")) {
|
|
||||||
require_once(FRAMEWORK."/classes/$class.php");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide nicely formatted error messages when PHP bombs out.
|
|
||||||
*/
|
|
||||||
function customErrorHandler ($errno, $errstr, $errfile, $errline)
|
|
||||||
{
|
|
||||||
global $ERROR_REPORTING;
|
|
||||||
|
|
||||||
if (isset($ERROR_REPORTING)) {
|
|
||||||
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
|
||||||
echo "
|
|
||||||
<div id=\"errorMessages\">
|
|
||||||
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
|
||||||
There is an error in the code on this page that is through no fault of your own.
|
|
||||||
Errors of this sort need to be fixed immediately, though.
|
|
||||||
Please help us out by copying and pasting the following error message into an email and sending it to me at
|
|
||||||
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
|
||||||
</p>
|
|
||||||
<p><strong>Code Error:</strong> Error on line $errline of file $errfile:</p>
|
|
||||||
<p>$errstr</p>
|
|
||||||
</div>
|
|
||||||
";
|
|
||||||
}
|
|
||||||
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
|
||||||
$subject = APPLICATION_NAME.' Error';
|
|
||||||
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
|
||||||
&& isset($_SESSION['USER'])
|
|
||||||
&& $_SESSION['USER']->getEmail()) {
|
|
||||||
$subject = APPLICATION_NAME.' Error';
|
|
||||||
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
mail($_SESSION['USER']->getEmail(),
|
|
||||||
$subject,
|
|
||||||
$message,
|
|
||||||
"From: apache@$_SERVER[SERVER_NAME]");
|
|
||||||
}
|
|
||||||
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
|
||||||
$message = "Error on line $errline of file $errfile:\n$errstr\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
|
|
||||||
$skidder = curl_init(SKIDDER_URL);
|
|
||||||
curl_setopt($skidder,CURLOPT_POST,true);
|
|
||||||
curl_setopt($skidder,CURLOPT_HEADER,true);
|
|
||||||
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
|
||||||
curl_setopt($skidder,
|
|
||||||
CURLOPT_POSTFIELDS,
|
|
||||||
array('application_id'=>SKIDDER_APPLICATION_ID,
|
|
||||||
'script'=>$_SERVER['REQUEST_URI'],
|
|
||||||
'type'=>$errstr,
|
|
||||||
'message'=>$message));
|
|
||||||
curl_exec($skidder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
|
||||||
set_error_handler('customErrorHandler');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Object oriented exceptions are handled differently from other PHP errors.
|
|
||||||
*/
|
|
||||||
function customExceptionHandler($exception)
|
|
||||||
{
|
|
||||||
global $ERROR_REPORTING;
|
|
||||||
|
|
||||||
if (isset($ERROR_REPORTING)) {
|
|
||||||
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
|
||||||
echo "
|
|
||||||
<div id=\"errorMessages\">
|
|
||||||
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
|
||||||
There is an error in the code on this page that is through no fault of your own.
|
|
||||||
Errors of this sort need to be fixed immediately, though.
|
|
||||||
Please help me out by copying and pasting the following error message into an email and sending it to me at
|
|
||||||
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
|
||||||
</p>
|
|
||||||
<p><strong>Uncaught exception:</strong>
|
|
||||||
Exception on line {$exception->getLine()} of file {$exception->getFile()}:
|
|
||||||
</p>
|
|
||||||
<p>{$exception->getMessage()}</p>
|
|
||||||
</div>
|
|
||||||
";
|
|
||||||
}
|
|
||||||
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
|
||||||
$subject = APPLICATION_NAME.' Exception';
|
|
||||||
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
|
||||||
}
|
|
||||||
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
|
||||||
&& isset($_SESSION['USER'])
|
|
||||||
&& $_SESSION['USER']->getEmail()) {
|
|
||||||
$subject = APPLICATION_NAME.' Exception';
|
|
||||||
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
mail($_SESSION['USER']->getEmail(),
|
|
||||||
$subject,
|
|
||||||
$message,
|
|
||||||
"From: apache@$_SERVER[SERVER_NAME]");
|
|
||||||
}
|
|
||||||
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
|
||||||
$message = "Error on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n";
|
|
||||||
$message.= print_r(debug_backtrace(),true);
|
|
||||||
|
|
||||||
$skidder = curl_init(SKIDDER_URL);
|
|
||||||
curl_setopt($skidder,CURLOPT_POST,true);
|
|
||||||
curl_setopt($skidder,CURLOPT_HEADER,true);
|
|
||||||
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
|
||||||
curl_setopt($skidder,
|
|
||||||
CURLOPT_POSTFIELDS,
|
|
||||||
array('application_id'=>SKIDDER_APPLICATION_ID,
|
|
||||||
'script'=>$_SERVER['REQUEST_URI'],
|
|
||||||
'type'=>'Uncaught Exception',
|
|
||||||
'message'=>$message));
|
|
||||||
curl_exec($skidder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
|
||||||
set_exception_handler('customExceptionHandler');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the user is logged in and is supposed to have acces to the resource
|
|
||||||
*
|
|
||||||
* This is implemented by checking against a Zend_Acl object
|
|
||||||
* The Zend_Acl should be created in configuration.inc
|
|
||||||
* @param Zend_Acl_Resource|string $resource
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
function userIsAllowed($resource)
|
|
||||||
{
|
|
||||||
global $ZEND_ACL;
|
|
||||||
if (isset($_SESSION['USER'])) {
|
|
||||||
foreach ($_SESSION['USER']->getRoles() as $role) {
|
|
||||||
if ($ZEND_ACL->isAllowed($role,$resource)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
<?php
|
|
||||||
/* SVN FILE: $Id: inflections.php 3028 2006-06-08 02:18:18Z phpnut $ */
|
|
||||||
/**
|
|
||||||
* Custom Inflected Words.
|
|
||||||
*
|
|
||||||
* This file is used to hold words that are not matched in the normail Inflector::pluralize() and
|
|
||||||
* Inflector::singularize()
|
|
||||||
*
|
|
||||||
* Orinally written by the CakePHP Project
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright (c) 2006, 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.
|
|
||||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*
|
|
||||||
* Modified to work in City of Bloomington's Framework
|
|
||||||
* Relicensed under GPL
|
|
||||||
* Redistributions must retain all copyright notices
|
|
||||||
* @copyright 2006 City of Bloomington, Indiana
|
|
||||||
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This is a key => value array of regex used to match words.
|
|
||||||
* If key matches then the value is returned.
|
|
||||||
*
|
|
||||||
* $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
|
|
||||||
*/
|
|
||||||
$pluralRules = array();
|
|
||||||
/**
|
|
||||||
* This is a key only array of plural words that should not be inflected.
|
|
||||||
* Notice the last comma
|
|
||||||
*
|
|
||||||
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
|
|
||||||
*/
|
|
||||||
$uninflectedPlural = array();
|
|
||||||
/**
|
|
||||||
* This is a key => value array of plural irregular words.
|
|
||||||
* If key matches then the value is returned.
|
|
||||||
*
|
|
||||||
* $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
|
|
||||||
*/
|
|
||||||
$irregularPlural = array();
|
|
||||||
/**
|
|
||||||
* This is a key => value array of regex used to match words.
|
|
||||||
* If key matches then the value is returned.
|
|
||||||
*
|
|
||||||
* $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
|
|
||||||
*/
|
|
||||||
$singularRules = array();
|
|
||||||
/**
|
|
||||||
* This is a key only array of singular words that should not be inflected.
|
|
||||||
* You should not have to change this value below if you do change it use same format
|
|
||||||
* as the $uninflectedPlural above.
|
|
||||||
*/
|
|
||||||
$uninflectedSingular = $uninflectedPlural;
|
|
||||||
/**
|
|
||||||
* This is a key => value array of singular irregular words.
|
|
||||||
* Most of the time this will be a reverse of the above $irregularPlural array
|
|
||||||
* You should not have to change this value below if you do change it use same format
|
|
||||||
*
|
|
||||||
* $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
|
|
||||||
*/
|
|
||||||
$irregularSingular = array_flip($irregularPlural);
|
|
||||||
?>
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 12d6f65aa0ed31e5503c7f7aed13b742dbc35b53
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit b1e33265a731aab365aad59a7263f557d0cfdd08
|
|
@ -0,0 +1,15 @@
|
||||||
|
alter table people add username varchar(40) unique;
|
||||||
|
alter table people add password varchar(40);
|
||||||
|
alter table people add authenticationMethod varchar(40);
|
||||||
|
alter table people add role varchar(30);
|
||||||
|
|
||||||
|
update people p, users u
|
||||||
|
set p.username=u.username, p.authenticationMethod=u.authenticationMethod
|
||||||
|
where p.id=u.person_id;
|
||||||
|
|
||||||
|
update people set role='Staff';
|
||||||
|
update people set role='Administrator' where id=1;
|
||||||
|
|
||||||
|
drop table user_roles;
|
||||||
|
drop table roles;
|
||||||
|
drop table users;
|
|
@ -1,36 +1,16 @@
|
||||||
-- @copyright 2009 City of Bloomington, Indiana
|
-- @copyright 2009-2014 City of Bloomington, Indiana
|
||||||
-- @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
-- @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||||
-- @author Cliff Ingham <inghamn@bloomington.in.gov>
|
-- @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||||
create table people (
|
create table people (
|
||||||
id int unsigned not null primary key auto_increment,
|
id int unsigned not null primary key auto_increment,
|
||||||
firstname varchar(128) not null,
|
firstname varchar(128) not null,
|
||||||
lastname varchar(128) not null,
|
lastname varchar(128) not null,
|
||||||
email varchar(255) not null
|
email varchar(255) not null,
|
||||||
) engine=InnoDB;
|
username varchar(40) unique,
|
||||||
|
password varchar(40),
|
||||||
create table users (
|
authenticationMethod varchar(40),
|
||||||
id int unsigned not null primary key auto_increment,
|
role varchar(30)
|
||||||
person_id int unsigned not null unique,
|
);
|
||||||
username varchar(30) not null unique,
|
|
||||||
password varchar(32),
|
|
||||||
authenticationMethod varchar(40) not null default 'LDAP',
|
|
||||||
foreign key (person_id) references people(id)
|
|
||||||
) engine=InnoDB;
|
|
||||||
|
|
||||||
create table roles (
|
|
||||||
id int unsigned not null primary key auto_increment,
|
|
||||||
name varchar(30) not null unique
|
|
||||||
) engine=InnoDB;
|
|
||||||
insert roles values(1,'Administrator');
|
|
||||||
insert roles values(2,'Editor');
|
|
||||||
|
|
||||||
create table user_roles (
|
|
||||||
user_id int unsigned not null,
|
|
||||||
role_id int unsigned not null,
|
|
||||||
primary key (user_id,role_id),
|
|
||||||
foreign key(user_id) references users (id),
|
|
||||||
foreign key(role_id) references roles (id)
|
|
||||||
) engine=InnoDB;
|
|
||||||
|
|
||||||
create table cemeteries (
|
create table cemeteries (
|
||||||
id int unsigned not null primary key auto_increment,
|
id int unsigned not null primary key auto_increment,
|
||||||
|
|
Loading…
Reference in New Issue