Updated libraries to latest version
This commit is contained in:
parent
8b4eacd1e1
commit
baad9f58c1
|
@ -1,4 +1,6 @@
|
|||
configuration.inc
|
||||
site_config.inc
|
||||
build
|
||||
dist
|
||||
data/sessions/*
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
[submodule "html/js/yui3"]
|
||||
path = html/js/yui3
|
||||
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
|
||||
/**
|
||||
* Used to keep sessions on the same webserver seperate;
|
||||
*/
|
||||
define('APPLICATION_NAME','application_name');
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* Multi-Site support
|
||||
*
|
||||
* 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('ADMINISTRATOR_EMAIL','admin@servername.com');
|
||||
define('SITE_HOME', !empty($_SERVER['SITE_HOME']) ? $_SERVER['SITE_HOME'] : __DIR__.'/data');
|
||||
include SITE_HOME.'/site_config.inc';
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
*
|
||||
* 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','CUSTOM');
|
||||
//$ERROR_REPORTING = array('PRETTY_PRINT','SKIDDER');
|
||||
|
||||
/**
|
||||
* Skidder is a web service for error notifications. Error reporting supports
|
||||
* 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_APPLICATION_ID',);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Bootstrap code
|
||||
// No editing is usually needed after this point
|
||||
//-------------------------------------------------------------------
|
||||
/**
|
||||
* Database Setup
|
||||
* Refer to the PDO documentation for DSN sytnax for your database type
|
||||
* http://www.php.net/manual/en/pdo.drivers.php
|
||||
* Enable autoloading for the PHP libraries
|
||||
*/
|
||||
define('DB_ADAPTER','Pdo_Mysql');
|
||||
define('DB_HOST','localhost');
|
||||
define('DB_NAME',APPLICATION_NAME);
|
||||
define('DB_USER',APPLICATION_NAME);
|
||||
define('DB_PASS','password');
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
// 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');
|
||||
require_once ZEND.'/Loader/AutoloaderFactory.php';
|
||||
$config = [
|
||||
'Zend\Loader\StandardAutoloader' => [
|
||||
'namespaces' => [
|
||||
'Application' => APPLICATION_HOME,
|
||||
'Blossom' => BLOSSOM,
|
||||
'Zend' => ZEND
|
||||
]
|
||||
]
|
||||
];
|
||||
Zend\Loader\AutoloaderFactory::factory($config);
|
||||
|
||||
/**
|
||||
* Session Startup
|
||||
|
@ -113,27 +71,21 @@ spl_autoload_register('autoload');
|
|||
* We only want sessions when PHP code is executed from the webserver
|
||||
*/
|
||||
if (!defined('STDIN')) {
|
||||
ini_set('session.save_path',APPLICATION_HOME.'/data/sessions');
|
||||
ini_set('session.save_path', SITE_HOME.'/sessions');
|
||||
session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
||||
set_error_handler ('Blossom\Classes\Error::customErrorHandler');
|
||||
set_exception_handler('Blossom\Classes\Error::customExceptionHandler');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
namespace Blossom\Classes;
|
||||
use Zend\Db\Adapter\Adapter;
|
||||
|
||||
class Database
|
||||
{
|
||||
private static $connection;
|
||||
|
@ -21,13 +24,13 @@ class Database
|
|||
}
|
||||
if (!self::$connection) {
|
||||
try {
|
||||
$parameters = array('host'=>DB_HOST,
|
||||
$parameters = array('driver' =>DB_ADAPTER,
|
||||
'hostname'=>DB_HOST,
|
||||
'username'=>DB_USER,
|
||||
'password'=>DB_PASS,
|
||||
'dbname'=>DB_NAME,
|
||||
'options'=>array(Zend_Db::AUTO_QUOTE_IDENTIFIERS=>false));
|
||||
self::$connection = Zend_Db::factory(DB_ADAPTER,$parameters);
|
||||
self::$connection->getConnection();
|
||||
'database' =>DB_NAME,
|
||||
'charset' =>'utf8');
|
||||
self::$connection = new Adapter($parameters);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
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
|
||||
/**
|
||||
* @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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
namespace Blossom\Classes;
|
||||
|
||||
interface ExternalIdentity
|
||||
{
|
||||
|
@ -25,15 +26,11 @@ interface ExternalIdentity
|
|||
* @return string
|
||||
*/
|
||||
public function getFirstname();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
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)
|
||||
*
|
||||
* @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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
namespace Blossom\Classes;
|
||||
|
||||
class Paginator implements ArrayAccess,SeekableIterator,Countable
|
||||
{
|
||||
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;
|
||||
* 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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class URL
|
||||
namespace Blossom\Classes;
|
||||
|
||||
class Url
|
||||
{
|
||||
private $scheme;
|
||||
private $host;
|
||||
|
@ -20,26 +22,43 @@ class URL
|
|||
|
||||
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)
|
||||
{
|
||||
$script = urldecode($script);
|
||||
|
||||
// If scheme wasn't provided add one to the start of the string
|
||||
if (!preg_match('|://|',$script)) {
|
||||
$scheme = $_SERVER['SERVER_PORT']==443 ? 'https://' : 'http://';
|
||||
if (!strpos(substr($script,0,20),'://')) {
|
||||
$scheme = (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']==443)
|
||||
? 'https://'
|
||||
: 'http://';
|
||||
$script = $scheme.$script;
|
||||
}
|
||||
|
||||
$url = parse_url($script);
|
||||
$this->scheme = $url['scheme'];
|
||||
$this->host = $url['host'];
|
||||
$this->path = $url['path'];
|
||||
if (isset($url['fragment'])) {
|
||||
$this->anchor = $url['fragment'];
|
||||
}
|
||||
if (isset($url['query'])) {
|
||||
parse_str($url['query'],$this->parameters);
|
||||
}
|
||||
if (isset($url['host'])) { $this->host = $url['host']; }
|
||||
if (isset($url['path'])) { $this->path = $url['path']; }
|
||||
if (isset($url['fragment'])) { $this->anchor = $url['fragment']; }
|
||||
if (isset($url['query'])) { parse_str($url['query'],$this->parameters); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +102,7 @@ class URL
|
|||
*/
|
||||
public function getScheme() {
|
||||
if (!$this->scheme) {
|
||||
$this->scheme = 'http://';
|
||||
$this->scheme = 'http';
|
||||
}
|
||||
return $this->scheme;
|
||||
}
|
||||
|
@ -94,9 +113,7 @@ class URL
|
|||
*/
|
||||
public function setScheme($string)
|
||||
{
|
||||
if (!preg_match('|://|',$string)) {
|
||||
$string .= '://';
|
||||
}
|
||||
$string = preg_replace('|://|', '', $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
|
||||
/**
|
||||
* @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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param Zend_Paginator $this->pages
|
||||
* @param Zend\Paginator $this->paginator
|
||||
*/
|
||||
if ($this->pages->pageCount > 1) {
|
||||
$url = new URL($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
|
||||
use Blossom\Classes\Url;
|
||||
|
||||
if ($this->paginator->count() > 1) {
|
||||
$pages = $this->paginator->getPages();
|
||||
|
||||
$url = new Url($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
|
||||
$url->purgeEmptyParameters();
|
||||
|
||||
echo '<ul class="pageNavigation">';
|
||||
|
||||
// Show the Back button
|
||||
if (isset($this->pages->previous)) {
|
||||
$url->page = $this->pages->first;
|
||||
if (isset($pages->previous)) {
|
||||
$url->page = $pages->first;
|
||||
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>";
|
||||
}
|
||||
// Show the page number links
|
||||
// Show only $maxNumLinks pages at a time
|
||||
foreach ($this->pages->pagesInRange as $page) {
|
||||
foreach ($pages->pagesInRange as $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>";
|
||||
}
|
||||
|
||||
// Show the Next button
|
||||
if (isset($this->pages->next)) {
|
||||
$url->page = $this->pages->next;
|
||||
if (isset($pages->next)) {
|
||||
$url->page = $pages->next;
|
||||
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>";
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
<?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
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
use Blossom\Classes\Block;
|
||||
|
||||
if (isset($_SESSION['errorMessages'])) {
|
||||
$errorBlock = new Block('errorMessages.inc',array('errorMessages'=>$_SESSION['errorMessages']));
|
||||
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
|
||||
-- @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
create table people (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
firstname varchar(128) not null,
|
||||
lastname varchar(128) not null,
|
||||
email varchar(255) not null
|
||||
) engine=InnoDB;
|
||||
|
||||
create table users (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
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;
|
||||
id int unsigned not null primary key auto_increment,
|
||||
firstname varchar(128) not null,
|
||||
lastname varchar(128) not null,
|
||||
email varchar(255) not null,
|
||||
username varchar(40) unique,
|
||||
password varchar(40),
|
||||
authenticationMethod varchar(40),
|
||||
role varchar(30)
|
||||
);
|
||||
|
||||
create table cemeteries (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
|
|
Loading…
Reference in New Issue