initial commit

This commit is contained in:
Michael Becker 2023-11-01 23:10:09 -04:00
parent 9151934c83
commit 6c87446672
121 changed files with 15623 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
app/include/Configuration.inc.php

10
app/.htaccess Normal file
View File

@ -0,0 +1,10 @@
RewriteEngine On
# Do not remove this line, otherwise mod_rewrite rules will stop working
# RewriteBase /
RewriteRule ^StyleSheets/(.*)\.css$ lessc.php?filename=$1 [PT,L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?virtualpath=$1 [PT,L,QSA]

View File

@ -0,0 +1,14 @@
<?php
use Phast\System;
// Here you define some common application configuration...
System::$Configuration["Application.Title"] = "PHP Hypertext Application Server Technology";
System::$Configuration["Paths.Pages"] = [ "/ui/pages" ];
// Your normal Configuration.inc.php would not be included in your repository,
// as it may contain sensitive information such as database passwords, etc.
//
// Please add it to your .gitignore !
?>

39
app/index.php Normal file
View File

@ -0,0 +1,39 @@
<?php
// =============================================================================
// Phast bootstrapper - loads the application modules and executes Phast
// Copyright (C) 2013-2023 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// =============================================================================
// Load the Phast content (which also include_once's the system modules and
// other Phast-specific stuff)
require_once("lib/phast/System.inc.php");
// Bring in the Phast\System and Phast\IncludeFile classes so we can simply refer
// to them (in this file only) as "System" and "IncludeFile", respectively, from
// now on
use Phast\System;
use Phast\IncludeFile;
// We need to set the root path of the Web site. It's usually something like
// /var/www/yourdomain.com.
System::SetApplicationPath(dirname(__FILE__));
// Tell Phast that we are ready to launch the application. This searches the entire
// directory hierarchy for Phast files, loading *.phpx files as Phast XML files and
// *.phpx.php files as PHP code-behind files. We may decide to use the *.ctlx extension
// (and its associated *.ctlx.php) for PHPX controls.
System::Launch();
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Phast;
/**
* Provides data for a cancelable event.
* @author Michael Becker
*/
class CancelEventArgs extends EventArgs
{
/**
* True if the event should be canceled; false otherwise.
* @var boolean
*/
public $Cancel;
}
?>

View File

@ -0,0 +1,99 @@
<?php
namespace Phast\Compilers\StyleSheet\Internal\Formatters;
class ClassicFormatter
{
public $indentChar = " ";
public $break = "\n";
public $open = " {";
public $close = "}";
public $selectorSeparator = ", ";
public $assignSeparator = ":";
public $openSingle = " { ";
public $closeSingle = " }";
public $disableSingle = false;
public $breakSelectors = false;
public $compressColors = false;
public function __construct() {
$this->indentLevel = 0;
}
public function indentStr($n = 0) {
return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
}
public function property($name, $value) {
return $name . $this->assignSeparator . $value . ";";
}
protected function isEmpty($block) {
if (empty($block->lines)) {
foreach ($block->children as $child) {
if (!$this->isEmpty($child)) return false;
}
return true;
}
return false;
}
public function block($block) {
if ($this->isEmpty($block)) return;
$inner = $pre = $this->indentStr();
$isSingle = !$this->disableSingle &&
is_null($block->type) && count($block->lines) == 1;
if (!empty($block->selectors)) {
$this->indentLevel++;
if ($this->breakSelectors) {
$selectorSeparator = $this->selectorSeparator . $this->break . $pre;
} else {
$selectorSeparator = $this->selectorSeparator;
}
echo $pre .
implode($selectorSeparator, $block->selectors);
if ($isSingle) {
echo $this->openSingle;
$inner = "";
} else {
echo $this->open . $this->break;
$inner = $this->indentStr();
}
}
if (!empty($block->lines)) {
$glue = $this->break.$inner;
echo $inner . implode($glue, $block->lines);
if (!$isSingle && !empty($block->children)) {
echo $this->break;
}
}
foreach ($block->children as $child) {
$this->block($child);
}
if (!empty($block->selectors)) {
if (!$isSingle && empty($block->children)) echo $this->break;
if ($isSingle) {
echo $this->closeSingle . $this->break;
} else {
echo $pre . $this->close . $this->break;
}
$this->indentLevel--;
}
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
namespace Phast\Compilers\StyleSheet\Internal\Formatters;
require_once ("ClassicFormatter.inc.php");
class CompressedFormatter extends ClassicFormatter
{
public $disableSingle = true;
public $open = "{";
public $selectorSeparator = ",";
public $assignSeparator = ":";
public $break = "";
public $compressColors = true;
public function indentStr($n = 0)
{
return "";
}
}
?>

View File

@ -0,0 +1,11 @@
<?php
namespace Phast\Compilers\StyleSheet\Internal\Formatters;
class LessJSFormatter extends ClassicFormatter
{
public $disableSingle = true;
public $breakSelectors = true;
public $assignSeparator = ": ";
public $selectorSeparator = ",";
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
<?php
namespace Phast\Conditionals;
use Phast\Enumeration;
class ConditionalComparison extends Enumeration
{
/**
* The variable is equal to the given value.
* @var ConditionalStatementComparison 1
*/
const Equals = 1;
}
?>

View File

@ -0,0 +1,17 @@
<?php
namespace Phast\Conditionals;
class ConditionalStatement
{
public $Name;
public $Comparison;
public $Value;
public function __construct($name, $comparison, $value)
{
$this->Name = $name;
$this->Comparison = $comparison;
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,183 @@
<?php
namespace Phast\Configuration;
use UniversalEditor\ObjectModels\Markup\XMLParser;
use UniversalEditor\ObjectModels\Markup\MarkupTagElement;
class ConfigurationParser
{
/**
* The Flavor which stores configuration data common to all flavors.
* @var Flavor
*/
public $CommonFlavor;
/**
* The flavors available in this configuration.
* @var Flavor[]
*/
public $Flavors;
public function __construct()
{
$this->CommonFlavor = new Flavor();
$this->Flavors = array();
}
public function RetrieveGroup($path, $pathSeparator = ".")
{
}
public function RetrieveGroupExact($path, $pathSeparator = ".")
{
}
/**
* Retrieves the property defined by the specified path for the currently
* active flavor. All path parts before the last path part are considered to be groups.
* @param string $name The name of the property to search for.
* @param mixed $defaultValue The value to return if the property cannot be found.
*/
public function RetrieveProperty($name, $defaultValue = null)
{
$flavor = $this->GetCurrentFlavor();
if ($flavor == null) return new Property($name, $defaultValue);
$property = $flavor->RetrieveProperty($name, $defaultValue);
if ($property == null)
{
// property was not found in the active flavor; try the common
// flavor
$flavor = $this->CommonFlavor;
$property = $flavor->RetrieveProperty($name, $defaultValue);
}
return $property;
}
/**
* Retrieves the currently-active configuration flavor.
* @return Flavor|NULL The currently-active configuration flavor, or NULL if no configuration flavor is currently active.
*/
public function GetCurrentFlavor()
{
foreach ($this->Flavors as $flavor)
{
if ($flavor->HostName != null && $flavor->HostName == $_SERVER["SERVER_NAME"])
{
return $flavor;
}
}
return null;
}
/**
* Loads the group from the given MarkupTagElement into the specified parent.
* @param MarkupTagElement $tag
* @param Group|ConfigurationParser $parent
* @return boolean True if the load was successful; false if an error occurred.
*/
private function LoadGroup($tag, $parent)
{
if (!$tag->HasAttribute("ID")) return false;
$group = new Group();
$group->Name = $tag->GetAttribute("ID")->Value;
$elems = $tag->GetElements();
foreach ($elems as $elem)
{
$this->LoadTag($elem, $group);
}
$parent->Groups[] = $group;
return true;
}
private function LoadProperty($tag, $parent)
{
if (!$tag->HasAttribute("ID")) return false;
$id = $tag->GetAttribute("ID")->Value;
if ($tag->HasAttribute("Value"))
{
$parent->UpdatePropertyValue($id, $tag->GetAttribute("Value")->Value);
return true;
}
else if (count($tag->Elements) == 1)
{
$parent->UpdatePropertyValue($id, $tag->Elements[0]->GetInnerMarkup());
return true;
}
else
{
$parent->UpdatePropertyValue($id, $tag->GetInnerMarkup());
return true;
}
return false;
}
/**
*
* @param MarkupTagElement $tag
* @param ConfigurationParser|Group $parent
*/
private function LoadTag($tag, $parent)
{
if ($tag->Name == "Group")
{
$this->LoadGroup($tag, $parent);
}
else if ($tag->Name == "Property")
{
$this->LoadProperty($tag, $parent);
}
}
public function LoadFile($filename)
{
$parser = new XMLParser();
$markup = $parser->LoadFile($filename);
$tagWebsite = $markup->GetElement("Website");
$tagCommon = $tagWebsite->GetElement("Common");
if ($tagCommon != null)
{
$tagConfiguration = $tagCommon->GetElement("Configuration");
if ($tagConfiguration != null)
{
$tags = $tagConfiguration->GetElements();
foreach ($tags as $tag)
{
$this->LoadTag($tag, $this->CommonFlavor);
}
}
}
$tagFlavors = $tagWebsite->GetElement("Flavors");
if ($tagFlavors != null)
{
foreach ($tagFlavors->Elements as $elem)
{
$flavor = new Flavor();
$flavor->Name = $elem->GetAttribute("ID")->Value;
if ($elem->HasAttribute("HostName"))
{
$flavor->HostName = $elem->GetAttribute("HostName")->Value;
}
$tagConfiguration = $elem->GetElement("Configuration");
if ($tagConfiguration != null)
{
$tags = $tagConfiguration->GetElements();
foreach ($tags as $tag)
{
$this->LoadTag($tag, $flavor);
}
}
$this->Flavors[] = $flavor;
}
}
$this->GetCurrentFlavor();
}
}
?>

View File

@ -0,0 +1,61 @@
<?php
namespace Phast\Configuration;
class Flavor
{
public $Name;
/**
* Groups of Properties and other Groups in this Flavor.
* @var Group[]
*/
public $Groups;
public $Properties;
public $HostName;
public function __construct()
{
$this->Groups = array();
$this->Properties = array();
$this->HostName = null;
}
public function RetrieveGroup($name)
{
foreach ($this->Groups as $group)
{
if ($group->Name == $name) return $group;
}
$group = new Group();
$group->Name = $name;
$this->Groups[] = $name;
return $group;
}
public function RetrieveProperty($name, $defaultValue = null)
{
foreach ($this->Properties as $property)
{
if ($property->Name == $name) return $property;
}
$property = new Property();
$property->Name = $name;
$property->Value = $defaultValue;
$this->Properties[] = $property;
return $property;
}
public function RetrievePropertyValue($name, $defaultValue = null)
{
$property = $this->RetrieveProperty($name, $defaultValue);
return $property->Value;
}
public function UpdatePropertyValue($name, $value)
{
$property = $this->RetrieveProperty($name, $value);
$property->Value = $value;
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
namespace Phast\Configuration;
class Group
{
public $Name;
public $Groups;
public $Properties;
public function __construct()
{
$this->Groups = array();
$this->Properties = array();
}
public function RetrieveGroup($name)
{
foreach ($this->Groups as $group)
{
if ($group->Name == $name) return $group;
}
$group = new Group();
$group->Name = $name;
$this->Groups[] = $name;
return $group;
}
public function RetrieveProperty($name, $defaultValue = null)
{
foreach ($this->Properties as $property)
{
if ($property->Name == $name) return $property;
}
$property = new Property();
$property->Name = $name;
$property->Value = $defaultValue;
$this->Properties[] = $property;
return $property;
}
public function RetrievePropertyValue($name, $defaultValue = null)
{
$property = $this->RetrieveProperty($name, $defaultValue);
return $property->Value;
}
public function UpdatePropertyValue($name, $value)
{
$property = $this->RetrieveProperty($name, $value);
$property->Value = $value;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
namespace Phast\Configuration;
class Property
{
/**
* The name of this Property.
* @var string
*/
public $ID;
/**
* The value of this Property.
* @var string
*/
public $Value;
public function __construct($id = null, $value = null)
{
$this->ID = $id;
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,13 @@
<?php
namespace Phast\Configuration\V1;
class ConfigurationComment extends ConfigurationItem
{
public $Value;
public function __construct($value)
{
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,8 @@
<?php
namespace Phast\Configuration\V1;
abstract class ConfigurationItem
{
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast\Configuration\V1;
class ConfigurationProperty extends ConfigurationItem
{
public $ID;
public $Value;
public function __construct($id, $value = null)
{
$this->ID = $id;
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,8 @@
<?php
namespace Phast\Configuration\V1;
class ConfigurationSpacer extends ConfigurationItem
{
}
?>

View File

@ -0,0 +1,67 @@
<?php
namespace Phast\Data;
/**
* Represents a column on a Table.
* @author Michael Becker
* @see Table
*/
class Column
{
/**
* The name of the column.
* @var string
*/
public $Name;
/**
* The data type of the column.
* @var string
*/
public $DataType;
/**
* The maximum size of the data in the column.
* @var int
*/
public $Size;
/**
* The default value of the column.
* @var string
*/
public $DefaultValue;
/**
* True if the column should allow null values; false otherwise.
* @var boolean
*/
public $AllowNull;
/**
* True if the column is a primary key; false otherwise.
* @var boolean
*/
public $PrimaryKey;
/**
* True if the column should automatically increment its value when a row is added; false otherwise.
* @var boolean
*/
public $AutoIncrement;
/**
* Creates a Column with the specified values.
* @param string $name The name of the column.
* @param string $dataType The data type of the column.
* @param string $size The maximum size of the data in the column. Default null.
* @param string $defaultValue The default value of the column. Default null.
* @param boolean $allowNull True if the column should allow null values; false otherwise. Default false.
* @param boolean $primaryKey True if the column is a primary key; false otherwise. Default false.
* @param boolean $autoIncrement True if the column should automatically increment its value when a row is added; false otherwise. Default false.
*/
public function __construct($name, $dataType, $size = null, $defaultValue = null, $allowNull = false, $primaryKey = false, $autoIncrement = false)
{
$this->Name = $name;
$this->DataType = $dataType;
$this->Size = $size;
$this->DefaultValue = $defaultValue;
$this->AllowNull = $allowNull;
$this->PrimaryKey = $primaryKey;
$this->AutoIncrement = $autoIncrement;
}
}
?>

View File

@ -0,0 +1,107 @@
<?php
namespace Phast\Data;
class DataObject
{
public static function Create($name, $prefix, $_)
{
// Fetch the arguments of the function
$args = func_get_args();
// Exclude the "name" and "prefix" arguments from the array of function arguments,
// so only the property definitions names remain in the array
array_shift($args);
array_shift($args);
$args = $args[0];
// UPDATE 2013-08-23 14:52 by BECKERMJ - it now supports enums in namespaces!
$classDeclaration = "";
$realName = $name;
$ns = null;
$nses = explode("\\", $realName);
$nsc = count($nses);
if ($nsc > 1)
{
$realName = $nses[$nsc - 1];
$ns = "";
for ($i = 0; $i < $nsc - 1; $i++)
{
$ns .= $nses[$i];
if ($i < $nsc - 2) $ns .= "\\";
}
$classDeclaration = "namespace " . $ns . "; \n";
}
// Generate the code of the class for this enumeration
$classDeclaration .= "class " . $realName . " { \n";
foreach ($args as $arg)
{
$classDeclaration .= "\tpublic \$" . $arg->Name . ";\n";
}
$classDeclaration .= "\n\tpublic static function GetByAssoc(\$values)\n\t{\n";
$classDeclaration .= "\t\t\$item = new " . $name . "();\n\n";
foreach($args as $arg)
{
$classDeclaration .= "\t\t\$item->" . $arg->Name . " = \$values[\"" . $prefix . $arg->Name . "\"];\n";
}
$classDeclaration .= "\n\t\treturn \$item;\n";
$classDeclaration .= "\t}\n";
/*
public function ToJSON()
{
$json = "{";
$json .= "\"ID\":" . $this->ID . ",";
$json .= "\"Title\":\"" . \JH\Utilities::JavaScriptDecode($this->Title,"\"") . "\",";
$json .= "\"URL\":\"" . \JH\Utilities::JavaScriptDecode($this->URL,"\"") . "\"";
$json .= "}";
return $json;
}
*/
$classDeclaration .= "\n\tpublic function ToJSON()\n\t{\n";
$classDeclaration .= "\t\t\$json = \"{\";\n\n";
foreach($args as $arg)
{
$classDeclaration .= "\t\t\$json .= \"\\\"" . $arg->Name . "\\\":\";\n";
$classDeclaration .= "\t\tif (gettype(\$this->" . $arg->Name . ") == \"string\")\n\t\t{";
$classDeclaration .= "\n\t\t\t\$json .= \"\\\"\" . \$MySQL->real_escape_string(\$this->" . $arg->Name . ") . \"\\\"\";\n\t\t";
$classDeclaration .= "}\n\t\telse\n\t\t{";
$classDeclaration .= "\n\t\t\t\$json .= \$this->" . $arg->Name . ";\n\t\t";
$classDeclaration .= "}\n\n ";
// .= \" . \\JH\\Utilities::JavaScriptDecode(\$this->" . $arg . ",\"\\\") . "\"\\\",\"">" . $arg . " = \$values[\$this->GetTablePrefix() . \"" . $arg . "\"];\n";
}
$classDeclaration .= "\t\t\$json .= \"}\";\n\n";
$classDeclaration .= "\n\t\treturn \$json;\n";
$classDeclaration .= "\t}\n";
$classDeclaration .= "\n\tpublic function Get(\$max = null)\n\t{\n";
$classDeclaration .= "\t\tglobal \$MySQL;\n";
$classDeclaration .= "\t\t\$query = \"SELECT * FROM \" . System::GetConfigurationValue(\"Database.TablePrefix\") . \"StartPages\";\n";
$classDeclaration .= "\t\tif (is_numeric(\$max)) \$query .= \" LIMIT \" . \$max;\n";
$classDeclaration .= "\t\t\$result = \$MySQL->query(\$query);\n";
$classDeclaration .= "\t\t\$count = \$result->num_rows;\n";
$classDeclaration .= "\t\t\$retval = array();\n";
$classDeclaration .= "\t\tfor (\$i = 0; \$i < \$count; \$i++)\n";
$classDeclaration .= "\t\t{\n";
$classDeclaration .= "\t\t\t\$values = \$result->fetch_assoc();\n";
$classDeclaration .= "\t\t\t\$retval[] = " . $name . "::GetByAssoc(\$values);\n";
$classDeclaration .= "\t\t}\n";
$classDeclaration .= "\t\treturn \$retval;\n";
$classDeclaration .= "\t}\n";
$classDeclaration .= "}";
// Create the class for this enumeration
eval($classDeclaration);
echo($classDeclaration);
// Create the class for this enumeration
// eval($classDeclaration);
}
}
?>

View File

@ -0,0 +1,95 @@
<?php
namespace Phast\Data;
use Phast\System;
use Phast\Enumeration;
use PDO;
abstract class ColumnValue extends Enumeration
{
const Undefined = 0;
const Now = 1;
const Today = 2;
const CurrentTimestamp = 3;
}
require_once("Column.inc.php");
require_once("DataObject.inc.php");
require_once("DatabaseOperationResult.inc.php");
require_once("Record.inc.php");
require_once("RecordColumn.inc.php");
require_once("SelectResult.inc.php");
require_once("Table.inc.php");
require_once("TableForeignKey.inc.php");
require_once("TableKey.inc.php");
require_once("TableSelectCriteria.inc.php");
include_once("Traits/DataObject.inc.php");
class DataSystem
{
/**
* @var DataErrorCollection
*/
public static $Errors;
private static $_PDO = null;
/**
* Returns the currently-loaded PDO engine.
* @return \PDO The currently-loaded PDO engine.
*/
public static function GetPDO()
{
if (DataSystem::$_PDO == null)
{
$engine = 'mysql';
$host = System::GetConfigurationValue("Database.ServerName");
$database = System::GetConfigurationValue("Database.DatabaseName");
$user = System::GetConfigurationValue("Database.UserName");
$pass = System::GetConfigurationValue("Database.Password");
$dns = $engine . ':dbname=' . $database . ";host=" . $host;
DataSystem::$_PDO = new PDO($dns, $user, $pass);
}
return DataSystem::$_PDO;
}
}
DataSystem::$Errors = new DataErrorCollection();
class DataError
{
public $Code;
public $Message;
public $Query;
public function __construct($code, $message, $query = null)
{
$this->Code = $code;
$this->Message = $message;
$this->Query = $query;
}
}
class DataErrorCollection
{
public function __construct()
{
$this->Clear();
}
/**
*
* @var DataError[]
*/
public $Items;
public function Add($item)
{
$this->Items[] = $item;
}
public function Clear()
{
$this->Items = array();
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
namespace Phast\Data;
class DatabaseOperationResult
{
public $AffectedRowCount;
public function __construct($affectedRowCount)
{
$this->AffectedRowCount = $affectedRowCount;
}
}
class InsertResult extends DatabaseOperationResult
{
public $LastInsertID;
public function __construct($affectedRowCount, $lastInsertId)
{
parent::__construct($affectedRowCount);
$this->LastInsertID = $lastInsertId;
}
}
?>

View File

@ -0,0 +1,42 @@
<?php
namespace Phast\Data;
/**
* Represents a record on a Table.
* @author Michael Becker
* @see Table
* @see RecordColumn
*/
class Record
{
/**
* The column values for this record.
* @var RecordColumn[]
*/
public $Columns;
/**
* Retrieves the RecordColumn with the specified name for this record.
* @param string $name
* @return RecordColumn|NULL The RecordColumn with the specified name, or NULL if no RecordColumn with the specified name was found.
* @see RecordColumn
*/
public function GetColumnByName($name)
{
foreach ($this->Columns as $column)
{
if ($column->Name == $name) return $column;
}
return null;
}
/**
* Creates a Record object with the specified column values, but does not insert the record into a table.
* @param RecordColumn[] $columns The column values to associate with this Record.
*/
public function __construct($columns = null)
{
if ($columns == null) $columns = array();
$this->Columns = $columns;
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Phast\Data;
/**
* Associates a column name with a value for a record on a table.
* @author Michael Becker
* @see Record
* @see Column
*/
class RecordColumn
{
/**
* The name of the column for which to associate a value.
* @var string
*/
public $Name;
/**
* The value to associate.
* @var unknown
*/
public $Value;
/**
* Creates a RecordColumn with the specified values.
* @param string $name The name of the column for which to associate a value.
* @param unknown $value The value to associate.
*/
public function __construct($name, $value)
{
$this->Name = $name;
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,12 @@
<?php
namespace Phast\Data;
class SelectResult
{
/**
* The records returned from this SELECT statement.
* @var Record[]
*/
public $Records;
}
?>

View File

@ -0,0 +1,610 @@
<?php
namespace Phast\Data;
use Phast\System;
use PDO;
use Phast\Conditionals\ConditionalComparison;
use Phast\StringMethods;
/**
* Represents a table on the database.
* @author Michael Becker
* @see Column
* @see Record
* @see TableForeignKey
*/
class Table
{
/**
* The name of the table.
* @var string
*/
public $Name;
/**
* The prefix used before the name of each column in the table.
* @var string
*/
public $ColumnPrefix;
/**
* The columns on the table.
* @var Column[]
*/
public $Columns;
/**
* The records in the table.
* @var Record[]
*/
public $Records;
/**
* The key that is the primary key of the table.
* @var TableKey
*/
public $PrimaryKey;
/**
* The key(s) that are the unique keys of the table.
* @var TableForeignKey[]
*/
public $UniqueKeys;
/**
* Any additional key(s) on the table that are not primary or unique keys.
* @var TableForeignKey[]
*/
public $ForeignKeys;
/**
* Creates a Table object with the given parameters (but does not create the table on the database).
* @param string $name The name of the table.
* @param string $columnPrefix The prefix used before the name of each column in the table.
* @param Column[] $columns The column(s) of the table.
* @param Record[] $records The record(s) to insert into the table.
*/
public function __construct($name, $columnPrefix, $columns, $records = null)
{
$this->Name = $name;
$this->ColumnPrefix = $columnPrefix;
$this->Columns = $columns;
if ($records == null) $records = array();
$this->Records = $records;
$this->PrimaryKey = null;
$this->UniqueKeys = array();
$this->ForeignKeys = array();
}
/**
* Gets the table with the specified name from the database.
* @param string $name The name of the table to search for.
* @param string $columnPrefix The column prefix for the columns in the table. Columns that begin with this prefix will be populated with the prefix stripped.
* @return Table The table with the specified name.
*/
public static function Get($name, $columnPrefix = null)
{
$pdo = DataSystem::GetPDO();
$query = "SHOW COLUMNS FROM " . System::GetConfigurationValue("Database.TablePrefix") . $name;
$statement = $pdo->prepare($query);
$result = $statement->execute();
$count = $statement->rowCount();
$columns = array();
for ($i = 0; $i < $count; $i++)
{
$values = $statement->fetch(PDO::FETCH_ASSOC);
$columnName = $values["Field"];
if (substr($columnName, 0, strlen($columnPrefix)) == $columnPrefix)
{
$columnName = substr($columnName, strlen($columnPrefix));
}
$dataTypeNameAndSize = $values["Type"];
$dataTypeName = substr($dataTypeNameAndSize, 0, strpos($dataTypeNameAndSize, "("));
$dataTypeSize = substr($dataTypeNameAndSize, strpos($dataTypeNameAndSize, "("), strlen($dataTypeNameAndSize) - strpos($dataTypeNameAndSize, "(") - 2);
$defaultValue = $values["Default"];
$allowNull = ($values["Null"] == "YES");
$primaryKey = ($values["Key"] == "PRI");
$autoIncrement = ($values["Extra"] == "auto_increment");
$columns[] = new Column($columnName, $dataTypeName, $dataTypeSize, $defaultValue, $allowNull, $primaryKey, $autoIncrement);
}
return new Table($name, $columnPrefix, $columns);
}
/**
* Creates the table on the database.
* @return boolean True if the table was created successfully; false if an error occurred.
*/
public function Create()
{
$pdo = DataSystem::GetPDO();
$query = "CREATE TABLE " . System::$Configuration["Database.TablePrefix"] . $this->Name;
$query .= "(";
$count = count($this->Columns);
for ($i = 0; $i < $count; $i++)
{
$column = $this->Columns[$i];
$query .= ($this->ColumnPrefix . $column->Name) . " " . $column->DataType;
if ($column->Size != null)
{
$query .= "(" . $column->Size . ")";
}
if ($column->AllowNull == false)
{
$query .= " NOT NULL";
}
if ($column->DefaultValue != null)
{
$query .= " DEFAULT ";
if ($column->DefaultValue === ColumnValue::Undefined)
{
$query .= "NULL";
}
else if ($column->DefaultValue === ColumnValue::CurrentTimestamp)
{
$query .= "CURRENT_TIMESTAMP";
}
else if (is_string($column->DefaultValue))
{
$query .= "\"" . $column->DefaultValue . "\"";
}
else
{
$query .= $column->DefaultValue;
}
}
if ($column->PrimaryKey)
{
$query .= " PRIMARY KEY";
}
if ($column->AutoIncrement)
{
$query .= " AUTO_INCREMENT";
}
if ($i < $count - 1) $query .= ", ";
}
$count = count($this->ForeignKeys);
if ($count > 0)
{
$query .= ", ";
for ($i = 0; $i < $count; $i++)
{
$fk = $this->ForeignKeys[$i];
$query .= "FOREIGN KEY ";
if ($fk->ID != null)
{
$query .= $fk->ID . " ";
}
$query .= "(";
if (is_array($fk->ColumnName))
{
$columnNameCount = count($fk->ColumnName);
for ($j = 0; $j < $columnNameCount; $j++)
{
$query .= $this->ColumnPrefix . $fk->ColumnName[$j];
if ($j < $columnNameCount - 1) $query .= ", ";
}
}
else
{
$query .= $this->ColumnPrefix . $fk->ColumnName;
}
$query .= ")";
$query .= " REFERENCES " . System::GetConfigurationValue("Database.TablePrefix") . $fk->ForeignColumnReference->Table->Name . " (";
if (is_array($fk->ForeignColumnReference->Column))
{
$foreignColumnReferenceCount = count($fk->ForeignColumnReference->Column);
for ($j = 0; $j < $foreignColumnReferenceCount; $j++)
{
$query .= $fk->ForeignColumnReference->Table->ColumnPrefix;
if (is_string($fk->ForeignColumnReference->Column[$j]))
{
$query .= $fk->ForeignColumnReference->Column[$j];
}
else
{
$query .= $fk->ForeignColumnReference->Column[$j]->Name;
}
if ($j < $foreignColumnReferenceCount - 1) $query .= ", ";
}
}
else
{
$query .= $fk->ForeignColumnReference->Table->ColumnPrefix . $fk->ForeignColumnReference->Column->Name;
}
$query .= ")";
$query .= " ON DELETE ";
switch ($fk->DeleteAction)
{
case TableForeignKeyReferenceOption::Restrict:
{
$query .= "RESTRICT";
break;
}
case TableForeignKeyReferenceOption::Cascade:
{
$query .= "CASCADE";
break;
}
case TableForeignKeyReferenceOption::SetNull:
{
$query .= "SET NULL";
break;
}
case TableForeignKeyReferenceOption::NoAction:
{
$query .= "NO ACTION";
break;
}
}
$query .= " ON UPDATE ";
switch ($fk->DeleteAction)
{
case TableForeignKeyReferenceOption::Restrict:
{
$query .= "RESTRICT";
break;
}
case TableForeignKeyReferenceOption::Cascade:
{
$query .= "CASCADE";
break;
}
case TableForeignKeyReferenceOption::SetNull:
{
$query .= "SET NULL";
break;
}
case TableForeignKeyReferenceOption::NoAction:
{
$query .= "NO ACTION";
break;
}
}
if ($i < $count - 1) $query .= ", ";
}
}
$query .= ")";
$statement = $pdo->prepare($query);
$result = $statement->execute();
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
return false;
}
if ($this->PrimaryKey != null)
{
$key = $this->PrimaryKey;
$query = "ALTER TABLE `" . System::$Configuration["Database.TablePrefix"] . $this->Name . "` ADD PRIMARY KEY (";
$count = count($key->Columns);
for ($i = 0; $i < $count; $i++)
{
$col = $key->Columns[$i];
$query .= "`" . $this->ColumnPrefix . $col->Name . "`";
if ($i < $count - 1)
{
$query .= ", ";
}
}
$query .= ");";
$statement = $pdo->prepare($query);
$result = $statement->execute();
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
return false;
}
}
foreach ($this->UniqueKeys as $key)
{
$query = "ALTER TABLE `" . System::$Configuration["Database.TablePrefix"] . $this->Name . "` ADD UNIQUE (";
$count = count($key->Columns);
for ($i = 0; $i < $count; $i++)
{
$col = $key->Columns[$i];
$query .= "`" . $this->ColumnPrefix . $col->Name . "`";
if ($i < $count - 1)
{
$query .= ", ";
}
}
$query .= ")";
$statement = $pdo->prepare($query);
$result = $statement->execute();
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
return false;
}
}
if ($this->Records != null)
{
$result = $this->Insert($this->Records);
if ($result == null)
{
return false;
}
}
return true;
}
public function Select(TableSelectCriteria $criteria)
{
$columnNames = "*";
if (is_array($criteria->ColumnNames))
{
$count = count($criteria->ColumnNames);
if ($count > 0)
{
$columnNames = "";
for ($i = 0; $i < $count; $i++)
{
$columnNames .= $criteria->ColumnNames[$i];
if ($i < $count - 1) $columnNames .= ", ";
}
}
}
$query = "SELECT " . $columnNames . " FROM " . System::GetConfigurationValue("Database.TablePrefix") . $this->Name;
if (is_array($criteria->Conditions))
{
$count = count($criteria->Conditions);
if ($count > 0)
{
$query .= " WHERE ";
for ($i = 0; $i < $count; $i++)
{
$conditionalStatement = $criteria->Conditions[$i];
$query .= "(";
$query .= $this->ColumnPrefix . $conditionalStatement->Name . " ";
switch ($conditionalStatement->Comparison)
{
case ConditionalComparison::Equals:
{
$query .= "=";
break;
}
}
$query .= " ";
$query .= ":conditionalStatement" . $i;
$query .= ")";
if ($i < $count - 1)
{
$query .= " AND ";
}
}
}
}
$conditionalStatementCriteria = array();
$count = count($criteria->Conditions);
for ($i = 0; $i < $count; $i++)
{
$conditionalStatement = $criteria->Conditions[$i];
$conditionalStatementCriteria[":conditionalStatement" . $i] = $conditionalStatement->Value;
}
$pdo = DataSystem::GetPDO();
$statement = $pdo->prepare($query);
$result = $statement->execute($conditionalStatementCriteria);
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
return false;
}
$count = $statement->rowCount();
$selectResult = new SelectResult();
for ($i = 0; $i < $count; $i++)
{
$record = new Record();
$values = $statement->fetch(PDO::FETCH_ASSOC);
foreach ($values as $key => $value)
{
if (StringMethods::StartsWith($key, $this->ColumnPrefix)) $key = substr($key, strlen($this->ColumnPrefix));
$record->Columns[] = new RecordColumn($key, $value);
}
$selectResult->Records[] = $record;
}
return $selectResult;
}
/**
*
* @param Record[] $records The record(s) to insert into the table.
* @param boolean $stopOnError True if processing of the records should stop if an error occurs; false to continue.
* @return NULL|InsertResult
*/
public function Insert($records, $stopOnError = true)
{
DataSystem::$Errors->Clear();
$pdo = DataSystem::GetPDO();
$rowCount = 0;
$lastInsertId = 0;
if (!is_array($records))
{
if (get_class($records) == "Phast\\Data\\Record")
{
// single record
$records = array($records);
}
else
{
trigger_error("Table::Insert() called, but $records is not an array or single Record!");
return false;
}
}
foreach ($records as $record)
{
$query = "INSERT INTO " . System::GetConfigurationValue("Database.TablePrefix") . $this->Name;
$query .= " (";
$count = count($record->Columns);
for ($i = 0; $i < $count; $i++)
{
$column = $record->Columns[$i];
$query .= ($this->ColumnPrefix . $column->Name);
if ($i < $count - 1) $query .= ", ";
}
$query .= " ) VALUES ( ";
for ($i = 0; $i < $count; $i++)
{
$query .= ":" . $record->Columns[$i]->Name;
if ($i < $count - 1) $query .= ", ";
}
$query .= ")";
$statement = $pdo->prepare($query);
$values = array();
for ($i = 0; $i < $count; $i++)
{
$column = $record->Columns[$i];
$name = ":" . $column->Name;
if ($column->Value === null || $column->Value === ColumnValue::Undefined)
{
$values[$name] = null;
}
else if ($column->Value === ColumnValue::Now)
{
$values[$name] = "NOW()";
}
else if ($column->Value === ColumnValue::CurrentTimestamp)
{
$values[$name] = "CURRENT_TIMESTAMP";
}
else if ($column->Value === ColumnValue::Today)
{
$values[$name] = "TODAY()";
}
else if (gettype($column->Value) == "string")
{
$values[$name] = $column->Value;
}
else if (gettype($column->Value) == "object")
{
if (get_class($column->Value) == "DateTime")
{
$values[$name] = date_format($column->Value, "Y-m-d H:i:s");
}
else
{
$values[$name] = $column->Value;
}
}
else
{
$values[$name] = $column->Value;
}
}
$result = $statement->execute($values);
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
if ($stopOnError) return null;
}
else
{
$rowCount += $statement->rowCount();
$lastInsertId = $pdo->lastInsertId();
}
}
return new InsertResult($rowCount, $lastInsertId);
}
/**
* Deletes this table from the database.
* @return boolean True if the table was deleted successfully; false otherwise.
*/
public function Delete()
{
$pdo = DataSystem::GetPDO();
$query = "DROP TABLE " . System::$Configuration["Database.TablePrefix"] . $this->Name;
$statement = $pdo->prepare($query);
$result = $statement->execute();
if ($result === false)
{
$ei = $statement->errorInfo();
trigger_error("DataSystem error: (" . $ei[1] . ") " . $ei[2]);
trigger_error("DataSystem query: " . $query);
DataSystem::$Errors->Clear();
DataSystem::$Errors->Add(new DataError($ei[1], $ei[2], $query));
return false;
}
return true;
}
/**
* Determines if this table exists on the database.
* @return boolean True if this table exists; false otherwise.
*/
public function Exists()
{
$pdo = DataSystem::GetPDO();
$query = "SHOW TABLES LIKE '" . System::$Configuration["Database.TablePrefix"] . $this->Name . "'";
$statement = $pdo->prepare($query);
$result = $statement->execute();
if ($result !== false)
{
return ($statement->rowCount() > 0);
}
return false;
}
/**
* Retrieves the Column with the given name on this Table.
* @param string $name The name of the column to search for.
* @return Column|NULL The column with the given name, or NULL if no columns with the given name were found.
*/
public function GetColumnByName($name)
{
foreach ($this->Columns as $column)
{
if ($column->Name == $name) return $column;
}
return null;
}
}
?>

View File

@ -0,0 +1,94 @@
<?php
namespace Phast\Data;
use Phast\Enumeration;
abstract class TableForeignKeyReferenceOption extends Enumeration
{
const NoAction = 0;
const Restrict = 1;
const Cascade = 2;
const SetNull = 3;
}
/**
* Defines a relationship to a column in another table.
* @author Michael Becker
*/
class TableForeignKey
{
/**
* The ID of the foreign key. Can be null.
* @var string
*/
public $ID;
/**
* The name of the column in the source table.
* @var string
*/
public $ColumnName;
/**
* The reference(s) to the foreign column(s) in the foreign table(s).
* @var TableForeignKeyColumn
*/
public $ForeignColumnReference;
/**
* The action to take when a value in this column is deleted.
* @var TableForeignKeyReferenceOption
*/
public $DeleteAction;
/**
* The action to take when a value in this column is updated.
* @var TableForeignKeyReferenceOption
*/
public $UpdateAction;
/**
*
* @param unknown $columnName
* @param TableForeignKeyColumn[] $foreignColumnReference The column(s) included in this foreign key.
* @param string $deleteAction
* @param string $updateAction
* @param string $id
*/
public function __construct($columnName, $foreignColumnReference, $deleteAction = null, $updateAction = null, $id = null)
{
$this->ID = $id;
$this->ColumnName = $columnName;
$this->ForeignColumnReference = $foreignColumnReference;
if ($deleteAction == null) $deleteAction = TableForeignKeyReferenceOption::Restrict;
$this->DeleteAction = $deleteAction;
if ($updateAction == null) $updateAction = TableForeignKeyReferenceOption::Restrict;
$this->UpdateAction = $updateAction;
}
}
class TableForeignKeyColumn
{
/**
* The table that contains the foreign column.
* @var Table
*/
public $Table;
/**
* A reference to the foreign column(s), or the name of the foreign column(s).
* @var string|Column|string[]|Column[]
*/
public $Column;
/**
* Creates a TableForeignKeyColumn with the given parameters.
* @param Table $table The table that contains the foreign column.
* @param string|Column $column A reference to the foreign column, or the name of the foreign column.
*/
public function __construct($table, $column)
{
$this->Table = $table;
if (is_string($column))
{
$column = $table->GetColumnByName($column);
}
$this->Column = $column;
}
}
?>

View File

@ -0,0 +1,30 @@
<?php
namespace Phast\Data;
use Phast\System;
class TableKey
{
public $Columns;
public function __construct($columns)
{
if (is_array($columns))
{
$this->Columns = $columns;
}
else
{
$this->Columns = array();
}
}
}
class TableKeyColumn
{
public $Name;
public function __construct($name)
{
$this->Name = $name;
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
namespace Phast\Data;
use Phast\Conditionals\ConditionalStatement;
class TableSelectCriteria
{
/**
* The names of the columns to return, or NULL to return all columns.
* @var string[]
*/
public $ColumnNames;
/**
* The conditions for this select statement.
* @var ConditionalStatement[]
*/
public $Conditions;
}
?>

View File

@ -0,0 +1,68 @@
<?php
namespace Phast\Data\Traits;
use Phast\Data\DataSystem;
use Phast\System;
use PDO;
trait DataObjectTrait
{
public static $DataObjectTableName;
public static $DataObjectColumnPrefix;
/**
* Called when a property on the DataObject is being bound to a data column.
* @param string $columnName The name of the column to bind.
* @param mixed $value The value to assign to the column.
* @return boolean True if the data binding was handled by this function; false otherwise.
*/
protected function BindDataColumn($columnName, $value)
{
return false;
}
public static function GetByAssoc($values)
{
$columnNames = array_keys($values);
$columnPrefix = self::$DataObjectColumnPrefix;
$columnCount = count($columnNames);
$item = new self();
for ($j = 0; $j < $columnCount; $j++)
{
$columnName = $columnNames[$j];
$realColumnName = $columnName;
if (stripos($realColumnName, $columnPrefix) === 0)
{
$realColumnName = substr($realColumnName, strlen($columnPrefix));
}
if (!$item->BindDataColumn($realColumnName, $values[$columnName]))
{
$item->{$realColumnName} = $values[$columnName];
}
}
return $item;
}
/**
* Returns all the instances of this DataObject.
*/
public static function Get()
{
$pdo = DataSystem::GetPDO();
$query = "SELECT * FROM " . (System::GetConfigurationValue("Database.TablePrefix") . self::$DataObjectTableName);
$statement = $pdo->prepare($query);
$statement->execute();
$count = $statement->rowCount();
$retval = array();
for ($i = 0; $i < $count; $i++)
{
$values = $statement->fetch(PDO::FETCH_ASSOC);
$item = self::GetByAssoc($values);
$retval[] = $item;
}
return $retval;
}
}
?>

View File

@ -0,0 +1,56 @@
<?php
namespace Phast;
/**
* Provides the base class for a full-featured Enumeration in PHP.
*
* @author Brian Cline, Robert Harvey @ stackoverflow.com
* @link http://stackoverflow.com/questions/254514/php-and-enumerations
*/
class Enumeration
{
private static $constCacheArray = NULL;
public static function GetValues()
{
if (self::$constCacheArray == NULL)
{
self::$constCacheArray = array();
}
$calledClass = get_called_class();
if (!array_key_exists($calledClass, self::$constCacheArray))
{
$reflect = new ReflectionClass($calledClass);
self::$constCacheArray[$calledClass] = $reflect->getConstants();
}
return self::$constCacheArray[$calledClass];
}
/**
* Determines if this enumeration contains the specified name.
* @param string $name The name of the enum value to search for.
* @param boolean $caseSensitive True if the search should be case-sensitive; false otherwise.
*/
public static function ContainsName($name, $caseSensitive = false)
{
$constants = self::GetValues();
if ($caseSensitive)
{
return array_key_exists($name, $constants);
}
$keys = array_map('strtolower', array_keys($constants));
return in_array(strtolower($name), $keys);
}
/**
* Determines if this enumeration contains the specified value.
* @param unknown $value The enum value to search for.
*/
public static function ContainsValue($value)
{
$values = array_values(self::GetValues());
return in_array($value, $values, $strict = true);
}
}
?>

View File

@ -0,0 +1,17 @@
<?php
namespace Phast;
class EventArgs
{
private static $_empty;
public static function GetEmptyInstance()
{
if (EventArgs::$_empty == null)
{
EventArgs::$_empty = new EventArgs();
}
return EventArgs::$_empty;
}
}
?>

View File

@ -0,0 +1,21 @@
<?php
namespace Phast;
class HTMLControl extends WebControl
{
public $InnerHTML;
public function __construct($tagName = null)
{
parent::__construct();
$this->TagName = $tagName;
}
protected function RenderContent()
{
echo($this->InnerHTML);
}
}
require_once("HTMLControls/Literal.inc.php");
?>

View File

@ -0,0 +1,61 @@
<?php
namespace Phast\HTMLControls;
use Phast\System;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
/**
* Provides an HTMLControl for the <A> HTML tag.
* @author Michael Becker
*/
class Anchor extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "a";
}
/**
* The URL to navigate to when this anchor is activated.
* @var string
*/
public $TargetURL;
/**
* The script to execute when this anchor is activated.
* @var string
*/
public $TargetScript;
/**
* The frame in which to open the associated TargetURL.
* @var string
*/
public $TargetFrame;
protected function RenderBeginTag()
{
if ($this->TargetURL != null)
{
$this->Attributes[] = new WebControlAttribute("href", System::ExpandRelativePath($this->TargetURL));
if ($this->TargetFrame != null)
{
$this->Attributes[] = new WebControlAttribute("target", $this->TargetFrame);
}
}
else
{
$this->Attributes[] = new WebControlAttribute("href", "#");
}
if ($this->TargetScript != null)
{
$this->Attributes[] = new WebControlAttribute("onclick", $this->TargetScript);
}
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Footer extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "footer";
}
}
?>

View File

@ -0,0 +1,108 @@
<?php
namespace Phast\HTMLControls;
use Phast\Enumeration;
use Phast\HTMLControl;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
/**
* Provides an enumeration of predefined values for method of form submission.
* @author Michael Becker
*/
abstract class FormMethod extends Enumeration
{
/**
* No method is specified
* @var int 0
*/
const None = 0;
/**
* Will use the HTTP GET method
* @var int 1
*/
const Get = 1;
/**
* Will use the HTTP POST method
* @var int 2
*/
const Post = 2;
}
class Form extends HTMLControl
{
public function __construct($id = null, $method = FormMethod::None)
{
parent::__construct($id);
$this->TagName = "form";
$this->Method = $method;
}
/**
* The URL to direct the user to upon form submission.
* @var string
*/
public $Action;
/**
* The method of form submission.
* @var FormMethod
*/
public $Method;
/**
* The type of encoding used to submit this form. Known values are "application/x-www-form-urlencoded" (the default) and "multipart/form-data" (used in combination with the file input element.
* @var string
*/
public $EncodingType;
protected function RenderBeginTag()
{
if ($this->Action != null)
{
$this->Attributes[] = new WebControlAttribute("action", System::ExpandRelativePath($this->Action));
}
if ($this->EncodingType != null)
{
$this->Attributes[] = new WebControlAttribute("enctype", $this->EncodingType);
}
if (is_string($this->Method))
{
switch (strtolower($this->Method))
{
case "get":
{
$this->Method = FormMethod::Get;
break;
}
case "post":
{
$this->Method = FormMethod::Post;
break;
}
}
}
if ($this->Method != FormMethod::None)
{
$methodstr = "";
switch ($this->Method)
{
case FormMethod::Get:
{
$methodstr = "GET";
break;
}
case FormMethod::Post:
{
$methodstr = "POST";
break;
}
}
$this->Attributes[] = new WebControlAttribute("method", $methodstr);
}
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,52 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
class HTMLControlSelectOption
{
public $Title;
public $Value;
public $Selected;
public function __construct($title, $value = null, $selected = false)
{
$this->Title = $title;
$this->Value = $value;
$this->Selected = $selected;
}
}
class HTMLControlSelect extends HTMLControl
{
public $Items;
public function __construct()
{
parent::__construct();
$this->TagName = "select";
$this->Items = array();
}
protected function RenderContent()
{
foreach ($this->Items as $item)
{
$tag = new HTMLControl();
$tag->TagName = "option";
if ($item->Value != null)
{
$tag->Attributes[] = new WebControlAttribute("value", $item->Value);
}
$tag->InnerHTML = $item->Title;
if ($item->Selected)
{
$tag->Attributes[] = new WebControlAttribute("selected", "selected");
}
$tag->Render();
}
}
}
?>

View File

@ -0,0 +1,61 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
use Phast\WebControl;
class HTMLControlTable extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "table";
}
public function BeginHeader()
{
echo("<thead>");
}
public function EndHeader()
{
echo("</thead>");
}
public function BeginBody()
{
echo("<tbody>");
}
public function EndBody()
{
echo("</tbody>");
}
public function BeginRow($namedParameters = null)
{
WebControl::BeginTag("tr", $namedParameters);
}
public function EndRow()
{
WebControl::EndTag("tr");
}
public function BeginCell($namedParameters = null)
{
WebControl::BeginTag("td", $namedParameters);
}
public function EndCell()
{
WebControl::EndTag("td");
}
public function BeginHeaderCell($namedParameters = null)
{
WebControl::BeginTag("th", $namedParameters);
}
public function EndHeaderCell()
{
WebControl::EndTag("th");
}
}
?>

View File

@ -0,0 +1,42 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
class HTMLControlTextArea extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "textarea";
$this->HasContent = true;
}
public $Name;
public $Value;
public $PlaceholderText;
public $Rows;
public $Columns;
protected function RenderBeginTag()
{
if (isset($this->ID)) $this->Attributes[] = new WebControlAttribute("id", $this->ID);
if (isset($this->Name)) $this->Attributes[] = new WebControlAttribute("name", $this->Name);
if (isset($this->PlaceholderText)) $this->Attributes[] = new WebControlAttribute("placeholder", $this->PlaceholderText);
if (isset($this->Rows)) $this->Attributes[] = new WebControlAttribute("rows", $this->Rows);
if (isset($this->Columns)) $this->Attributes[] = new WebControlAttribute("cols", $this->Columns);
parent::RenderBeginTag();
}
protected function RenderContent()
{
if (isset($this->Value))
{
echo($this->Value);
}
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Header extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "header";
}
}
?>

View File

@ -0,0 +1,22 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Heading extends HTMLControl
{
public $Level;
public function __construct()
{
parent::__construct();
$this->Level = 1;
}
public function RenderBeginTag()
{
$this->TagName = "h" . $this->Level;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Phast\HTMLControls;
use Phast\System;
use Phast\HTMLControl;
use Phast\WebControlAttribute;
use Phast\WebScript;
class Image extends HTMLControl
{
public $AlternateText;
public $ImageUrl;
public function __construct()
{
parent::__construct();
$this->TagName = "img";
$this->HasContent = false;
}
protected function OnInitialize()
{
if ($this->AlternateText != "")
{
$this->Attributes[] = new WebControlAttribute("alt", $this->AlternateText);
}
if ($this->ImageUrl != "")
{
$this->Attributes[] = new WebControlAttribute("src", System::ExpandRelativePath($this->ImageUrl));
}
}
}
?>

View File

@ -0,0 +1,125 @@
<?php
namespace Phast\HTMLControls;
use Phast\Enumeration;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
/**
* Provides an enumeration of predefined values for type of input.
* @author Michael Becker
*/
abstract class InputType extends Enumeration
{
/**
* No type is specified
* @var int 0
*/
const None = 0;
/**
* Text
* @var int 1
*/
const Text = 1;
/**
* Password
* @var int 2
*/
const Password = 2;
/**
* CheckBox
* @var int 3
*/
const CheckBox = 3;
/**
* RadioButton
* @var int 4
*/
const RadioButton = 4;
/**
* Number
* @var int 5
*/
const Number = 5;
/**
* Hidden
* @var int 9
*/
const Hidden = 9;
/**
* Submit
* @var int 10
*/
const Submit = 10;
}
class Input extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "input";
$this->HasContent = false;
}
public $Name;
public $Type;
public $Value;
public $PlaceholderText;
protected function RenderBeginTag()
{
switch ($this->Type)
{
case "Text":
case InputType::Text:
{
$this->Attributes[] = new WebControlAttribute("type", "text");
break;
}
case "Password":
case InputType::Password:
{
$this->Attributes[] = new WebControlAttribute("type", "password");
break;
}
case "CheckBox":
case InputType::CheckBox:
{
$this->Attributes[] = new WebControlAttribute("type", "checkbox");
break;
}
case "RadioButton":
case InputType::RadioButton:
{
$this->Attributes[] = new WebControlAttribute("type", "radio");
break;
}
case "Number":
case InputType::Number:
{
$this->Attributes[] = new WebControlAttribute("type", "number");
break;
}
case "Hidden":
case InputType::Hidden:
{
$this->Attributes[] = new WebControlAttribute("type", "hidden");
break;
}
case "Submit":
case InputType::Submit:
{
$this->Attributes[] = new WebControlAttribute("type", "submit");
break;
}
}
if (isset($this->Name)) $this->Attributes[] = new WebControlAttribute("name", $this->Name);
if (isset($this->Value)) $this->Attributes[] = new WebControlAttribute("value", $this->Value);
if (isset($this->PlaceholderText)) $this->Attributes[] = new WebControlAttribute("placeholder", $this->PlaceholderText);
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,14 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Layer extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "div";
}
}
?>

View File

@ -0,0 +1,27 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\System;
class Literal extends HTMLControl
{
public $Value;
public function __construct($value = null)
{
parent::__construct();
if ($value == null) $value = "";
$this->Value = $value;
}
protected function RenderContent()
{
echo(System::ExpandRelativePath($this->Value));
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Navigation extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "nav";
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast\HTMLControls;
use Phast\HTMLControl;
class Paragraph extends HTMLControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "p";
}
}
?>

View File

@ -0,0 +1,9 @@
<?php
namespace Phast;
class Orientation extends Enumeration
{
const Horizontal = 1;
const Vertical = 2;
}
?>

View File

@ -0,0 +1,23 @@
<?php
namespace Phast\Pages;
require_once("MessagePage.inc.php");
class ErrorPage extends MessagePage
{
protected function BeforeContent()
{
parent::BeforeContent();
?>
<div class="Icon ErrorIcon">&nbsp;</div>
<div class="Title">Application error</div>
<?php
}
protected function AfterContent()
{
?>
<?php
parent::AfterContent();
}
}
?>

View File

@ -0,0 +1,21 @@
<?php
namespace Phast\Pages;
class MessagePage extends \Phast\WebPage
{
public $Message;
protected function BeforeContent()
{
?><div class="Message"><?php
}
protected function RenderContent()
{
?><div class="Content"><?php echo($this->Message); ?></div><?php
}
protected function AfterContent()
{
?></div><?php
}
}
?>

View File

@ -0,0 +1,301 @@
<?php
namespace Phast\Parser;
use Phast\HTMLControl;
use Phast\HTMLControls\Literal;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\WebPageMessage;
use Phast\WebPageMessageSeverity;
use Phast\System;
use UniversalEditor\ObjectModels\Markup\MarkupElement;
use UniversalEditor\ObjectModels\Markup\MarkupTagElement;
class ControlLoader
{
public static $Messages;
public static $Namespaces;
/**
* Parses the children of the specified MarkupElement into the specified object.
* @param MarkupTagElement $elem
* @param WebControl $obj
*/
public static function ParseChildren($elem, &$obj)
{
// our parent is a WebControl and we should parse its children as properties
if (is_array($elem->Elements))
{
foreach ($elem->Elements as $elem1)
{
if (get_class($elem1) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
if (!is_array($elem1->Elements))
{
trigger_error("\$elem1->Elements not array for tag '" . $elem1->Name . "'");
continue;
}
foreach ($elem1->Elements as $elem2)
{
if (get_class($elem2) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
$i = stripos($elem2->Name, ":");
if ($i === false)
{
$prefix = "";
$name = $elem2->Name;
}
else
{
$prefix = substr($elem2->Name, 0, $i);
$name = substr($elem2->Name, $i + 1);
}
if (isset(ControlLoader::$Namespaces[$prefix]) && ControlLoader::$Namespaces[$prefix] != "")
{
$realname = ControlLoader::$Namespaces[$prefix] . "\\" . $name;
}
else
{
$realname = $name;
}
if ($prefix == "")
{
// assume regular HTML control
$obj1 = new HTMLControl($name);
foreach ($elem2->Attributes as $att)
{
$obj1->Attributes[] = new WebControlAttribute($att->Name, $att->Value);
}
if ($elem2->GetInnerMarkup() == "")
{
// we have to make some compromises; AFAIK the SCRIPT tag is the only
// tag that doesn't know how to properly handle close /> tag
$obj1->HasContent = false;
}
}
else
{
if (class_exists($realname))
{
$obj1 = new $realname();
}
else
{
ControlLoader::$Messages[] = new WebPageMessage("Unknown class " . $realname . " (" . $prefix . ":" . $name . ")", WebPageMessageSeverity::Error);
System::WriteErrorLog("Unknown class " . $realname . " (" . $prefix . ":" . $name . ")");
continue;
}
}
ControlLoader::LoadAttributes($elem2, $obj1);
$parseChildElements = false;
if (isset($obj1->ParseChildElements))
{
$parseChildElements = $obj1->ParseChildElements;
}
if ($parseChildElements)
{
ControlLoader::ParseChildren($elem2, $obj1);
}
else
{
if (is_array($elem2->Elements))
{
foreach ($elem2->Elements as $elem3)
{
ControlLoader::LoadControl($elem3, $obj1);
}
}
}
$obj->{$elem1->Name}[] = $obj1;
}
}
}
}
public static function LoadAttributes($elem, &$obj)
{
if (is_array($elem->Attributes))
{
foreach ($elem->Attributes as $attr)
{
$obj->{$attr->Name} = $attr->Value;
}
}
}
public static function GetPHPXAttributes($elem)
{
$attrs = array();
if (is_array($elem->Attributes))
{
foreach ($elem->Attributes as $attr)
{
$attrs[$attr->Name] = $attr->Value;
}
}
if (count($elem->Elements) == 1 && get_class($elem->Elements[0]) == "UniversalEditor\\ObjectModels\\Markup\\MarkupLiteralElement")
{
$attrs["Content"] = $elem->Elements[0]->Value;
$elem->Elements = array();
}
return $attrs;
}
public static function LoadPHPXControlAttributes($attrs, &$obj)
{
foreach ($obj->Attributes as $att)
{
foreach ($attrs as $name => $value)
{
if (is_string($att->Value) && stripos($att->Value, "\$(Control:" . $name . ")") !== false)
{
$att->Value = str_replace("\$(Control:" . $name . ")", $value, $att->Value);
}
}
}
foreach ($obj as $key => $val)
{
foreach ($attrs as $name => $value)
{
if (is_string($val) && stripos($val, "\$(Control:" . $name . ")") !== false)
{
$obj->{$key} = str_replace("\$(Control:" . $name . ")", $value, $val);
}
}
}
foreach ($obj->Controls as $ctl)
{
ControlLoader::LoadPHPXControlAttributes($attrs, $ctl);
}
}
/**
* Creates a WebControl from markup in a MarkupElement.
* @param MarkupElement $elem The MarkupElement to parse.
* @param WebControl $parent The WebControl that owns this control.
*/
public static function LoadControl($elem, $parent)
{
if (get_class($elem) == "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement")
{
$i = stripos($elem->Name, ":");
if ($i !== false)
{
$prefix = substr($elem->Name, 0, $i);
$name = substr($elem->Name, $i + 1);
if (isset(ControlLoader::$Namespaces[$prefix]) && ControlLoader::$Namespaces[$prefix] != "")
{
$realname = ControlLoader::$Namespaces[$prefix] . "\\" . $name;
}
else
{
$realname = $name;
}
if (class_exists($realname))
{
$obj = new $realname();
}
else
{
$basectl = System::$Parser->GetControlByVirtualTagPath($realname);
if ($basectl !== null)
{
$ctl = clone $basectl;
$obj = $ctl;
}
else
{
ControlLoader::$Messages[] = new WebPageMessage("Unknown class " . $realname . " (" . $prefix . ":" . $name . ")", WebPageMessageSeverity::Error);
return;
}
}
$loadedFromVTP = false;
if (isset($obj->VirtualTagPath))
{
if ($obj->VirtualTagPath != null)
{
$attrs = ControlLoader::GetPHPXAttributes($elem);
$loadedFromVTP = true;
}
}
if (!$loadedFromVTP)
{
ControlLoader::LoadAttributes($elem, $obj);
}
if (is_subclass_of($obj, "Phast\\WebControl") && $obj->ParseChildElements)
{
ControlLoader::ParseChildren($elem, $obj);
}
else
{
if (is_array($elem->Elements))
{
foreach ($elem->Elements as $elem1)
{
ControlLoader::LoadControl($elem1, $obj);
}
}
}
if (isset($obj->VirtualTagPath))
{
if ($obj->VirtualTagPath != null)
{
ControlLoader::LoadPHPXControlAttributes($attrs, $obj);
}
}
$obj->ParentObject = $parent;
$parent->Controls[] = $obj;
}
else
{
$ctl = new HTMLControl();
$ctl->TagName = $elem->Name;
if (is_array($elem->Attributes))
{
foreach ($elem->Attributes as $attr)
{
$ctl->Attributes[] = new WebControlAttribute($attr->Name, $attr->Value);
}
}
if (is_array($elem->Elements) && count($elem->Elements) > 0)
{
foreach ($elem->Elements as $elem1)
{
ControlLoader::LoadControl($elem1, $ctl);
}
}
else
{
if ($ctl->TagName != "script")
{
$ctl->HasContent = false;
}
}
$ctl->ParentObject = $parent;
$parent->Controls[] = $ctl;
}
}
else if (get_class($elem) == "UniversalEditor\\ObjectModels\\Markup\\MarkupLiteralElement")
{
$parent->Controls[] = new Literal($elem->Value);
}
}
}
ControlLoader::$Messages = array();
?>

View File

@ -0,0 +1,193 @@
<?php
namespace Phast\Parser;
use UniversalEditor\ObjectModels\Markup\MarkupObjectModel;
use Phast\System;
use Phast\WebControl;
use Phast\WebPage;
use Phast\WebNamespaceReference;
use Phast\WebScript;
use Phast\WebStyleSheet;
use Phast\WebVariable;
use Phast\WebPageMessage;
use Phast\WebControlAttribute;
use Phast\WebControlClientIDMode;
use Phast\HTMLControl;
use Phast\HTMLControls\HTMLControlLiteral;
use Phast\EventArgs;
use Phast\CancelEventArgs;
require("XMLParser.inc.php");
class PhastPage
{
/**
* The Page generated by this template.
* @var WebPage
*/
public $Page;
/**
* Code executed before the page is initialized.
* @param CancelEventArgs $e
*/
public function OnInitializing(CancelEventArgs $e)
{
}
/**
* Code executed after the page is initialized.
* @param EventArgs $e
*/
public function OnInitialized(EventArgs $e)
{
}
/**
* Code executed after the class definition is loaded by the Phast parser.
* @param EventArgs $e
*/
public function OnClassLoaded(EventArgs $e)
{
}
/**
* The function called before the page constructor is called.
* @param CancelEventArgs $e The arguments for this event handler.
*/
public function OnCreating(CancelEventArgs $e)
{
}
/**
* The function called after the page constructor has completed.
* @param EventArgs $e The arguments for this event handler.
*/
public function OnCreated(EventArgs $e)
{
}
/**
* The function called before the page has started rendering.
* @param RenderedEventArgs $e The arguments for this event handler.
*/
public function OnRendering(\Phast\RenderingEventArgs $e)
{
}
/**
* The function called after the page has completely rendered.
* @param RenderedEventArgs $e The arguments for this event handler.
*/
public function OnRendered(\Phast\RenderedEventArgs $e)
{
}
}
class PhastParser
{
public $Controls;
public $MasterPages;
public $Pages;
public function GetControlByVirtualTagPath($path)
{
foreach ($this->Controls as $ctl)
{
if ($ctl->VirtualTagPath == $path) return $ctl;
}
return null;
}
public function GetMasterPageByFileName($filename)
{
foreach ($this->MasterPages as $page)
{
if ($page->FileName == $filename) return $page;
}
return null;
}
public function GetPageByFileName($filename)
{
foreach ($this->Pages as $page)
{
if ($page->FileName == $filename) return $page;
}
return null;
}
public function __construct()
{
$this->Clear();
}
public function Clear()
{
$this->Controls = array();
$this->MasterPages = array();
$this->Pages = array();
}
/**
* Loads an XML file describing a portion or portions of the Phast environment.
* @param string $filename The name of the XML file to load into the environment.
*/
public function LoadFile($filename)
{
$markup = MarkupObjectModel::FromFile($filename);
$tagWebsite = $markup->GetElement("Website");
if ($tagWebsite == null) return;
$tagControls = $tagWebsite->GetElement("Controls");
if ($tagControls != null)
{
foreach ($tagControls->Elements as $element)
{
if (get_class($element) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
if ($element->Name == "Control")
{
$ctl = WebControl::FromMarkup($element, $this);
$ctl->PhysicalFileName = $filename;
$this->Controls[] = $ctl;
}
}
}
$tagMasterPages = $tagWebsite->GetElement("MasterPages");
if ($tagMasterPages != null)
{
foreach ($tagMasterPages->Elements as $element)
{
if (get_class($element) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
if ($element->Name == "MasterPage")
{
$page = WebPage::FromMarkup($element, $this);
$page->PhysicalFileName = $filename;
$this->MasterPages[] = $page;
}
}
}
$tagPages = $tagWebsite->GetElement("Pages");
if ($tagPages != null)
{
foreach ($tagPages->Elements as $element)
{
if (get_class($element) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
if ($element->Name == "Page")
{
$page = WebPage::FromMarkup($element, $this);
$page->PhysicalFileName = $filename;
$this->Pages[] = $page;
}
}
}
}
}
?>

View File

@ -0,0 +1,359 @@
<?php
namespace UniversalEditor\ObjectModels\Markup;
class MarkupAttribute
{
public $Prefix;
public $Name;
public $Value;
public function GetFullName()
{
if ($this->Prefix != "")
{
return $this->Prefix . ":" . $this->Name;
}
else
{
return $this->Name;
}
}
public function SetFullName($name)
{
$names = explode(":", $name);
if (count($names) > 1)
{
$this->Prefix = $names[0];
$this->Name = $names[1];
}
else if (count($names) == 1)
{
$this->Prefix = "";
$this->Name = $names[0];
}
}
public function __construct($name, $value, $prefix = null)
{
if ($prefix == null)
{
$this->SetFullName($name);
}
else
{
$this->Prefix = $prefix;
$this->Name = $name;
}
$this->Value = $value;
}
}
abstract class MarkupElement
{
public abstract function GetOuterMarkup();
public abstract function GetInnerMarkup();
public static function FromArray($array)
{
if (!isset($array["Type"])) return null;
switch ($array["Type"])
{
case "MarkupTagElement":
{
$element = new MarkupTagElement();
$element->Name = $array["Name"];
if (isset($array["Attributes"]))
{
$attributes = $array["Attributes"];
foreach ($attributes as $name => $value)
{
$element->Attributes[] = new MarkupAttribute($name, $value);
}
}
if (isset($array["Elements"]))
{
$elements = $array["Elements"];
foreach ($elements as $elem)
{
$element->Elements[] = MarkupElement::FromArray($elem);
}
}
if (isset($array["Value"]))
{
$element->Value = $array["Value"];
}
return $element;
}
case "MarkupLiteralElement":
{
$element = new MarkupLiteralElement();
$element->Value = $array["Value"];
return $element;
}
}
return null;
}
}
class MarkupLiteralElement extends MarkupElement
{
public $Value;
public function GetOuterMarkup()
{
return $this->GetInnerMarkup();
}
public function GetInnerMarkup()
{
return $this->Value;
}
}
class MarkupTagElement extends MarkupElement
{
/**
* The name of this MarkupTagElement.
* @var string
*/
public $Name;
/**
* The MarkupAttributes associated with this MarkupTagElement.
* @var MarkupAttribute[]
*/
public $Attributes;
/**
* The child MarkupElements of this MarkupTagElement.
* @var MarkupTagElement[]
*/
public $Elements;
public function __construct()
{
$this->Attributes = array();
$this->Elements = array();
}
public function GetOuterMarkup()
{
$str = "<" . $this->Name;
if (count($this->Attributes) != 0)
{
foreach ($this->Attributes as $attr)
{
$str .= " " . $attr->Name . "=\"" . $attr->Value . "\"";
}
}
if (count($this->Elements) == 0)
{
$str .= " />";
}
else
{
$str .= ">" . $this->GetInnerMarkup() . "</" . $this->Name . ">";
}
return $str;
}
public function GetInnerMarkup()
{
$str = "";
foreach ($this->Elements as $elem)
{
$str .= $elem->GetOuterMarkup();
}
return $str;
}
public function GetAttribute($name, $index = 0)
{
$i = 0;
$last = null;
foreach ($this->Attributes as $attribute)
{
if ($attribute->Name == $name)
{
$last = $attribute;
$i++;
if ($i == $index) return $attribute;
}
}
return $last;
}
public function GetAttributes()
{
return $this->Attributes;
}
public function HasAttribute($name)
{
return ($this->GetAttribute($name) != null);
}
/**
* Gets a MarkupElement with the specified name.
* @param string $name The name of the element to retrieve.
* @param number $index The index of the element to retrieve if there is more than one element with the specified name.
* @return MarkupTagElement|MarkupLiteralElement|MarkupElement|null
*/
public function GetElement($name, $index = 0)
{
$i = 0;
$last = null;
foreach ($this->Elements as $element)
{
if (is_numeric($name))
{
if ($i == $name) return $element;
continue;
}
if (get_class($element) == "UniversalEditor\\ObjectModels\\Markup\\MarkupLiteralElement") continue;
if ($element->Name == $name)
{
$last = $element;
$i++;
if ($i == $index) return $element;
}
}
return $last;
}
public function GetElements()
{
return $this->Elements;
}
}
class MarkupObjectModel
{
public $Elements;
/**
* Gets a MarkupElement with the specified name.
* @param string $name The name of the element to retrieve.
* @param number $index The index of the element to retrieve if there is more than one element with the specified name.
* @return MarkupTagElement|MarkupLiteralElement|MarkupElement
*/
public function GetElement($name, $index = 0)
{
$i = 0;
$last = null;
foreach ($this->Elements as $element)
{
if ($element->Name == $name)
{
$last = $element;
$i++;
if ($i == $index) return $element;
}
}
return $last;
}
public function GetElements()
{
return $this->Elements;
}
public static function FromFile($filename)
{
$parser = new XMLParser();
$markup = $parser->LoadFile($filename);
return $markup;
}
public function __construct()
{
$this->Elements = array();
}
public static function FromArray($array)
{
$markup = new MarkupObjectModel();
$markup->LoadArray($array);
return $markup;
}
public function LoadArray($array)
{
$count = count($array);
for ($i = 0; $i < $count; $i++)
{
$this->Elements[] = MarkupElement::FromArray($array[$i]);
}
}
}
class XMLParser
{
public $RemoveWhitespace;
private $mvarOutput;
var $resParser;
var $strXmlData;
public function __construct()
{
$this->RemoveWhitespace = true;
}
/**
* Loads an XML file and returns the MarkupObjectModel.
* @param string $filename
* @return MarkupObjectModel
*/
public function LoadFile($filename)
{
$file = fopen($filename, "r");
$input = fread($file, filesize($filename));
return $this->Load($input);
}
public function Load($input)
{
$this->mvarOutput = array();
$input = html_entity_decode($input);
$this->resParser = \xml_parser_create ();
\xml_parser_set_option($this->resParser, XML_OPTION_CASE_FOLDING, 0);
\xml_set_object($this->resParser, $this);
\xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
\xml_set_character_data_handler($this->resParser, "tagData");
$this->strXmlData = \xml_parse($this->resParser, $input);
if(!$this->strXmlData)
{
$message = \xml_error_string(xml_get_error_code($this->resParser));
$lineNumber = \xml_get_current_line_number($this->resParser);
die(sprintf("XML error: %s at line %d", $message, $lineNumber));
}
\xml_parser_free($this->resParser);
return MarkupObjectModel::FromArray($this->mvarOutput);
}
private function tagOpen($parser, $name, $attrs)
{
$tag = array("Type" => "MarkupTagElement", "Name" => $name, "Attributes" => $attrs);
array_push($this->mvarOutput,$tag);
}
private function tagData($parser, $value)
{
if ($this->RemoveWhitespace && trim($value) == "") return;
$value = htmlentities($value);
$tag = array("Type" => "MarkupLiteralElement", "Value" => $value);
array_push($this->mvarOutput, $tag);
$this->mvarOutput[count($this->mvarOutput) - 2]['Elements'][] = $this->mvarOutput[count($this->mvarOutput) - 1];
array_pop($this->mvarOutput);
}
function tagClosed($parser, $name)
{
$this->mvarOutput[count($this->mvarOutput) - 2]['Elements'][] = $this->mvarOutput[count($this->mvarOutput) - 1];
array_pop($this->mvarOutput);
}
}
?>

View File

@ -0,0 +1,51 @@
<?php
namespace Phast;
abstract class RandomStringGeneratorCharacterSets
{
const AlphaNumericMixedCase = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const AlphaNumericLowerCase = "abcdefghijklmnopqrstuvwxyz0123456789";
const AlphaNumericUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const AlphaOnlyUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const AlphaOnlyLowerCase = "abcdefghijklmnopqrstuvwxyz";
}
/**
* Provides methods to generate a random string using a specified character set.
* @author Michael Becker
*/
class RandomStringGenerator
{
/**
* Generates a random string of the specified length using the specified character set.
* @param string $valid_chars The character set to use.
* @param int $length The length of the string to generate.
* @return string A random string.
*/
public static function Generate($valid_chars, $length)
{
// start with an empty random string
$random_string = "";
// count the number of chars in the valid chars string so we know how many choices we have
$num_valid_chars = strlen($valid_chars);
// repeat the steps until we've created a string of the right length
for ($i = 0; $i < $length; $i++)
{
// pick a random number from 1 up to the number of valid chars
$random_pick = mt_rand(1, $num_valid_chars);
// take the random character out of the string of valid chars
// subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
$random_char = $valid_chars[$random_pick-1];
// add the randomly-chosen char onto the end of our string so far
$random_string .= $random_char;
}
// return our finished random string
return $random_string;
}
}
?>

View File

@ -0,0 +1,40 @@
<?php
namespace Phast;
class RenderingEventArgs extends CancelEventArgs
{
/**
* Describes whether this is a partial or complete render.
* @var RenderMode
*/
public $RenderMode;
/**
* Creates a new instance of RenderingEventArgs with the specified renderMode.
* @param RenderMode $renderMode Describes whether this is a partial or complete render. Default RenderMode::Any.
*/
public function __construct($renderMode = null)
{
if ($renderMode == null) $renderMode = RenderMode::Any;
$this->RenderMode = $renderMode;
}
}
class RenderedEventArgs extends EventArgs
{
/**
* Describes whether this is a partial or complete render.
* @var RenderMode
*/
public $RenderMode;
/**
* Creates a new instance of RenderedEventArgs with the specified renderMode.
* @param RenderMode $renderMode Describes whether this is a partial or complete render. Default RenderMode::Any.
*/
public function __construct($renderMode = null)
{
if ($renderMode == null) $renderMode = RenderMode::Any;
$this->RenderMode = $renderMode;
}
}
?>

View File

@ -0,0 +1,26 @@
<?php
namespace Phast;
/**
* Provides an enumeration of predefined values for type of input.
* @author Michael Becker
*/
abstract class RenderMode extends Enumeration
{
/**
* The page is being rendered, either partially or completely.
* @var int 0
*/
const Any = 0;
/**
* The page is being partially rendered (e.g. as part of an AJAX request)
* @var int 1
*/
const Partial = 1;
/**
* The page is being completely rendered.
* @var int 2
*/
const Complete = 2;
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast;
class StringMethods
{
public static function StartsWith($haystack, $needle)
{
return $needle === "" || strpos($haystack, $needle) === 0;
}
public static function EndsWith($haystack, $needle)
{
return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
}
}
?>

1022
app/lib/phast/System.inc.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
<?php
namespace Phast;
class UUID
{
protected $urand;
public function __construct()
{
$this->urand = @fopen ( '/dev/urandom', 'rb' );
}
public static function Generate()
{
$uuid = new UUID();
return $uuid->get();
}
/**
* @brief Generates a Universally Unique IDentifier, version 4.
*
* This function generates a truly random UUID. The built in CakePHP String::uuid() function
* is not cryptographically secure. You should uses this function instead.
*
* @see http://tools.ietf.org/html/rfc4122#section-4.4
* @see http://en.wikipedia.org/wiki/UUID
* @return string A UUID, made up of 32 hex digits and 4 hyphens.
*/
function get()
{
$pr_bits = false;
if (is_a ( $this, 'uuid' ))
{
if (is_resource ( $this->urand ))
{
$pr_bits .= @fread ( $this->urand, 16 );
}
}
if (! $pr_bits)
{
$fp = @fopen ( '/dev/urandom', 'rb' );
if ($fp !== false)
{
$pr_bits .= @fread ( $fp, 16 );
@fclose ( $fp );
}
else
{
// If /dev/urandom isn't available (eg: in non-unix systems), use mt_rand().
$pr_bits = "";
for($cnt = 0; $cnt < 16; $cnt ++)
{
$pr_bits .= chr ( mt_rand ( 0, 255 ) );
}
}
}
$time_low = bin2hex ( substr ( $pr_bits, 0, 4 ) );
$time_mid = bin2hex ( substr ( $pr_bits, 4, 2 ) );
$time_hi_and_version = bin2hex ( substr ( $pr_bits, 6, 2 ) );
$clock_seq_hi_and_reserved = bin2hex ( substr ( $pr_bits, 8, 2 ) );
$node = bin2hex ( substr ( $pr_bits, 10, 6 ) );
/**
* Set the four most significant bits (bits 12 through 15) of the
* time_hi_and_version field to the 4-bit version number from
* Section 4.1.3.
* @see http://tools.ietf.org/html/rfc4122#section-4.1.3
*/
$time_hi_and_version = hexdec ( $time_hi_and_version );
$time_hi_and_version = $time_hi_and_version >> 4;
$time_hi_and_version = $time_hi_and_version | 0x4000;
/**
* Set the two most significant bits (bits 6 and 7) of the
* clock_seq_hi_and_reserved to zero and one, respectively.
*/
$clock_seq_hi_and_reserved = hexdec ( $clock_seq_hi_and_reserved );
$clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved >> 2;
$clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved | 0x8000;
return strtoupper( sprintf ( '%08s%04s%04x%04x%012s', $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $node ) );
}
public static function format($input)
{
$output = $input;
$output = substr($output, 0, 8) . "-" . substr($output, 8, 4) . "-" . substr($output, 12, 4) . "-" . substr($output, 16, 4) . "-" . substr($output, 20);
return "{" . $output . "}";
}
}
?>

View File

@ -0,0 +1,52 @@
<?php
namespace Phast\Utilities;
class Stopwatch
{
/**
* @var $startTime float The start time of the StopWatch
*/
private $startTime;
private $endTime;
/**
* Start the timer
* @return void
*/
public function start()
{
$this->startTime = microtime(true);
$this->endTime = null;
}
public function stop()
{
$this->endTime = microtime(true);
}
public function reset()
{
$this->startTime = null;
$this->endTime = null;
}
/**
* Get the elapsed time in seconds
*
* @param $timerName string The name of the timer to start
* @return float|bool The elapsed time since start() was called, or false if the timer is stopped;
*/
public function getElapsedTime()
{
if ($this->startTime === null) return false;
if ($this->endTime === null) return false;
return ($this->endTime - $this->startTime);
}
public function __construct()
{
$this->startTime = null;
$this->endTime = null;
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast;
abstract class Validator
{
public $Message;
protected abstract function ValidateInternal($value);
public function Validate($value)
{
return $this->ValidateInternal($value);
}
}
?>

View File

@ -0,0 +1,116 @@
<?php
namespace Phast\Validators;
use Phast\Validator;
class EmailAddressValidator extends Validator
{
public $DomainBlockedMessage;
public $EmailAddressInvalidMessage;
public $CheckDNSRecords;
public $PreventThrowawayAddresses;
public $ThrowawayAddresses;
public static $DefaultDomainBlockedMessage;
public static $DefaultEmailAddressInvalidMessage;
public static $DefaultThrowawayAddresses;
public function __construct()
{
$this->CheckDNSRecords = false;
$this->PreventThrowawayAddresses = false;
$this->DomainBlockedMessage = EmailAddressValidator::$DefaultDomainBlockedMessage;
$this->EmailAddressInvalidMessage = EmailAddressValidator::$DefaultEmailAddressInvalidMessage;
$this->ThrowawayAddresses = array();
foreach (EmailAddressValidator::$DefaultThrowawayAddresses as $addr)
{
$this->ThrowawayAddresses[] = $addr;
}
}
protected function ValidateInternal($value)
{
$domainPos = stripos($value, "@");
$domain = $value;
if ($domainPos !== false)
{
$domain = substr($value, $domainPos + 1);
}
else
{
$this->Message = $this->EmailAddressInvalidMessage;
return false;
}
if ($this->PreventThrowawayAddresses || $this->CheckDNSRecords)
{
// determine if domain is in the blacklist
if ($this->PreventThrowawayAddresses)
{
if (in_array($domain, $this->ThrowawayAddresses))
{
$this->Message = $this->DomainBlockedMessage;
return false;
}
}
// domain isn't, check DNS and see if the IP is blocked
$recs = dns_get_record($domain);
if (count($recs) === 0)
{
$this->Message = $this->EmailAddressInvalidMessage;
return false;
}
$ips = array();
foreach ($recs as $rec)
{
switch ($rec["type"])
{
case "AAAA":
{
$ips[] = $rec["ipv6"];
break;
}
case "A":
{
$ips[] = $rec["ip"];
break;
}
}
}
foreach ($this->ThrowawayAddresses as $ip)
{
if (in_array($ip, $ips))
{
$this->Message = $this->DomainBlockedMessage;
return false;
}
}
}
return true;
}
}
EmailAddressValidator::$DefaultThrowawayAddresses = array
(
// mailinator.com throwaway domains
"mailinator.com",
"mailinator.net",
"streetwisemail.com",
// mailinator.com throwaway IP addresses
"2600:3c03::f03c:91ff:fe50:caa7",
"23.239.11.30"
);
EmailAddressValidator::$DefaultDomainBlockedMessage = "Your e-mail address has been blocked";
EmailAddressValidator::$DefaultEmailAddressInvalidMessage = "Please enter a valid e-mail address";
?>

View File

@ -0,0 +1,20 @@
<?php
namespace Phast;
class WebApplication
{
public $Configuration;
public $Modules;
public function __construct()
{
$this->Configuration = array();
$this->Modules = array();
}
public function Run()
{
echo(ROOT_PATH);
}
}
?>

View File

@ -0,0 +1,45 @@
<?php
namespace Phast;
class WebApplicationTask
{
public $ID;
public $Title;
public $TaskType;
public $Description;
public $TargetURL;
public $TargetScript;
public $TargetFrame;
public $Tasks;
public $CheckAvailabilityFunction;
public function IsAvailable()
{
return call_user_func($this->CheckAvailabilityFunction);
}
public function __construct($id, $title = null, $taskType = null, $description = null, $targetURL = null, $targetScript = null, $targetFrame = null, $tasks = null)
{
if ($title == null) $title = $id;
if ($tasks == null) $tasks = array();
$this->ID = $id;
$this->Title = $title;
$this->TaskType = $taskType;
$this->Description = $description;
$this->TargetURL = $targetURL;
$this->TargetScript = $targetScript;
$this->TargetFrame = $targetFrame;
$this->Tasks = $tasks;
$this->CheckAvailabilityFunction = function()
{
return true;
};
}
}
?>

View File

@ -0,0 +1,684 @@
<?php
namespace Phast;
use UniversalEditor\ObjectModels\Markup\MarkupElement;
use Phast\Parser\ControlLoader;
class WebControl
{
/**
* The unique identifier of this WebControl on a WebPage.
* @var string
*/
public $ID;
/**
* The unique identifier of this WebControl on the client rendered WebPage.
* @var string
*/
public $ClientID;
/**
* Determines how ClientIDs are generated for WebControls.
* @var WebControlClientIDMode
*/
public $ClientIDMode;
public $Content;
/**
* True if the WebControl is enabled (does not have the "disabled" attribute set); false if it is disabled.
* @var boolean
*/
public $Enabled;
/**
* True if the WebControl should render its content to the output HTML; false otherwise.
* @var boolean
*/
public $EnableRender;
public $ExtraData;
public $Controls;
public $HasContent;
public $ParentObject;
public $Top;
public $Left;
public $Width;
public $Height;
public $MinimumWidth;
public $MinimumHeight;
public $MaximumWidth;
public $MaximumHeight;
public $Visible;
/**
* The horizontal alignment of this WebControl.
* @var HorizontalAlignment
*/
public $HorizontalAlignment;
/**
* The vertical alignment of this WebControl.
* @var VerticalAlignment
*/
public $VerticalAlignment;
/**
* The CssClass to assign to this WebControl. CssClass is assigned after all classes defined in ClassList have been assigned.
* @var string
* @see WebControl::$ClassList
*/
public $CssClass;
/**
* Array of CssClasses to assign to this WebControl.
* @var string[]
* @see WebControl::$CssClass
*/
public $ClassList;
public $TagName;
public $Attributes;
public $StyleRules;
public $ToolTipTitle;
public $ToolTipText;
/**
* True if child tags should be parsed as control properties; false if they should be parsed as child controls.
* @var boolean
*/
public $ParseChildElements;
public $OnClientClick;
public function GetAllControls()
{
return $this->Controls;
}
/**
* Retrieves the control with the specified ID in this control's child control collection.
* @param string $id The ID of the control to search for.
* @return WebControl|NULL The control with the specified ID, or null if no control with the specified ID was found.
*/
public function GetControlByID($id, $recurse = true)
{
$ctls = $this->GetAllControls();
foreach ($ctls as $ctl)
{
if ($ctl->ID == $id) return $ctl;
if ($recurse)
{
$ctl1 = $ctl->GetControlByID($id, true);
if ($ctl1 != null) return $ctl1;
}
}
return null;
}
public function FindParentPage()
{
$parent = $this->ParentObject;
while ($parent != null)
{
if (get_class($parent) == "Phast\\Parser\\Page" || get_class($parent) == "Phast\\Parser\\MasterPage")
{
return $parent;
}
$parent = $parent->ParentObject;
}
return null;
}
/**
* Generates a random string of the specified length using the characters specified in the string valid_chars.
* @param string $valid_chars Set of characters used to build the resulting random string.
* @param int $length The length of the resulting random string.
* @return string The random string of the specified length using the specified character set.
*/
private static function GenerateRandomString($valid_chars, $length)
{
// start with an empty random string
$random_string = "";
// count the number of chars in the valid chars string so we know how many choices we have
$num_valid_chars = strlen($valid_chars);
// repeat the steps until we've created a string of the right length
for ($i = 0; $i < $length; $i++)
{
// pick a random number from 1 up to the number of valid chars
$random_pick = mt_rand(1, $num_valid_chars);
// take the random character out of the string of valid chars
// subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
$random_char = $valid_chars[$random_pick-1];
// add the randomly-chosen char onto the end of our string so far
$random_string .= $random_char;
}
// return our finished random string
return $random_string;
}
public function __construct()
{
$this->Enabled = true;
$this->Visible = true;
$this->HorizontalAlignment = HorizontalAlignment::Inherit;
$this->VerticalAlignment = VerticalAlignment::Inherit;
$this->Controls = array();
$this->EnableRender = true;
$this->HasContent = true;
$this->TagName = null;
$this->ClassList = array();
$this->Attributes = array();
$this->StyleRules = array();
$this->ParseChildElements = false;
$this->ClientIDMode = WebControlClientIDMode::None;
}
/**
* Retrieves a ClientProperty associated with this control via a browser cookie.
* @param string $name The name of the property to retrieve.
* @param string $defaultValue The value to retrieve if the ClientProperty has not been set.
* @return string The value of the property with the given name, or defaultValue if the property has not been set.
*/
public function GetClientProperty($name, $defaultValue = null)
{
if (!isset($_COOKIE[$this->ID . "__ClientProperty_" . $name])) return $defaultValue;
return $_COOKIE[$this->ID . "__ClientProperty_" . $name];
}
/**
* Updates a ClientProperty associated with this control via a browser cookie.
* @param string $name The name of the property to update.
* @param string $value The value with which to update the property.
* @param string $expires Expiration data for the cookie associated with the ClientProperty.
*/
public function SetClientProperty($name, $value, $expires = null)
{
setcookie($this->ID . "__ClientProperty_" . $name, $value, $expires);
}
private $Initialized;
/**
* Initializes this control, calling the OnInitialize() function and initializing any child
* controls.
*/
public function Initialize()
{
$id = null;
$clientid = null;
if ($this->ClientIDMode == WebControlClientIDMode::Automatic && $this->ID == null)
{
$parent = $this->ParentObject;
$clientid = "";
while ($parent != null)
{
$clientid = $parent->ID . "_" . $clientid;
$parent = $parent->ParentObject;
}
$id = "WFX" . WebControl::GenerateRandomString("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 10);
$clientid .= $id;
}
if ($id != null) $this->ID = $id;
if ($clientid != null) $this->ClientID = $clientid;
if ($this->OnClientClick != null)
{
$this->Attributes[] = new WebControlAttribute("onclick", $this->OnClientClick);
}
$this->OnInitialize();
if (is_array($this->Controls))
{
foreach ($this->Controls as $control)
{
$control->ParentObject = $this;
if (method_exists($control, "Initialize"))
{
$control->Initialize();
}
}
}
else
{
trigger_error("Controls is not array in " . get_class($this) . " ; did you forget to call parent::__construct() ?");
}
$this->Initialized = true;
}
protected function OnInitialize()
{
}
protected function BeforeContent()
{
}
protected function RenderContent()
{
}
protected function AfterContent()
{
}
/**
* Renders an HTML beginning tag with the specified parameters.
* @param string $tagName The name of the tag to open.
* @param array $namedParameters Associative array that specifies ClassNames, Attributes, and StyleRules to render with the beginning tag.
*/
public static function BeginTag($tagName, $namedParameters)
{
echo("<" . $tagName);
if (is_array($namedParameters))
{
if (isset($namedParameters["ClassNames"])) $classNames = $namedParameters["ClassNames"];
if (isset($namedParameters["Attributes"])) $attributes = $namedParameters["Attributes"];
if (isset($namedParameters["StyleRules"])) $styleRules = $namedParameters["StyleRules"];
}
if (!isset($classNames) || !is_array($classNames)) $classNames = array();
if (!isset($attributes) ||!is_array($attributes)) $attributes = array();
if (!isset($styleRules) ||!is_array($styleRules)) $styleRules = array();
$count = count($classNames);
if ($count > 0)
{
echo(" class=\"");
for ($i = 0; $i < $count; $i++)
{
echo($classNames[$i]);
if ($i < $count - 1) echo(" ");
}
echo("\"");
}
$count = count($styleRules);
if ($count > 0)
{
echo(" style=\"");
for ($i = 0; $i < $count; $i++)
{
$item = $styleRules[$i];
echo($item->Name . ": " . $item->Value);
if ($i < $count - 1) echo("; ");
}
echo("\"");
}
$count = count($attributes);
if ($count > 0)
{
echo(" ");
for ($i = 0; $i < $count; $i++)
{
$item = $attributes[$i];
echo($item->Name . "=\"" . $item->Value . "\"");
if ($i < $count - 1) echo(" ");
}
}
echo(">");
}
/**
* Renders an HTML ending tag with the given tag name.
* @param string $tagName The name of the tag to close.
*/
public static function EndTag($tagName)
{
echo("</" . $tagName . ">");
}
/**
* Renders the beginning tag of this WebControl, including any attribute, CSS class, or style
* information specified by the control author or the caller.
*/
protected function RenderBeginTag()
{
if ($this->TagName != "")
{
echo("<" . $this->TagName);
$styleAttributeContent = "";
$classAttributeContent = "";
$count = count($this->Attributes);
if ($count > 0)
{
$found = false;
foreach ($this->Attributes as $attr)
{
if (!(strtolower($attr->Name) == "style" || strtolower($attr->Name) == "class" || strtolower($attr->Name) == "disabled"))
{
$found = true;
break;
}
}
if ($found) echo(" ");
$i = 0;
foreach ($this->Attributes as $attr)
{
if (strtolower($attr->Name) == "style")
{
if (!StringMethods::EndsWith($attr->Value, ";"))
{
$styleAttributeContent .= $attr->Value . "; ";
}
else
{
$styleAttributeContent .= $attr->Value;
}
}
else if (strtolower($attr->Name) == "class")
{
$classAttributeContent .= $attr->Value;
}
else if (strtolower($attr->Name) == "disabled")
{
// we normalize the disabled attribute
$this->Enabled = false;
echo(" disabled=\"disabled\"");
}
else if (strtolower($attr->Name) == "id")
{
$this->ID = $attr->Value;
}
else
{
echo($attr->Name);
echo("=\"");
echo($attr->Value);
echo("\"");
if ($i < $count - 1) echo(" ");
}
$i++;
}
}
$styleRules = $this->StyleRules;
if (!$this->Visible)
{
$styleRules[] = new WebStyleSheetRule("display", "none");
}
if ($this->Width != null)
{
$styleRules[] = new WebStyleSheetRule("width", $this->Width);
}
if ($this->Height != null)
{
$styleRules[] = new WebStyleSheetRule("height", $this->Height);
}
if ($this->MinimumWidth != null)
{
$styleRules[] = new WebStyleSheetRule("min-width", $this->MinimumWidth);
}
if ($this->MinimumHeight != null)
{
$styleRules[] = new WebStyleSheetRule("min-height", $this->MinimumHeight);
}
if ($this->MaximumWidth != null)
{
$styleRules[] = new WebStyleSheetRule("max-width", $this->MaximumWidth);
}
if ($this->MaximumHeight != null)
{
$styleRules[] = new WebStyleSheetRule("max-height", $this->MaximumHeight);
}
if (count($styleRules) > 0 || $styleAttributeContent != "")
{
echo(" style=\"");
echo($styleAttributeContent);
$count = count($styleRules);
$i = 0;
foreach ($styleRules as $rule)
{
echo($rule->Name);
echo(": ");
echo($rule->Value);
echo(";");
if ($i < $count - 1) echo(" ");
$i++;
}
echo("\"");
}
if ($this->CssClass != "")
{
if ($classAttributeContent != "") $classAttributeContent .= " ";
$classAttributeContent .= $this->CssClass;
}
if (count($this->ClassList) > 0)
{
if ($classAttributeContent != "") $classAttributeContent .= " ";
$count = count($this->ClassList);
for ($i = 0; $i < $count; $i++)
{
$classAttributeContent .= $this->ClassList[$i];
if ($i < $count - 1) $classAttributeContent .= " ";
}
}
if ($classAttributeContent != "")
{
echo(" class=\"" . $classAttributeContent . "\"");
}
if ($this->ClientID != null)
{
echo(" id=\"" . $this->ClientID . "\"");
}
else if ($this->ID != null)
{
echo(" id=\"" . $this->ID . "\"");
}
if ($this->ToolTipTitle != null) echo(" data-tooltip-title=\"" . $this->ToolTipTitle . "\"");
if ($this->ToolTipText != null) echo(" data-tooltip-content=\"" . $this->ToolTipText . "\"");
if (!$this->DoesHaveContent()) echo(" /");
echo(">");
}
}
private static $tagNamesThatMustHaveContent= array("script", "div", "i");
private function DoesHaveContent()
{
$mustHaveContent = in_array(strtolower($this->TagName), WebControl::$tagNamesThatMustHaveContent);
return $this->HasContent || $mustHaveContent;
}
/**
* Renders the ending tag of this WebControl.
*/
protected function RenderEndTag()
{
if ($this->TagName != "" && $this->DoesHaveContent())
{
echo("</" . $this->TagName . ">");
}
}
/**
* Renders the beginning tag of this WebControl, followed by any leading content specified by
* the control author.
*/
public function BeginContent()
{
if ($this->EnableRender !== true) return;
$this->RenderBeginTag();
$this->BeforeContent();
}
/**
* Renders any trailing content specified by the control author before the ending tag of this
* WebControl, followed by the ending tag itself.
*/
public function EndContent()
{
if ($this->EnableRender !== true) return;
$this->AfterContent();
$this->RenderEndTag();
}
/**
* Creates the child controls for this WebControl.
*/
protected function CreateControl()
{
}
/**
* Renders this WebControl and any child controls.
*/
public function Render()
{
if ($this->EnableRender !== true) return;
if (!$this->Initialized) $this->Initialize();
if ($this->Enabled !== true)
{
$this->Attributes[] = new WebControlAttribute("disabled", "disabled");
}
$this->CreateControl();
$this->BeginContent();
if (is_callable($this->Content))
{
call_user_func($this->Content, $this, $this->ExtraData);
}
else if (is_string($this->Content))
{
echo($this->Content);
}
else
{
if (count($this->Controls) > 0)
{
foreach ($this->Controls as $control)
{
$control->Render();
}
}
else
{
$this->RenderContent();
}
}
$this->EndContent();
}
/**
* Parses an XML representation of a WebControl MarkupElement
* @param MarkupElement $element
* @param PhastParser $parser
* @return WebPage
*/
public static function FromMarkup($element, $parser)
{
$ctl = new WebControl();
$attNamespacePath = $element->GetAttribute("NamespacePath");
$attTagName = $element->GetAttribute("TagName");
$virtualTagPath = "";
if ($attNamespacePath != null) $virtualTagPath .= $attNamespacePath->Value . "\\";
if ($attTagName != null) $virtualTagPath .= $attTagName->Value;
if ($virtualTagPath != "")
{
$ctl->VirtualTagPath = $virtualTagPath;
}
$references = array();
$tagReferences = $element->GetElement("References");
if ($tagReferences != null)
{
foreach ($tagReferences->Elements as $elem)
{
if (get_class($elem) != "UniversalEditor\\ObjectModels\\Markup\\MarkupTagElement") continue;
$attTagPrefix = $elem->GetAttribute("TagPrefix");
if ($attTagPrefix == null) continue;
$attNamespacePath = $elem->GetAttribute("NamespacePath");
if ($attNamespacePath == null) continue;
$attNamespaceURL = $elem->GetAttribute("NamespaceURL");
$namespaceURL = "";
if ($attNamespaceURL != null) $namespaceURL = $attNamespaceURL->Value;
$references[] = new WebNamespaceReference($attTagPrefix->Value, $attNamespacePath->Value, $namespaceURL);
}
}
foreach ($references as $reference)
{
ControlLoader::$Namespaces[$reference->TagPrefix] = $reference->NamespacePath;
}
$tagContent = $element->GetElement("Content");
if ($tagContent != null)
{
foreach ($tagContent->Elements as $elem)
{
ControlLoader::LoadControl($elem, $ctl);
}
}
$attrCssClass = $element->GetAttribute("CssClass");
if ($attrCssClass != null)
{
$ctl->ClassList[] = $attrCssClass->Value;
}
/*
$attrCodeBehindClassName = $element->GetAttribute("CodeBehindClassName");
if ($attrCodeBehindClassName != null)
{
$ctl->CodeBehindClassName = $attrCodeBehindClassName->Value;
if (class_exists($page->CodeBehindClassName))
{
$page->ClassReference = new $page->CodeBehindClassName();
$page->ClassReference->Page = $page;
$page->IsPostback = ($_SERVER["REQUEST_METHOD"] == "POST");
if (method_exists($page->ClassReference, "OnClassLoaded"))
{
$page->ClassReference->OnClassLoaded(EventArgs::GetEmptyInstance());
}
else
{
System::WriteErrorLog("Code-behind for '" . $page->CodeBehindClassName . "' does not define an 'OnClassLoaded' entry point");
}
}
else
{
System::WriteErrorLog("Code-behind for '" . $page->CodeBehindClassName . "' not found");
}
}
*/
return $ctl;
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
namespace Phast;
class WebControlAttribute
{
public $Name;
public $Value;
public function __construct($name, $value)
{
$this->Name = $name;
$this->Value = $value;
}
}
?>

View File

@ -0,0 +1,22 @@
<?php
namespace Phast;
abstract class WebControlClientIDMode extends Enumeration
{
/**
* ClientIDs are not assigned or the implementation is unspecified.
* @var WebControlClientIDMode
*/
const None = 0;
/**
* ClientIDs are automatically assigned by PHAST.
* @var WebControlClientIDMode
*/
const Automatic = 1;
/**
* ClientIDs are manually specified by the Web site author.
* @var WebControlClientIDMode
*/
const Manual = 2;
}
?>

View File

@ -0,0 +1,75 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
class ActionList extends WebControl
{
public $Items;
protected function RenderContent()
{
echo("<div class=\"ActionList\">");
foreach ($this->Items as $item)
{
if (get_class($item) == "Phast\\WebControls\\ActionListCommand")
{
echo("<a");
if ($item->TargetURL != null)
{
echo(" href=\"" . $item->TargetURL . "\"");
}
else
{
echo(" href=\"#\"");
}
if ($item->TargetScript != null)
{
echo(" onclick=\"" . $item->TargetScript . "\"");
}
echo(">");
if ($item->ImageURL != null)
{
echo("<img src=\"" . System::ExpandRelativePath($item->ImageURL) . "\" />");
}
echo("<span class=\"Title\">" . $item->Title . "</span>");
echo("<span class=\"Description\">" . $item->Description . "</span>");
echo("</a>");
}
else if (get_class($item) == "Phast\\WebControls\\ActionListSeparator")
{
echo("<hr />");
}
}
echo("</div>");
}
}
class ActionListItem
{
public $ID;
}
class ActionListCommand extends ActionListItem
{
public $Title;
public $Description;
public $ImageURL;
public $TargetURL;
public $TargetScript;
public function __construct($id, $title, $description = null, $imageURL = null, $targetURL = null, $targetScript = null)
{
$this->Title = $title;
$this->Description = $description;
$this->ImageURL = $imageURL;
$this->TargetURL = $targetURL;
$this->TargetScript = $targetScript;
}
}
class ActionListSeparator extends ActionListItem
{
}
?>

View File

@ -0,0 +1,191 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\Enumeration;
use Phast\HTMLControl;
use Phast\WebControls\Menu;
abstract class AdditionalDetailWidgetDisplayStyle extends Enumeration
{
const Magnify = 1;
const Ellipsis = 2;
const Arrow = 3;
}
class AdditionalDetailWidget extends WebControl
{
public $DisplayStyle; /* AdditionalDetailWidgetDisplayStyle */
public $Text;
public $ShowText; /* bool */
public $ShowURL; /* bool */
public $TargetFrame;
public $TargetURL;
public $TargetScript;
public $MenuItems;
public $MenuItemHeaderText;
public $PreviewContentURL;
public $ClassTitle;
public function __construct($id)
{
parent::__construct($id);
$this->ClassTitle = "";
$this->DisplayStyle = AdditionalDetailWidgetDisplayStyle::Ellipsis;
$this->MenuItemHeaderText = "Available Actions";
$this->MenuItems = array();
$this->ShowText = true;
$this->ShowURL = true;
}
private function RenderMenuItem($mi)
{
if (get_class($mi) == "Phast\\WebControls\\MenuItemCommand")
{
echo("<a href=\"");
if ($mi->PostBackUrl == "")
{
echo("#");
}
else
{
echo(System::ExpandRelativePath($mi->PostBackUrl));
}
echo("\"");
if ($mi->OnClientClick != "")
{
echo(" onclick=\"" . $mi->OnClientClick . "\"");
}
echo(">");
echo($mi->Title);
echo("</a>");
}
else if (get_class($mi) == "Phast\\WebControls\\MenuItemSeparator")
{
echo("<br />");
}
}
protected function OnInitialize()
{
$this->TagName = "div";
$this->ClassList[] = "AdditionalDetailWidget";
if ($this->ShowText)
{
$this->ClassList[] = "Text";
}
switch ($this->DisplayStyle)
{
case AdditionalDetailWidgetDisplayStyle::Magnify:
{
$this->ClassList[] = "Magnify";
break;
}
case AdditionalDetailWidgetDisplayStyle::Arrow:
{
$this->ClassList[] = "Arrow";
break;
}
case AdditionalDetailWidgetDisplayStyle::Ellipsis:
{
$this->ClassList[] = "Ellipsis";
break;
}
}
}
protected function BeforeContent()
{
if ($this->ShowURL)
{
echo("<a class=\"AdditionalDetailText\" href=\"");
if ($this->TargetURL != "")
{
echo(System::ExpandRelativePath($this->TargetURL));
}
else
{
echo("#");
}
echo("\"");
if ($this->TargetFrame != "")
{
echo(" target=\"" . $this->TargetFrame . "\"");
}
echo(">");
echo($this->Text);
echo("</a>");
}
else
{
echo ("<span class=\"AdditionalDetailText\">" . $this->Text . "</span>");
}
echo("<a class=\"AdditionalDetailButton\">&nbsp;</a>");
echo("<div class=\"Content\">");
echo("<div class=\"MenuItems");
if (count($this->MenuItems) <= 0)
{
echo(" Empty");
}
echo("\">");
echo("<div class=\"Header\">" . $this->MenuItemHeaderText . "</div>");
$divContent = new HTMLControl("div");
$divContent->ClassList[] = "Content";
$menu = new Menu();
foreach ($this->MenuItems as $mi)
{
$menu->Items[] = $mi;
}
$divContent->Controls[] = $menu;
$divContent->Render();
echo("</div>");
echo("<div class=\"PreviewContent\">");
echo("<div class=\"Header\">");
if ($this->ClassTitle != "") echo("<span class=\"ClassTitle\">" . $this->ClassTitle . "</span>");
if ($this->Text != "")
{
echo("<span class=\"ObjectTitle\">");
echo("<a href=\"");
if ($this->PostBackURL != "")
{
echo($this->PostBackURL);
}
else
{
echo("#");
}
echo("\"");
echo(">");
echo($this->Text);
echo("</a>");
echo("</span>");
}
echo("</div>");
echo("<div class=\"Content\">");
}
protected function AfterContent()
{
echo("</div>");
echo("</div>");
echo("</div>");
}
}
?>

View File

@ -0,0 +1,45 @@
<?php
namespace Phast\WebControls;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\Enumeration;
class Alert extends WebControl
{
/**
* The title of the Alert.
* @var string
*/
public $Title;
public function __construct()
{
parent::__construct();
$this->ClassList[] = "pwt-Alert";
$this->TagName = "div";
}
protected function RenderBeginTag()
{
$ctls = $this->Controls;
$this->Controls = array();
$divTitle = new HTMLControl("div");
$divTitle->ClassList[] = "Title";
$divTitle->Content = $this->Title;
$this->Controls[] = $divTitle;
$divContent = new HTMLControl("div");
$divContent->ClassList[] = "Content";
foreach ($ctls as $ctl)
{
$divContent->Controls[] = $ctl;
}
$this->Controls[] = $divContent;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Website xmlns="http://www.alceproject.net/xmlns/Phast/Parser"
xmlns:wfx="http://www.alceproject.net/xmlns/Phast/WebControls"
xmlns:html="http://www.alceproject.net/xmlns/Phast/HTMLControls"
>
<Controls>
<Control NamespacePath="Phast\WebControls" TagName="Blockquote">
<References>
<Reference TagPrefix="wfx" NamespacePath="Phast\WebControls" />
<Reference TagPrefix="html" NamespacePath="Phast\HTMLControls" />
</References>
<Content>
<blockquote>
<p><html:Literal Value="$(Control:Content)" /></p>
<small>
<html:Literal Value="$(Control:Author)" />, <cite title="$(Control:Source)"><html:Literal Value="$(Control:Source)" /></cite>
</small>
</blockquote>
</Content>
</Control>
</Controls>
</Website>

View File

@ -0,0 +1,55 @@
<?php
namespace Phast\WebControls
{
class BreadcrumbItem
{
public $NavigateURL;
public $Title;
public $Selected;
public function __construct($navigateURL, $title)
{
$this->NavigateURL = $navigateURL;
$this->Title = $title;
}
}
class BreadcrumbContainer extends \Phast\WebControl
{
public $Items;
// $bc->Items = array(
// new BreadcrumbItem("http://www.psychatica.com/", "Psychatica")
// new BreadcrumbItem("http://www.psychatica.com/community", "Community"),
// new BreadcrumbItem("http://www.psychatica.com/community/members", "Members", true)
// );
protected function RenderContent()
{
echo("<div class=\"BreadcrumbContainer\">");
$i = 0;
$c = count($this->Items);
foreach ($this->Items as $item)
{
echo("<span class=\"BreadcrumbItem\">");
if ($i == $c - 1)
{
echo("<span class=\"Selected\">" . $item->Title . "</span>");
}
else
{
echo("<a href=\"" . System::ExpandRelativePath($item->NavigateURL) . "\">" . $item->Title . "</a>");
}
if ($i < $c - 1)
{
echo("<a class=\"BreadcrumbArrow\">&gt;&gt;</a>");
}
echo("</span>");
$i++;
}
echo("</div>");
}
}
}
?>

View File

@ -0,0 +1,131 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\HTMLControl;
use Phast\HTMLControls\Anchor;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
class Button extends WebControl
{
public $DropDownControls;
public $DropDownDirection;
public $DropDownRequired;
public $IconName;
public $TargetFrame;
public $TargetURL;
public $TargetScript;
public $Text;
/**
* Determines whether this Button is rendered as an HTML Input control with type Submit.
* @var boolean
*/
public $UseSubmitBehavior;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "pwt-Button";
$this->DropDownControls = array();
$this->DropDownRequired = false;
$this->IconName = null;
$this->UseSubmitBehavior = false;
$this->ParseChildElements = true;
}
protected function RenderBeginTag()
{
if ($this->UseSubmitBehavior)
{
$tag = new Input();
foreach ($this->ClassList as $className)
{
if ($className == "pwt-Button") continue;
$tag->ClassList[] = $className;
}
$tag->ClassList = $this->ClassList;
$tag->ClassList[] = $this->CssClass;
$tag->Attributes[] = new WebControlAttribute("id", $this->ClientID);
$tag->Type = InputType::Submit;
$tag->Attributes[] = new WebControlAttribute("value", $this->Text);
$this->Controls[] = $tag;
}
else
{
$tag = new Anchor();
$tag->ClassList = $this->ClassList;
$tag->ClassList[] = $this->CssClass;
if ($this->ClientID != null)
{
$tag->Attributes[] = new WebControlAttribute("id", $this->ClientID);
}
else
{
$tag->Attributes[] = new WebControlAttribute("id", $this->ID);
}
$tag->TargetFrame = $this->TargetFrame;
$tag->TargetURL = $this->TargetURL;
$tag->TargetScript = $this->TargetScript;
if ($this->IconName != null)
{
$i = new HTMLControl("i");
$i->ClassList[] = "fa";
$i->ClassList[] = "fa-" . $this->IconName;
$tag->Controls[] = $i;
}
$spanText = new HTMLControl("span");
$spanText->ClassList[] = "Text";
$spanText->InnerHTML = $this->Text;
$tag->Controls[] = $spanText;
$this->Controls[] = $tag;
}
if (count($this->DropDownControls) > 0)
{
$this->ClassList[] = "pwt-DropDownButton";
}
if ($this->DropDownRequired)
{
$this->ClassList[] = "pwt-DropDownRequired";
}
if ($this->DropDownDirection != null)
{
$this->Attributes[] = new WebControlAttribute("data-pwt-dropdown-direction", $this->DropDownDirection);
}
$aDropDown = new Anchor();
$aDropDown->ClassList[] = "pwt-Button pwt-DropDownButton";
$aDropDown->InnerHTML = "&nbsp;";
$this->Controls[] = $aDropDown;
$divDropDown = new HTMLControl("div");
$divDropDown->ClassList[] = "pwt-DropDownContent Popup";
$divDropDown->Controls = $this->DropDownControls;
$this->Controls[] = $divDropDown;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,211 @@
<?php
namespace Phast\WebControls;
use Phast\Enumeration;
use Phast\System;
use Phast\WebControl;
use Phast\HorizontalAlignment;
class ButtonGroupImagePosition extends Enumeration
{
const AboveText = 1;
const BelowText = 2;
}
class ButtonGroupOrientation extends Enumeration
{
const Horizontal = 1;
const Vertical = 2;
}
class ButtonGroupButtonAspectRatioPreservationMode extends Enumeration
{
const None = 0;
const FitWidth = 1;
const FitHeight = 2;
const FitBoth = 3;
}
class ButtonGroup extends WebControl
{
public $Orientation;
public $ButtonSize;
public $ButtonWidth;
public $ButtonHeight;
public $Items;
public function __construct($id)
{
parent::__construct($id);
$this->Orientation = ButtonGroupOrientation::Horizontal;
$this->ParseChildElements = true;
}
protected function RenderContent()
{
?>
<div class="ButtonGroup<?php switch ($this->Orientation)
{
case "Vertical":
case ButtonGroupOrientation::Vertical:
{
echo(" ButtonGroupVertical");
break;
}
case "Horizontal":
case ButtonGroupOrientation::Horizontal:
{
echo(" ButtonGroupHorizontal");
break;
}
} ?>" style="<?php switch($this->HorizontalAlignment)
{
case "Left":
case HorizontalAlignment::Left:
{
echo("text-align: left;");
break;
}
case "Center":
case HorizontalAlignment::Center:
{
echo("text-align: center;");
break;
}
case "Right":
case HorizontalAlignment::Right:
{
echo("text-align: right;");
break;
}
}?>">
<?php
$buttonWidth = 160;
$buttonHeight = 160;
$buttonActualWidth = 128;
$buttonActualHeight = 128;
if (is_numeric($this->ButtonSize))
{
$buttonWidth = $this->ButtonSize + 32;
$buttonHeight = $this->ButtonSize + 32;
$buttonActualWidth = $this->ButtonSize;
$buttonActualHeight = $this->ButtonSize;
}
else
{
if (is_numeric($this->ButtonWidth))
{
$buttonWidth = $this->ButtonWidth + 32;
$buttonActualWidth = $this->ButtonWidth;
}
if (is_numeric($this->ButtonHeight))
{
$buttonHeight = $this->ButtonHeight + 32;
$buttonActualHeight = $this->ButtonHeight;
}
}
if (is_array($this->Items))
{
foreach ($this->Items as $item)
{
?>
<a class="ButtonGroupButton"<?php if ($item->NavigationURL != null) { echo (" href=\"" . System::ExpandRelativePath($item->NavigationURL) . "\""); } if ($item->OnClientClick != null) { echo (" onclick=\"" . $item->OnClientClick . "\""); } echo (" style=\"width: " . $buttonWidth . "px; height: " . $buttonHeight . "px; visibility: " . ($item->Visible ? "visible" : "hidden") . ";\""); ?>>
<?php
if ($item->ImagePosition == ButtonGroupImagePosition::AboveText)
{
?>
<img src="<?php echo(System::ExpandRelativePath($item->ImageURL)); ?>" title="<?php echo($item->Title); ?>" style="<?php
switch ($item->AspectRatioPreservationMode)
{
case ButtonGroupButtonAspectRatioPreservationMode::FitWidth:
{
echo("width: " . $buttonActualWidth . "px;");
break;
}
case ButtonGroupButtonAspectRatioPreservationMode::FitHeight:
{
echo("height: " . $buttonActualHeight . "px;");
break;
}
case ButtonGroupButtonAspectRatioPreservationMode::FitBoth:
{
echo("width: " . $buttonActualWidth . "px;");
echo("height: " . $buttonActualHeight . "px;");
break;
}
}?>" />
<?php
}
?>
<span class="ButtonGroupButtonText"><?php echo($item->Title); ?></span>
<?php
if ($item->ImagePosition == ButtonGroupImagePosition::BelowText)
{
?>
<img src="<?php echo(System::ExpandRelativePath($item->ImageURL)); ?>" title="<?php echo($item->Title); ?>" style="<?php
switch ($item->AspectRatioPreservationMode)
{
case ButtonGroupButtonAspectRatioPreservationMode::FitWidth:
{
echo("width: " . $buttonActualWidth . "px;");
break;
}
case ButtonGroupButtonAspectRatioPreservationMode::FitHeight:
{
echo("height: " . $buttonActualHeight . "px;");
break;
}
case ButtonGroupButtonAspectRatioPreservationMode::FitBoth:
{
echo("width: " . $buttonActualWidth . "px;");
echo("height: " . $buttonActualHeight . "px;");
break;
}
}
?>" />
<?php
}
?>
</a>
<?php
}
}
?></div><?php
}
}
class ButtonGroupItem
{
}
class ButtonGroupButton extends ButtonGroupItem
{
public $Name;
public $Title;
public $Description;
public $ImageURL;
public $NavigationURL;
public $OnClientClick;
public $ImagePosition;
public $AspectRatioPreservationMode;
public $Visible;
public function __construct($name, $title, $description = null, $imageURL = null, $navigationURL = null, $onClientClick = null)
{
$this->Name = $name;
$this->Title = $title;
$this->Description = $description;
$this->ImageURL = $imageURL;
$this->NavigationURL = $navigationURL;
$this->OnClientClick = $onClientClick;
$this->ImagePosition = ButtonGroupImagePosition::AboveText;
$this->AspectRatioPreservationMode = ButtonGroupButtonAspectRatioPreservationMode::FitHeight;
$this->Visible = true;
}
}
class ButtonGroupSeparator extends ButtonGroupItem
{
}
class ButtonGroupLineBreak extends ButtonGroupItem
{
}
?>

View File

@ -0,0 +1,81 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\HTMLControl;
class CommandBarContainer extends WebControl
{
public $Items;
public function __construct()
{
$this->TagName = "div";
$this->ClassList[] = "CommandBar";
}
protected function RenderContent()
{
foreach ($this->Items as $item)
{
$item->Render();
}
}
}
class CommandBar
{
public $ID;
public $Title;
}
class CommandBarItem
{
public $ID;
public function Render()
{
$this->RenderContent();
}
protected function RenderContent()
{
}
}
class CommandBarItemButton extends CommandBarItem
{
public $Title;
public $ImageURL;
public $TargetURL;
public $TargetScript;
public $Items;
public function __construct()
{
$this->Items = array();
}
protected function RenderContent()
{
echo("<div class=\"CommandBarItem\">");
echo("<span class=\"Text\">" . $this->Title . "</span>");
echo("<div class=\"Menu\">");
foreach ($this->Items as $item)
{
$item->Render();
}
echo("</div>");
echo("</div>");
}
}
class CommandBarItemSeparator extends CommandBarItem
{
protected function RenderContent()
{
echo("<div class=\"CommandBarSeparator\"></div>");
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
/**
* Provides a simple container for child controls that does not render any extra markup to the HTML page.
* @author Michael Becker
*
*/
class Container extends WebControl
{
public function __construct()
{
parent::__construct();
$this->ParseChildElements = false;
}
}
?>

View File

@ -0,0 +1,88 @@
<?php
namespace Phast\WebControls;
use Phast\HTMLControl;
use Phast\WebControl;
use Phast\WebControlAttribute;
class Countdown extends WebControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "Countdown";
}
protected function RenderBeginTag()
{
$year = 2015;
$month = 4;
$day = 25;
$hour = 0;
$minute = 0;
$second = 0;
$this->Attributes[] = new WebControlAttribute("data-target-year", $year);
$this->Attributes[] = new WebControlAttribute("data-target-month", $month);
$this->Attributes[] = new WebControlAttribute("data-target-day", $day);
$this->Attributes[] = new WebControlAttribute("data-target-hour", $hour);
$this->Attributes[] = new WebControlAttribute("data-target-minute", $minute);
$this->Attributes[] = new WebControlAttribute("data-target-second", $second);
$this->HasContent = true;
// quickly generate 6 child controls, one each for Year, Month, Day, Hour, Minute, Second
for ($i = 0; $i < 6; $i++)
{
$div = new HTMLControl("div");
$div->ClassList[] = "Segment";
$divContent = new HTMLControl("div");
$divContent->ClassList[] = "Content";
$divContent->InnerHTML = "0";
$div->Controls[] = $divContent;
$divTitle = new HTMLControl("div");
$divTitle->ClassList[] = "Title";
switch ($i)
{
case 0:
{
$divTitle->InnerHTML = "Years";
break;
}
case 1:
{
$divTitle->InnerHTML = "Months";
break;
}
case 2:
{
$divTitle->InnerHTML = "Days";
break;
}
case 3:
{
$divTitle->InnerHTML = "Hours";
break;
}
case 4:
{
$divTitle->InnerHTML = "Minutes";
break;
}
case 5:
{
$divTitle->InnerHTML = "Seconds";
break;
}
}
$div->Controls[] = $divTitle;
$this->Controls[] = $div;
}
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,51 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\WebScript;
class Disclosure extends WebControl
{
public $Expanded;
public $Title;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "Disclosure";
}
protected function OnInitialize()
{
$parent = $this->FindParentPage();
if ($parent != null) $parent->Scripts[] = new WebScript("$(PhastStaticPath)/Scripts/Controls/Disclosure.js");
}
protected function RenderBeginTag()
{
if ($this->Expanded)
{
$this->ClassList[] = "Expanded";
$this->Attributes[] = new WebControlAttribute("data-expanded", "true");
}
else
{
$this->Attributes[] = new WebControlAttribute("data-expanded", "false");
}
parent::RenderBeginTag();
}
protected function BeforeContent()
{
echo("<div class=\"Title\"><a href=\"#\"><span class=\"Title\">" . $this->Title . "</span></a><div class=\"Chevron\"></div></div>");
echo("<div class=\"Content\">");
}
protected function AfterContent()
{
echo("</div>");
}
}
?>

View File

@ -0,0 +1,115 @@
<?php
namespace Phast\WebControls;
use Phast\Enumeration;
use Phast\WebControl;
class FlyoutTabStripPosition extends Enumeration
{
const Top = 1;
const Bottom = 2;
const Left = 3;
const Right = 4;
}
class FlyoutTabStripItem
{
public $ID;
public $Title;
public $ImageURL;
public $Content;
public $RenderContent;
public function __construct($id, $title, $imageUrl = null, $contentOrFunction = null)
{
$this->ID = $id;
$this->Title = $title;
$this->ImageURL = $imageURL;
if ($contentOrFunction != null)
{
if (is_callable($contentOrFunction))
{
$this->Content = null;
$this->RenderContent = $contentOrFunction;
}
else
{
$this->Content = $contentOrFunction;
$this->RenderContent = null;
}
}
}
}
class FlyoutTabStrip extends WebControl
{
public $Items;
public $Position;
public function __construct($id)
{
parent::__construct($id);
$this->Position = FlyoutTabStripPosition::Right;
}
protected function RenderContent()
{
?>
<div class="FlyoutTabStrip <?php switch ($this->Position)
{
case FlyoutTabStripPosition::Top:
{
echo("Top");
break;
}
case FlyoutTabStripPosition::Bottom:
{
echo("Bottom");
break;
}
case FlyoutTabStripPosition::Left:
{
echo("Left");
break;
}
case FlyoutTabStripPosition::Right:
{
echo("Right");
break;
}
}?>">
<div class="FlyoutTabs">
<?php
foreach ($this->Items as $item)
{
?>
<div id="FlyoutTabContainer_<?php echo($this->ID); ?>_<?php echo($item->ID); ?>_Tab" onclick="<?php echo($this->ID); ?>.ToggleItem('<?php echo($item->ID); ?>');" title="<?php echo($item->Title); ?>" class="FlyoutTab"><img src="<?php echo(\System::ExpandRelativePath($item->ImageURL)); ?>" alt="<?php echo($item->Title); ?>" title="<?php echo($item->Title); ?>" /></div>
<?php
}
?>
</div>
<div class="FlyoutTabContents">
<?php
foreach ($this->Items as $item)
{
?><div id="FlyoutTabContainer_<?php echo($this->ID); ?>_<?php echo($item->ID); ?>_Content" class="FlyoutTabContent"><?php
if ($item->RenderContent != null && is_callable($item->RenderContent))
{
call_user_func($item->RenderContent);
}
else if ($item->Content != null)
{
echo($item->Content);
}
?></div>
<?php
}
?>
</div>
</div>
<script type="text/javascript">
var <?php echo($this->ID); ?> = new FlyoutTabContainer("<?php echo($this->ID); ?>");
</script>
<?php
}
}
?>

View File

@ -0,0 +1,446 @@
<?php
namespace Phast\WebControls;
use Phast\HTMLControl;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
use Phast\HTMLControls\HTMLControlSelect;
use Phast\HTMLControls\HTMLControlSelectOption;
use Phast\HTMLControls\HTMLControlTextArea;
use Phast\WebControlAttribute;
use Phast\Enumeration;
use Phast\System;
class FormViewLabelStyle extends Enumeration
{
/**
* The labels for FormView items are rendered as an HTML <label> element beside the form element.
* @var FormViewLabelStyle
*/
const Label = 1;
/**
* The labels for FormView items are rendered in-place where possible.
* @var FormViewLabelStyle
*/
const Placeholder = 2;
}
class FormView extends \Phast\WebControl
{
/**
* The style of the labels applied to FormView items.
* @var FormViewLabelStyle
*/
public $LabelStyle;
/**
* Array of FormViewItems contained within this FormView.
* @var FormViewItem[]
*/
public $Items;
public function GetItemByID($id)
{
foreach ($this->Items as $item)
{
if ($item->ID == $id) return $item;
}
return null;
}
public function __construct()
{
parent::__construct();
$this->ParseChildElements = true;
$this->TagName = "div";
$this->ClassList[] = "FormView";
}
protected function RenderContent()
{
foreach ($this->Items as $item)
{
$div = new HTMLControl("div");
$div->ID = "FormView_" . $this->ID . "_" . $item->ID;
$div->ClassList[] = "Field";
if ($item->Required) $div->ClassList[] = "Required";
if ($item->GenerateLabel)
{
$title = $item->Title;
$i = stripos($title, "_");
$char = null;
if ($i !== FALSE)
{
$before = substr($title, 0, $i);
$after = substr($title, $i + 1);
$char = substr($after, 0, 1);
$title = $before . "<u>" . $char . "</u>" . substr($after, 1);
}
$lbl = new HTMLControl("label");
$lbl->Attributes[] = new WebControlAttribute("for", $item->GetInputElementID());
if ($char !== null)
{
$lbl->Attributes[] = new WebControlAttribute("accesskey", $char);
echo(" accesskey=\"" . $char . "\"");
}
if ($item->IconName != "")
{
$i = new HTMLControl("i");
$i->ClassList[] = "fa";
$i->ClassList[] = "fa-" . $item->IconName;
$lbl->Controls[] = $i;
}
$spanText = new HTMLControl("span");
$spanText->ClassList[] = "Text";
$spanText->InnerHTML = $title;
$lbl->Controls[] = $spanText;
$div->Controls[] = $lbl;
}
$ctl = $item->CreateControl();
if ($ctl != null) $div->Controls[] = $ctl;
$div->Render();
}
}
}
abstract class FormViewItem
{
public $ID;
public $Name;
public $Title;
public $DefaultValue;
public $Value;
public $Required;
public $IconName;
public $GenerateLabel;
public $ReadOnly;
public function GetInputElementID()
{
return $this->ID;
}
/**
* The client-side script called when the value of this FormViewItem changed and validated.
* @var string
*/
public $OnClientValueChanged;
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
$this->ID = $id;
if ($name == null) $name = $id;
$this->Name = $name;
if ($title == null) $title = $name;
$this->Title = $title;
$this->DefaultValue = $defaultValue;
$this->Required = false;
$this->ParseChildElements = false;
$this->GenerateLabel = true;
$this->ReadOnly = false;
}
public function CreateControl()
{
return $this->CreateControlInternal();
}
protected abstract function CreateControlInternal();
}
class FormViewItemSeparator extends FormViewItem
{
public function __construct($id = null, $title = null)
{
parent::__construct($id, $id, $title);
$this->GenerateLabel = false;
}
protected function CreateControlInternal()
{
$divSeparator = new HTMLControl("div");
$divSeparator->ClassList[] = "Separator";
$divTitle = new HTMLControl("div");
$divTitle->ClassList[] = "Title";
$divTitle->InnerHTML = $this->Title;
$divSeparator->Controls[] = $divTitle;
return $divSeparator;
}
}
class FormViewItemLabel extends FormViewItem
{
/**
* Creates a new Label FormViewItem with the given parameters.
* @param string $id The control ID for the FormViewItem.
* @param string $name The name of the form field to associate with the FormViewItem.
* @param string $title The title of the FormViewItem.
* @param string $defaultValue The default value of the FormViewItem.
*/
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new HTMLControl("div");
$elem->ID = $this->ID;
$elem->Name = $this->Name;
$elem->InnerHTML = $this->DefaultValue;
if (isset($this->Value))
{
if (is_string($this->Value))
{
$elem->InnerHTML = System::ExpandRelativePath($this->Value);
}
}
return $elem;
}
}
class FormViewItemText extends FormViewItem
{
/**
* Text that is displayed in the textbox of the FormViewItem when the user has not entered a value.
* @var string
*/
public $PlaceholderText;
/**
* Creates a new Text FormViewItem with the given parameters.
* @param string $id The control ID for the FormViewItem.
* @param string $name The name of the form field to associate with the FormViewItem.
* @param string $title The title of the FormViewItem.
* @param string $defaultValue The default value of the FormViewItem.
*/
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new Input();
$elem->ID = $this->ID;
$elem->Type = InputType::Text;
$elem->Name = $this->Name;
$elem->Value = System::ExpandRelativePath($this->DefaultValue);
if (isset($this->Value)) $elem->Value = System::ExpandRelativePath($this->Value);
if (isset($this->PlaceholderText))
{
$elem->PlaceholderText = $this->PlaceholderText;
}
if ($this->OnClientValueChanged != null)
{
$elem->Attributes[] = new WebControlAttribute("onchange", $this->OnClientValueChanged);
}
return $elem;
}
}
class FormViewItemPassword extends FormViewItemText
{
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new Input();
$elem->ID = $this->ID;
$elem->Type = InputType::Password;
$elem->Name = $this->Name;
$elem->Value = System::ExpandRelativePath($this->DefaultValue);
if (isset($this->Value)) $elem->Value = System::ExpandRelativePath($this->Value);
if (isset($this->PlaceholderText))
{
$elem->PlaceholderText = $this->PlaceholderText;
}
return $elem;
}
}
class FormViewItemMemo extends FormViewItemText
{
public $Rows;
public $Columns;
public $PlaceholderText;
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new HTMLControlTextArea();
$elem->ID = $this->ID;
$elem->Name = $this->Name;
if (isset($this->Rows)) $elem->Rows = $this->Rows;
if (isset($this->Columns)) $elem->Columns = $this->Columns;
$elem->Value = System::ExpandRelativePath($this->DefaultValue);
if (isset($this->Value)) $elem->Value = System::ExpandRelativePath($this->Value);
if (isset($this->PlaceholderText)) $elem->PlaceholderText = $this->PlaceholderText;
return $elem;
}
}
class FormViewItemNumber extends FormViewItemText
{
public $MinimumValue;
public $MaximumValue;
/**
* Creates a new Number FormViewItem with the given parameters.
* @param string $id The control ID for the FormViewItem.
* @param string $name The name of the form field to associate with the FormViewItem.
* @param string $title The title of the FormViewItem.
* @param string $defaultValue The default value of the FormViewItem.
*/
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new Input();
$elem->ID = $this->ID;
$elem->Type = InputType::Number;
$elem->Name = $this->Name;
if ($this->MaximumValue != null)
{
$elem->Attributes[] = new WebControlAttribute("max", $this->MaximumValue);
}
if ($this->MinimumValue != null)
{
$elem->Attributes[] = new WebControlAttribute("min", $this->MinimumValue);
}
$elem->Value = System::ExpandRelativePath($this->DefaultValue);
if (isset($this->Value)) $elem->Value = System::ExpandRelativePath($this->Value);
if (isset($this->PlaceholderText))
{
$elem->PlaceholderText = $this->PlaceholderText;
}
if ($this->OnClientValueChanged != null)
{
$elem->Attributes[] = new WebControlAttribute("onchange", $this->OnClientValueChanged);
}
return $elem;
}
}
class FormViewItemBoolean extends FormViewItem
{
public function __construct($id = null, $name = null, $title = null, $defaultValue = null)
{
parent::__construct($id, $name, $title, $defaultValue);
}
protected function CreateControlInternal()
{
$elem = new Input();
$elem->ID = $this->ID;
$elem->Type = InputType::CheckBox;
$elem->Name = $this->Name;
if ($this->DefaultValue)
{
$elem->Attributes[] = new WebControlAttribute("checked", "checked");
}
return $elem;
}
}
class FormViewItemChoice extends FormViewItem
{
public $EnableMultipleSelection;
public $RequireSelectionFromChoices;
/**
* The items available for selection.
* @var FormViewItemChoiceValue[]
*/
public $Items;
public function __construct($id = null, $name = null, $title = null, $defaultValue = null, $items = null)
{
parent::__construct($id, $name, $title, $defaultValue);
if (is_array($items))
{
$this->Items = $items;
}
else
{
$this->Items = array();
}
$this->ParseChildElements = true;
}
public function GetInputElementID()
{
return $this->ID . "_InputElement";
}
protected function CreateControlInternal()
{
$elem = new TextBox();
$elem->ID = $this->ID;
$elem->Name = $this->Name;
$elem->EnableMultipleSelection = $this->EnableMultipleSelection;
$elem->RequireSelectionFromChoices = $this->RequireSelectionFromChoices;
$elem->ClearOnFocus = $elem->RequireSelectionFromChoices;
foreach ($this->Items as $item)
{
$elem->Items[] = new TextBoxItem($item->Title, System::ExpandRelativePath($item->Value), $item->Selected);
}
return $elem;
}
}
class FormViewItemChoiceValue
{
public $Title;
public $Value;
public $Selected;
public function __construct($title = null, $value = null, $selected = false)
{
$this->Title = $title;
$this->Value = $value;
$this->Selected = $selected;
}
}
class FormViewItemDateTime extends FormViewItem
{
public $Nullable;
public $NullableOptionText;
public function __construct($id = null, $name = null, $title = null, $defaultValue = null, $nullable = null)
{
parent::__construct($id, $name, $title, $defaultValue);
$this->Nullable = $nullable;
}
protected function CreateControlInternal()
{
$elem = new Input();
$elem->ID = $this->ID;
$elem->Type = InputType::Text;
$elem->Name = $this->Name;
return $elem;
}
}
?>

View File

@ -0,0 +1,26 @@
<?php
namespace Phast\WebControls;
class ImageGallery extends \Phast\WebControl
{
protected function RenderContent()
{
?>
<div class="ImageGallery" id="ImageGallery_<?php echo($this->ID); ?>">
<div class="ImageBrowser">
<a class="NavigationButton Left" href="#" onclick="<?php echo($this->ID); ?>.GoToPreviousImage();">&nbsp;</a>
<div class="CurrentImage">&nbsp;</div>
<a class="NavigationButton Right" href="#" onclick="<?php echo($this->ID); ?>.GoToNextImage();">&nbsp;</a>
</div>
<div class="Thumbnails">
<a href="#"><img src="" /></a>
<a href="#"><img src="" /></a>
<a href="#"><img src="" /></a>
<a href="#"><img src="" /></a>
</div>
</div>
<script type="text/javascript">var <?php echo($this->ID); ?> = new ImageGallery("<?php echo($this->ID); ?>");</script>
<?php
}
}
?>

View File

@ -0,0 +1,406 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\WebScript;
use Phast\WebStyleSheetRule;
use Phast\HTMLControls\Anchor;
use Phast\HTMLControls\HTMLControlTable;
use Phast\HTMLControls\HTMLControlForm;
use Phast\HTMLControls\HTMLControlFormMethod;
use Phast\Enumeration;
use Phast\HTMLControl;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
use Phast\HTMLControls\Literal;
abstract class ListViewMode extends Enumeration
{
const Icon = 1;
const Tile = 2;
const Detail = 3;
const Thumbnail = 4;
}
class ListViewColumnCheckBox extends ListViewColumn
{
public $Checked;
public function __construct($id = null, $title = null, $imageURL = null, $width = null, $checked = false)
{
parent::__construct($id, $title, $imageURL, ($width == null ? "64px" : $width));
$this->Checked = $checked;
}
}
class ListViewColumn
{
public $ID;
public $Title;
public $ImageURL;
/**
* True if this ListViewColumn should be hidden on mobile devices; false if it should be displayed.
* @var boolean
*/
public $MobileHidden;
public $Visible;
public $Width;
public $Template;
public function __construct($id = null, $title = null, $imageURL = null, $width = null)
{
$this->ID = $id;
$this->Title = $title;
$this->ImageURL = $imageURL;
$this->MobileHidden = false;
$this->Visible = true;
$this->Width = $width;
$this->ParseChildElements = false;
}
}
class ListViewItem
{
public $ID;
public $Columns;
public $Checked;
public $Selected;
public $NavigateURL;
public $OnClientClick;
public $Value;
public function GetColumnByID($id)
{
foreach ($this->Columns as $column)
{
if ($column->ID == $id) return $column;
}
return null;
}
public function __construct($columns = null, $selected = false)
{
if ($columns != null)
{
$this->Columns = $columns;
}
$this->Selected = $selected;
$this->ParseChildElements = true;
}
}
class ListViewItemColumn
{
public $ID;
public $Text;
public $Content;
public $UserData;
public $ParseChildElements;
public function __construct($id = null, $content = null, $text = null, $userData = null)
{
$this->ID = $id;
$this->Content = $content;
if ($text == null) $text = $content;
$this->Text = $text;
$this->UserData = $userData;
$this->ParseChildElements = true;
}
}
class ListView extends WebControl
{
public $AllowFiltering;
public $EnableAddRemoveRows;
public $EnableMultipleSelection;
/**
* The columns on this ListView.
* @var ListViewColumn[]
*/
public $Columns;
/**
* The items on this ListView.
* @var ListViewItem[]
*/
public $Items;
public $EnableHotTracking;
public $ShowBorder;
public $ShowGridLines;
public $HighlightAlternateRows;
public $EnableRowCheckBoxes;
public $PlaceholderText;
public $Mode;
public $OnItemActivate;
public function GetColumnByID($id)
{
foreach ($this->Columns as $column)
{
if ($column->ID == $id) return $column;
}
return null;
}
public function __construct()
{
parent::__construct();
$this->Columns = array();
$this->Items = array();
$this->AllowFiltering = true;
$this->Mode = ListViewMode::Detail;
$this->ShowBorder = true;
$this->ShowGridLines = true;
$this->HighlightAlternateRows = true;
$this->EnableAddRemoveRows = false;
$this->EnableHotTracking = true;
$this->EnableMultipleSelection = false;
$this->ParseChildElements = true;
$this->PlaceholderText = "There are no items";
}
protected function OnInitialize()
{
$parent = $this->FindParentPage();
if ($parent != null) $parent->Scripts[] = new WebScript("$(System.StaticPath)/Scripts/Controls/ListView.js");
}
protected function RenderContent()
{
$div = new HTMLControl("div");
$div->ClassList[] = "ListView";
if (count($this->Items) <= 0) $div->ClassList[] = "Empty";
foreach ($this->ClassList as $str)
{
$div->ClassList[] = $str;
}
foreach ($this->Attributes as $att)
{
$div->Attributes[] = $att;
}
$div->ID = $this->ID;
// set up CSS classes for properties
if ($this->ShowBorder) $div->ClassList[] = "HasBorder";
if ($this->EnableHotTracking) $div->ClassList[] = "HotTracking";
if ($this->ShowGridLines) $div->ClassList[] = "GridLines";
if ($this->HighlightAlternateRows) $div->ClassList[] = "AlternateRowHighlight";
if ($this->AllowFiltering) $div->ClassList[] = "AllowFiltering";
if ($this->EnableRowCheckBoxes) $div->ClassList[] = "RowCheckBoxes";
if ($this->EnableMultipleSelection) $div->ClassList[] = "MultiSelect";
if ($this->EnableAddRemoveRows) $div->ClassList[] = "EnableAddRemoveRows";
if ($this->Width != null) $div->StyleRules[] = new WebStyleSheetRule("width", $this->Width);
switch ($this->Mode)
{
case "Detail":
case ListViewMode::Detail:
{
$div->Attributes[] = new WebControlAttribute("data-mode", "Detail");
break;
}
case "Thumbnail":
case ListViewMode::Thumbnail:
{
$div->Attributes[] = new WebControlAttribute("data-mode", "Thumbnail");
break;
}
case "Icon":
case ListViewMode::Icon:
{
$div->Attributes[] = new WebControlAttribute("data-mode", "Icon");
break;
}
case "Tile":
case ListViewMode::Tile:
{
$div->Attributes[] = new WebControlAttribute("data-mode", "Tile");
break;
}
}
$divColumnHeaders = new HTMLControl("div");
$divColumnHeaders->ClassList[] = "ListViewColumnHeaders";
$lvcCount = 0;
$divItemColumn = new HTMLControl("div");
$divItemColumn->ClassList[] = "ListViewColumnHeader";
$divItemColumn->ClassList[] = "AddRemoveRowColumnHeader";
$aAdd = new HTMLControl("a");
$aAdd->ClassList[] = "Add";
$divItemColumn->Controls[] = $aAdd;
$divColumnHeaders->Controls[] = $divItemColumn;
$lvcCount++;
$count = count($this->Columns);
for ($i = 0; $i < $count; $i++)
{
$column = $this->Columns[$i];
$divColumnHeader = new HTMLControl("div");
$divColumnHeader->Attributes[] = new WebControlAttribute("data-id", $column->ID);
$divColumnHeader->ClassList[] = "ListViewColumnHeader";
if ($column->Width != null)
{
$divColumnHeader->StyleRules[] = new WebStyleSheetRule("width", $column->Width);
}
$classList = array();
if ($column->MobileHidden) $divColumnHeader->ClassList[] = "MobileHidden";
if (get_class($column) == "Phast\\WebControls\\ListViewColumnCheckBox")
{
$input = new Input();
$input->Type = InputType::CheckBox;
$divColumnHeader->Controls[] = $input;
}
else if (get_class($column) == "Phast\\WebControls\\ListViewColumn")
{
$link = new Anchor();
$link->TargetScript = "lvListView.Sort('" . $column->ID . "'); return false;";
$link->InnerHTML = $column->Title;
$divColumnHeader->Controls[] = $link;
}
else
{
$literal = new Literal();
$literal->Value = "<!-- Undefined column class: " . get_class($column) . " -->";
$divColumnHeader->Controls[] = $literal;
}
if (!$column->Visible)
{
$divColumnHeader->ClassList[] = "Hidden";
}
else
{
$lvcCount++;
}
if ($lvcCount == 1)
{
$divColumnHeader->ClassList[] = "FirstVisibleChild";
}
else if ($lvcCount == count($this->Columns))
{
$divColumnHeader->ClassList[] = "LastVisibleChild";
}
$divItemTemplate = new HTMLControl("div");
$divItemTemplate->ClassList[] = "ItemTemplate";
$divItemTemplate->Content = $column->Template;
$divColumnHeader->Controls[] = $divItemTemplate;
$divColumnHeaders->Controls[] = $divColumnHeader;
if ($i < $count - 1)
{
$divColumnResizer = new HTMLControl("div");
$divColumnResizer->ClassList[] = "ColumnResizer";
$divColumnHeaders->Controls[] = $divColumnResizer;
}
}
$div->Controls[] = $divColumnHeaders;
$divEmptyMessage = new HTMLControl("div");
$divEmptyMessage->ClassList[] = "ListViewEmptyMessage";
$divEmptyMessage->InnerHTML = $this->PlaceholderText;
$div->Controls[] = $divEmptyMessage;
$divItems = new HTMLControl("div");
$divItems->ClassList[] = "ListViewItems";
foreach ($this->Items as $item)
{
$divItem = new HTMLControl("div");
$divItem->ClassList[] = "ListViewItem";
if ($item->Value != null)
{
$divItem->Attributes[] = new WebControlAttribute("data-value", $item->Value);
}
$count = count($this->Columns);
$lvcCount = 0;
$divItemColumn = new HTMLControl("div");
$divItemColumn->ClassList[] = "ListViewItemColumn";
$divItemColumn->ClassList[] = "AddRemoveRowItemColumn";
$aAdd = new HTMLControl("a");
$aAdd->ClassList[] = "Add";
$divItemColumn->Controls[] = $aAdd;
$aRemove = new HTMLControl("a");
$aRemove->ClassList[] = "Remove";
$divItemColumn->Controls[] = $aRemove;
$divItem->Controls[] = $divItemColumn;
$lvcCount++;
for ($i = 0; $i < $count; $i++)
{
$column = $this->Columns[$i];
$divItemColumn = new HTMLControl("div");
if (!$column->Visible)
{
$divItemColumn->ClassList[] = "Hidden";
}
else
{
$lvcCount++;
}
if ($lvcCount == 1)
{
$divItemColumn->ClassList[] = "FirstVisibleChild";
}
else if ($lvcCount == $max)
{
$divItemColumn->ClassList[] = "LastVisibleChild";
}
$divItemColumn->ClassList[] = "ListViewItemColumn";
$col = $item->GetColumnByID($this->Columns[$i]->ID);
if ($col != null)
{
$divItemColumn->ExtraData = $col->UserData;
$divItemColumn->Content = $col->Content;
}
$divItem->Controls[] = $divItemColumn;
if ($i < $count - 1)
{
$divColumnResizer = new HTMLControl("div");
$divColumnResizer->ClassList[] = "ColumnResizer";
$divItem->Controls[] = $divColumnResizer;
}
}
$divItems->Controls[] = $divItem;
}
$div->Controls[] = $divItems;
$div->Render();
}
}
?>

View File

@ -0,0 +1,273 @@
<?php
namespace Phast\WebControls;
use Phast\Enumeration;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\WebStyleSheetRule;
use Phast\HTMLControl;
use Phast\HTMLControls\Anchor;
use Phast\Phast;
/**
* Provides an enumeration of predefined values for orientation of a menu.
* @author Michael Becker
*/
abstract class MenuOrientation extends Enumeration
{
/**
* The menu is displayed horizontally.
* @var int 1
*/
const Horizontal = 1;
/**
* The menu is displayed vertically.
* @var int 2
*/
const Vertical = 2;
}
class Menu extends WebControl
{
/**
* Determines whether the menu displays horizontally or vertically.
* @var MenuOrientation
*/
public $Orientation;
/**
* A collection of MenuItems on this Menu.
* @var MenuItem
*/
public $Items;
public function __construct()
{
parent::__construct();
$this->Items = array();
$this->ParseChildElements = true;
$this->TagName = "ul";
$this->ClassList[] = "Menu";
if ($this->Top != null) $this->StyleRules[] = new WebStyleSheetRule("top", $this->Top);
if ($this->Left != null) $this->StyleRules[] = new WebStyleSheetRule("left", $this->Left);
if ($this->Width != null) $this->StyleRules[] = new WebStyleSheetRule("width", $this->Width);
if ($this->Height != null) $this->StyleRules[] = new WebStyleSheetRule("height", $this->Height);
if ($this->MaximumWidth != null) $this->StyleRules[] = new WebStyleSheetRule("max-width", $this->MaximumWidth);
if ($this->MaximumHeight != null) $this->StyleRules[] = new WebStyleSheetRule("max-height", $this->MaximumHeight);
}
public function GetItemByID($id)
{
foreach ($this->Items as $item)
{
if ($item->ID == $id) return $item;
}
return null;
}
protected function RenderBeginTag()
{
if ($this->Orientation == "Horizontal" || $this->Orientation == MenuOrientation::Horizontal)
{
$this->ClassList[] = "Horizontal";
}
else if ($this->Orientation == "Vertical" || $this->Orientation == MenuOrientation::Vertical)
{
$this->ClassList[] = "Vertical";
}
$this->Controls = array();
$liArrow = new HTMLControl("li");
$liArrow->ClassList[] = "Arrow";
$this->Controls[] = $liArrow;
foreach ($this->Items as $menuItem)
{
$this->Controls[] = Menu::CreateMenuItemControl($menuItem);
}
parent::RenderBeginTag();
}
public static function CreateMenuItemControl($menuItem)
{
if (get_class($menuItem) == "Phast\\WebControls\\MenuItemCommand")
{
$li = new HTMLControl();
$li->Attributes = $menuItem->Attributes;
$li->TagName = "li";
$li->ClassList[] = "Command";
if ($menuItem->Visible)
{
$li->ClassList[] = "Visible";
}
if ($menuItem->Selected)
{
$li->ClassList[] = "Selected";
}
if (count($menuItem->Items) > 0)
{
$li->ClassList[] = "HasChildren";
}
$a = new Anchor();
$a->TargetURL = $menuItem->TargetURL;
if ($menuItem->OnClientClick != null)
{
$a->Attributes[] = new WebControlAttribute("onclick", $menuItem->OnClientClick);
}
if ($menuItem->IconName != "")
{
$iIcon = new HTMLControl();
$iIcon->TagName = "i";
$iIcon->ClassList[] = "fa";
$iIcon->ClassList[] = "fa-" . $menuItem->IconName;
$a->Controls[] = $iIcon;
}
if ($menuItem->Description != null)
{
$spanTitle = new HTMLControl();
$spanTitle->TagName = "span";
$spanTitle->ClassList[] = "Title";
$spanTitle->InnerHTML = $menuItem->Title;
$a->Controls[] = $spanTitle;
$spanDescription = new HTMLControl();
$spanDescription->TagName = "span";
$spanDescription->ClassList[] = "Description";
$spanDescription->InnerHTML = $menuItem->Description;
$a->Controls[] = $spanDescription;
}
else
{
$spanTitle = new HTMLControl();
$spanTitle->TagName = "span";
$spanTitle->ClassList[] = "Title NoDescription";
$spanTitle->InnerHTML = $menuItem->Title;
$a->Controls[] = $spanTitle;
}
$li->Controls[] = $a;
if (count($menuItem->Items) > 0)
{
$menu = new Menu();
foreach ($menuItem->Items as $item1)
{
$menu->Items[] = $item1;
}
$li->Controls[] = $menu;
}
return $li;
}
else if (get_class($menuItem) == "Phast\\WebControls\\MenuItemHeader")
{
$li = new HTMLControl();
$li->Attributes = $menuItem->Attributes;
$li->TagName = "li";
if ($menuItem->Visible)
{
$li->ClassList[] = "Visible";
}
$li->ClassList[] = "Header";
$spanHeader = new HTMLControl();
$spanHeader->TagName = "span";
$spanHeader->ClassList[] = "Text";
$spanHeader->InnerHTML = $menuItem->Title;
$li->Controls[] = $spanHeader;
return $li;
}
else if (get_class($menuItem) == "Phast\\WebControls\\MenuItemSeparator")
{
$hr = new HTMLControl();
$hr->Attributes = $menuItem->Attributes;
if ($menuItem->Visible)
{
$hr->ClassList[] = "Visible";
}
$hr->TagName = "hr";
return $hr;
}
else
{
System::WriteErrorLog("Unknown MenuItem class: " . get_class($menuItem));
}
}
}
class MenuItem extends WebControl
{
public $Visible;
public function __construct()
{
$this->ParseChildElements = true;
$this->Visible = true;
}
}
class MenuItemHeader extends MenuItem
{
public $Title;
public $Subtitle;
public function __construct($title = null, $subtitle = null)
{
parent::__construct();
$this->Title = $title;
$this->Subtitle = $subtitle;
}
}
class MenuItemCommand extends MenuItem
{
public $Items;
public $IconName;
public $Title;
public $TargetURL;
public $OnClientClick;
public $Selected;
public $Description;
public function GetItemByID($id)
{
foreach ($this->Items as $item)
{
if ($item->ID == $id) return $item;
}
return null;
}
public function __construct($title = null, $targetURL = null, $onClientClick = null, $description = null, $items = null)
{
parent::__construct();
$this->Title = $title;
$this->TargetURL = $targetURL;
$this->OnClientClick = $onClientClick;
$this->Description = $description;
if ($items == null) $items = array();
$this->Items = $items;
}
}
class MenuItemSeparator extends MenuItem
{
}
class MenuItemMenu extends MenuItem
{
public $Title;
public $Items;
public function __construct($title, $menuItems = array())
{
$this->Title = $title;
$this->Items = $menuItems;
}
}
?>

View File

@ -0,0 +1,176 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\HTMLControl;
use Phast\Enumeration;
class MeterDisplayStyle extends Enumeration
{
const None = 0;
const Percent = 1;
const Decimal = 2;
}
class Meter extends WebControl
{
/**
* The current value displayed in this Meter.
* @var double
*/
public $CurrentValue;
/**
* The lowest possible value that can be displayed in this Meter.
* @var double
*/
public $MinimumValue;
/**
* The highest possible value that can be displayed in this Meter.
* @var double
*/
public $MaximumValue;
/**
* The color displayed in the background of the meter fill area.
* @var string
*/
public $BackgroundColor;
/**
* The color displayed in the foreground of the meter fill area.
* @var string
*/
public $ForegroundColor;
/**
* The title of this Meter.
* @var string
*/
public $Title;
/**
* Determines how the value of this Meter should be displayed.
* @var MeterDisplayStyle
*/
public $DisplayStyle;
public function __construct()
{
parent::__construct();
$this->ClassList[] = "Meter";
$this->TagName = "div";
$this->MinimumValue = 0;
$this->MaximumValue = 100;
$this->CurrentValue = 0;
$this->DisplayStyle = MeterDisplayStyle::Percent;
}
private function GetDisplayStyleValue()
{
$strValue = $this->DisplayStyle;
if (is_string($strValue)) $strValue = strtolower($strValue);
return $strValue;
}
protected function RenderBeginTag()
{
$this->Controls = array();
$this->Attributes[] = new WebControlAttribute("data-minimum-value", $this->MinimumValue);
$this->Attributes[] = new WebControlAttribute("data-maximum-value", $this->MaximumValue);
$this->Attributes[] = new WebControlAttribute("data-current-value", $this->CurrentValue);
switch ($this->GetDisplayStyleValue())
{
case "decimal":
case MeterDisplayStyle::Decimal:
{
$this->Attributes[] = new WebControlAttribute("data-display-style", "decimal");
break;
}
case "none":
case MeterDisplayStyle::None:
{
$this->Attributes[] = new WebControlAttribute("data-display-style", "none");
break;
}
case "percent":
case MeterDisplayStyle::Percent:
{
$this->Attributes[] = new WebControlAttribute("data-display-style", "percent");
break;
}
default:
{
}
}
if ($this->BackgroundColor != null)
{
$this->Attributes[] = new WebControlAttribute("data-background-color", $this->BackgroundColor);
}
if ($this->ForegroundColor != null)
{
$this->Attributes[] = new WebControlAttribute("data-foreground-color", $this->ForegroundColor);
}
$divContentWrapper = new HTMLControl("div");
$divContentWrapper->ClassList[] = "ContentWrapper";
$divContent = new HTMLControl("div");
$divContent->ClassList[] = "Content";
$decimalValue = (($this->MinimumValue + $this->CurrentValue) / ($this->MaximumValue - $this->MinimumValue));
if (($this->MaximumValue - $this->MinimumValue) <= 0)
{
$decimalValue = 0;
}
$printedValue = round(($decimalValue * ($this->MaximumValue - $this->MinimumValue)), 0);
$percentValue = round(($decimalValue * 100), 0) . "%";
$stringValue = "";
switch ($this->GetDisplayStyleValue())
{
case "decimal":
case MeterDisplayStyle::Decimal:
{
$stringValue = $printedValue;
break;
}
case "none":
case MeterDisplayStyle::None:
{
$stringValue = "";
break;
}
case "percent":
case MeterDisplayStyle::Percent:
default:
{
$stringValue = $percentValue;
break;
}
}
$divContent->InnerHTML = $stringValue;
$divContentWrapper->Controls[] = $divContent;
$canvas = new HTMLControl("canvas");
$divContentWrapper->Controls[] = $canvas;
$this->Controls[] = $divContentWrapper;
$lblTitle = new HTMLControl("label");
$lblTitle->Attributes[] = new WebControlAttribute("for", $this->ClientID);
$lblTitle->InnerHTML = $this->Title;
$this->Controls[] = $lblTitle;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,141 @@
<?php
namespace Phast\WebControls;
use System;
use Phast\HorizontalAlignment;
use Phast\WebControl;
use Phast\WebStyleSheetRule;
class Panel extends WebControl
{
public $FooterContent;
public $Title;
public $HeaderControls;
public $ContentControls;
public $FooterControls;
public $Collapsible;
public $Expanded;
public function GetAllControls()
{
$ary = array();
foreach ($this->HeaderControls as $ctl)
{
$ary[] = $ctl;
}
foreach ($this->ContentControls as $ctl)
{
$ary[] = $ctl;
}
foreach ($this->FooterControls as $ctl)
{
$ary[] = $ctl;
}
return $ary;
}
public function __construct($id = null, $title = "")
{
parent::__construct($id);
$this->Title = $title;
$this->ParseChildElements = true;
$this->HeaderControls = array();
$this->ContentControls = array();
$this->FooterControls = array();
$this->TagName = "div";
$this->ClassList[] = "Panel";
$this->Collapsible = false;
$this->Expanded = true;
}
protected function RenderBeginTag()
{
if ($this->Collapsible === true || $this->Collapsible === "true")
{
$this->ClassList[] = "Collapsible";
if ($this->Expanded === true || $this->Expanded === "true")
{
$this->ClassList[] = "Expanded";
}
}
switch ($this->HorizontalAlignment)
{
case "Center":
case HorizontalAlignment::Center:
{
$this->StyleRules[] = new WebStyleSheetRule("margin-left", "auto");
$this->StyleRules[] = new WebStyleSheetRule("margin-right", "auto");
break;
}
case "Right":
case HorizontalAlignment::Right:
{
$this->StyleRules[] = new WebStyleSheetRule("margin-left", "auto");
break;
}
}
parent::RenderBeginTag();
}
protected function BeforeContent()
{
if ($this->Title != "")
{
echo("<div class=\"Header\">" . $this->Title . "</div>");
}
echo("<div class=\"Content\">");
}
public function BeginFooter()
{
echo("<div class=\"Footer\">");
}
public function EndFooter()
{
echo("</div>");
}
protected function RenderContent()
{
if (count($this->ContentControls) > 0)
{
foreach ($this->ContentControls as $ctl)
{
$ctl->Render();
}
}
else
{
parent::RenderContent();
}
}
protected function AfterContent()
{
echo("</div>");
if (is_callable($this->FooterContent))
{
$this->BeginFooter();
call_user_func($this->FooterContent);
$this->EndFooter();
}
else if (count($this->FooterControls) > 0)
{
$this->BeginFooter();
foreach ($this->FooterControls as $ctl)
{
$ctl->Render();
}
$this->EndFooter();
}
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
class PanelContainer extends WebControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "PanelContainer";
}
}
?>

View File

@ -0,0 +1,68 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\HTMLControl;
use Phast\WebStyleSheetRule;
class ProgressBar extends WebControl
{
public $MaximumValue;
public $MinimumValue;
public $CurrentValue;
public $Animated;
public $Striped;
public $Text;
public function __construct()
{
parent::__construct();
$this->MinimumValue = 0;
$this->MaximumValue = 100;
$this->CurrentValue = 0;
$this->Animated = false;
$this->Striped = false;
$this->TagName = "div";
$this->ClassList[] = "ProgressBar";
}
protected function RenderBeginTag()
{
if ((is_bool($this->Striped) && $this->Striped) || (is_string($this->Striped) && $this->Striped == "true"))
{
$this->ClassList[] = "Striped";
}
if ((is_bool($this->Animated) && $this->Animated) || (is_string($this->Animated) && $this->Animated == "true"))
{
$this->ClassList[] = "Animated";
}
$divProgressValueFill = new HTMLControl("div");
$divProgressValueFill->ClassList[] = "ProgressValueFill";
$divProgressValueFill->StyleRules[] = new WebStyleSheetRule("width", ((($this->MinimumValue + $this->CurrentValue) / ($this->MaximumValue - $this->MinimumValue)) * 100) . "%");
$divProgressValueFill->Content = "&nbsp;";
$divProgressValueLabel = new HTMLControl("div");
$divProgressValueLabel->ClassList[] = "ProgressValueLabel";
if ($this->Text == "")
{
$divProgressValueLabel->Content = "&nbsp;";
}
else
{
$divProgressValueLabel->Content = $this->Text;
}
$this->Controls = array($divProgressValueFill, $divProgressValueLabel);
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\System;
class PropertyReference extends WebControl
{
public $DefaultValue;
protected function RenderContent()
{
echo(System::GetConfigurationValue($this->ID, $this->DefaultValue));
}
}
?>

View File

@ -0,0 +1,554 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\System;
class Ribbon extends WebControl
{
public $Title;
public $ImageURL;
public $Collapsed;
public $ApplicationMenu;
public $Commands;
public $HelpButton;
public $Tabs;
public $SelectedTab;
public $UserName;
public function __construct($id, $title = null)
{
parent::__construct($id);
$this->Title = $title;
$this->Collapsed = false;
$this->ApplicationMenu = new RibbonApplicationMenuSettings();
$this->HelpButton = new RibbonHelpButtonSettings();
$this->Commands = array();
$this->Tabs = array();
$this->TagName = "div";
}
public function GetCommandByID($id)
{
foreach ($this->Commands as $command)
{
if ($command->ID == $id) return $command;
}
return null;
}
public function GetTabByID($id)
{
foreach ($this->Tabs as $tab)
{
if ($tab->ID === $id) return $tab;
}
return null;
}
protected function OnInitialize()
{
$this->Collapsed = ($this->GetClientProperty("Collapsed", "false") == "true");
$SelectedTabID = ($this->GetClientProperty("ActiveTabID", null));
if ($SelectedTabID != null)
{
$this->SelectedTab = $this->GetTabByID($SelectedTabID);
}
}
private function RenderRibbonTab($tab)
{
echo("<a class=\"RibbonTab");
if ($this->SelectedTab->ID === $tab->ID)
{
echo(" Selected");
}
echo("\" data-tab-id=\"" . $tab->ID . "\" data-tooltip-title=\"" . $tab->ToolTipTitle . "\" data-tooltip-content=\"" . $tab->ToolTipText . "\" href=\"#\"");
if (!$tab->Visible)
{
echo(" style=\"display: none;\"");
}
echo(">");
if ($tab->ImageURL != null)
{
echo("<img src=\"" . System::ExpandRelativePath($tab->ImageURL) . "\" />");
}
echo($tab->Title);
echo("</a>");
}
private function RenderRibbonItem($item)
{
if (get_class($item) == "Phast\\WebControls\\RibbonCommandReferenceItem")
{
$this->RenderRibbonCommand($this->GetCommandByID($item->TargetID));
}
else if (get_class($item) == "Phast\\WebControls\\RibbonSeparatorItem")
{
echo("<span class=\"Separator\">&nbsp;</span>");
}
}
private function RenderRibbonCommand($command)
{
if ($command == null) return;
echo("<div data-tooltip-title=\"" . $command->ToolTipTitle . "\" data-tooltip-content=\"" . $command->ToolTipText . "\" class=\"RibbonCommand Ribbon_" . $this->ID . "_Commands_" . $command->ID);
if ($command->Selected)
{
echo(" Selected");
}
if (!$command->Enabled)
{
echo(" Disabled");
}
if (get_class($command) == "Phast\\WebControls\\RibbonDropDownCommand")
{
echo(" RibbonDropDownCommand");
echo("\">");
$titleText = $command->Title;
$accessKey = null;
$iof = stripos($titleText, "&");
if ($iof !== false)
{
$titleTextBefore = substr($titleText, 0, $iof);
$titleTextAfter = substr($titleText, $iof . 2);
$accessKey = substr($titleText, $iof . 1, 1);
$titleText = $titleTextBefore . "<u>" . $accessKey . "</u>" . $titleTextAfter;
}
echo("<script type=\"text/javascript\">var " . $command->ID . " = new RibbonDropDownCommand('Ribbon_" . $this->ID . "_Commands_" . $command->ID . "');</script>");
echo("<a ");
if ($accessKey != null)
{
echo(" data-accesskey=\"" . $accessKey . "\"");
}
if ($command->TargetURL != null)
{
echo(" href=\"" . System::ExpandRelativePath($command->TargetURL) . "\"");
}
else
{
echo(" href=\"#\"");
}
if ($command->TargetFrame != null)
{
echo(" target=\"" . $command->TargetFrame . "\"");
}
$onclickstr = "var ribbon = Ribbon.FromID('" . $this->ID . "'); ribbon.SetApplicationMenuVisible(false);";
$onclickstr .= "if (ribbon.IsCollapsed() && ribbon.IsOpened())";
$onclickstr .= "{ ribbon.SetOpened(false); };";
$onclickstr .= $command->ID . ".ToggleSelected();";
/*
if ($command->TargetScript != null)
{
$onclickstr .= $command->TargetScript;
}
*/
echo(" onclick=\"" . $onclickstr . "\"");
echo(">");
if ($command->ImageURL != null)
{
echo("<img class=\"Icon\" src=\"" . System::ExpandRelativePath($command->ImageURL) . "\" />");
}
echo("<span class=\"Text\">");
echo($titleText);
echo("</span>");
echo("<span class=\"SpacerText\">");
echo($titleText);
echo("</span>");
echo("<img class=\"DropDownImage\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMNCw0c/NC4EQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAR0lEQVQI12P0Saj6z4AGmBZMbEARWDCxgYHhzrMvDG8+/vrvk1D1/83HX//vPPvCwHjn2RcGBgYGBgFutv8fvv5iZGBgYAAAlbYbf1Hz7NoAAAAASUVORK5CYII=\" />");
echo("</a>");
echo("<div class=\"RibbonDropDownItems Ribbon_" . $this->ID . "_Commands_" . $command->ID . "_DropDownItems\">");
echo("<div class=\"ImageMarginBackground\">&nbsp;</div>");
foreach ($command->Items as $item)
{
$this->RenderRibbonItem($item);
}
echo("</div>");
}
else if (get_class($command) == "Phast\\WebControls\\RibbonButtonCommand")
{
echo(" RibbonButtonCommand");
echo("\">");
$titleText = $command->Title;
$accessKey = null;
$iof = stripos($titleText, "&");
if ($iof !== false)
{
$titleTextBefore = substr($titleText, 0, $iof);
$titleTextAfter = substr($titleText, $iof . 2);
$accessKey = substr($titleText, $iof . 1, 1);
$titleText = $titleTextBefore . "<u>" . $accessKey . "</u>" . $titleTextAfter;
}
echo("<script type=\"text/javascript\">var " . $command->ID . " = new RibbonButtonCommand('Ribbon_" . $this->ID . "_Commands_" . $command->ID . "');</script>");
echo("<a ");
if ($accessKey != null)
{
echo(" data-accesskey=\"" . $accessKey . "\"");
}
if ($command->TargetURL != null)
{
echo(" href=\"" . System::ExpandRelativePath($command->TargetURL) . "\"");
}
else
{
echo(" href=\"#\"");
}
if ($command->TargetFrame != null)
{
echo(" target=\"" . $command->TargetFrame . "\"");
}
$onclickstr = "var ribbon = Ribbon.FromID('" . $this->ID . "'); ribbon.SetApplicationMenuVisible(false);";
$onclickstr .= "if (ribbon.IsCollapsed() && ribbon.IsOpened())";
$onclickstr .= "{ ribbon.SetOpened(false); };";
if ($command->TargetScript != null)
{
$onclickstr .= $command->TargetScript;
}
echo(" onclick=\"" . $onclickstr . "\"");
echo(">");
if ($command->ImageURL != null)
{
echo("<img class=\"Icon\" src=\"" . System::ExpandRelativePath($command->ImageURL) . "\" />");
}
echo("<span class=\"Text\">");
echo($titleText);
echo("</span>");
echo("<span class=\"SpacerText\">");
echo($titleText);
echo("</span>");
echo("</a>");
}
echo("</div>");
}
private function RenderRibbonTabGroup($group)
{
echo("<div class=\"RibbonTabGroup\"");
if (!$group->Visible) echo(" style=\"display: none;\"");
echo(">");
echo("<div class=\"RibbonTabGroupBackground\">&nbsp;</div>");
echo("<div class=\"RibbonTabGroupContent\">");
foreach ($group->Items as $item)
{
$this->RenderRibbonItem($item);
}
echo("</div>");
echo("<div class=\"RibbonTabGroupTitle\">" . $group->Title . "</div>");
echo("</div>");
echo("<span class=\"Separator\"");
if (!$group->Visible) echo(" style=\"display: none;\"");
echo(">&nbsp;</span>");
}
protected function RenderContent()
{
if ($this->Title != null || $this->ImageURL != null)
{
echo("<div class=\"RibbonTitleBar\">");
if ($this->ImageURL != null)
{
echo("<img src=\"" . System::ExpandRelativePath($this->ImageURL) . "\" /> ");
}
if ($this->Title != null)
{
echo("<span class=\"Text\">" . $this->Title . "</span>");
}
echo("</div>");
}
echo ("<div class=\"Ribbon");
if ($this->Collapsed)
{
echo(" Collapsed");
}
echo("\" data-id=\"" . $this->ID . "\">");
echo("<a id=\"Ribbon_" . $this->ID . "_ApplicationButton\" class=\"ApplicationButton\" data-tooltip-title=\"" . $this->ApplicationMenu->ToolTipTitle . "\" data-tooltip-content=\"" . $this->ApplicationMenu->ToolTipText . "\">");
echo("<img class=\"Icon\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAALCAYAAABhwJ3wAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIcEwcFpaQT2QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACW0lEQVQ4y3WTS4sVVxSFv33vqUduJ62ooQUVGhRaElQcBASTQaATW3CoE9H8CSeC0JHuQWfgLwgZCf4B8RVQBCGIBJJBHghOkoCgA1/d9PXWedRyUFW3b2vnTHadfdbZq9baZ9vj/16wf+8O0a6//n1tR2a3j/dbrX+er9rZlZuU23YDILVwCdQEBCBUN9HN7dshHxtg7mx8qctttWZnpuWHQ3NTdYPvoGJir4awjU5AShHJyJwjtbgYE/Pf37dNDIJ7y19LzhGDCD5NnLWFJ4gmc66qPDEmJKiqGl95utydxS9lEz8MEGLAqIkpEkMaWxfWXxJHaw2o1geWOh8CMSSEAIcPAR8CIUTmF3+xSTUAd5ePCzlSECHUYwWjtTc8+vH8Fn43quzV6zd6O/IYoiwLfv3jqX1xaI9GowoBNsHTfZdlwdy3l80NZpqkIPk1FIY8/nlRo9GI9eGQqcGAsiw5eGLJnOqa4CtAFHmGJFTXeF9x7LtrTW0DU1Px4dVzKvIMsdnSfv4JCZhbWLK/b11SmQqyPOPgwpJZNsClOuG9ByDViVo1TS7w4Kcz4j1Fla8Y1CX0etDvjYkM6H20DSrj81Mr9uf1i/rs1Ir18ymsmMal2BIZpJhIEikmfPAsXLhtnV+dottXTirFRD93uDLbIBL0AMqdpGqVw6evWDY1Tb+cBoGTRIyxbZqwXjNLMQRu/PBNU942BjDGgCT6RU6/LNuD7nX1ENArirZ1rQ8y3IPfnthXRw+oe44d0ae7dv3vwP7+5Jllg49xRY4h1DSxLdrIa8aiozPeARJkctn1QJKkAAAAAElFTkSuQmCC\" />");
echo("</a>");
echo("<div class=\"ApplicationMenu\" id=\"Ribbon_" . $this->ID . "_ApplicationMenu\">");
echo("<div class=\"ApplicationMenuHeader\">&nbsp;</div>");
echo("<div class=\"ApplicationMenuItems\">");
foreach ($this->ApplicationMenu->Commands as $item)
{
$this->RenderRibbonCommand($item);
}
echo("</div>");
echo("</div>");
echo("<div class=\"RibbonTabContainer\" id=\"Ribbon_" . $this->ID . "_TabContainer\">");
foreach ($this->Tabs as $tab)
{
$this->RenderRibbonTab($tab);
}
/*
foreach (RibbonTabContext ctx in $this->Contexts)
{
echo("<div class=\"RibbonTabContext\" style=\"");
HSLColor borderColor = new HSLColor(ctx.BackgroundColor);
HSLColor startColor = new HSLColor(borderColor);
startColor.Hue .= 10;
startColor.Saturation -= 54;
startColor.Luminosity .= 10;
HSLColor endColor = new HSLColor(borderColor);
endColor.Saturation -= 54;
endColor.Luminosity .= 20;
string css = "border-color: " . GradientGenerator.GetColorCSS(borderColor) . ";";
css .= GradientGenerator.GenerateCSS(new GradientColorStop(0.0, startColor), new GradientColorStop(1.0, endColor));
echo(css);
if (ctx.Active)
{
echo(" display: block;\"");
}
echo("\">");
echo("<div class=\"Title\">");
echo(ctx.Title);
echo("</div>");
foreach (RibbonTab tab in ctx.Tabs)
{
$this->RenderRibbonTab(tab, writer);
}
echo("</div>");
}
*/
echo("</div>");
echo("<div class=\"RibbonTabContentContainer\" id=\"Ribbon_" . $this->ID . "_TabContentContainer\">");
foreach ($this->Tabs as $tab)
{
echo("<div class=\"RibbonTabContent");
if ($tab->ID === $this->SelectedTab->ID)
{
echo(" Selected");
}
echo("\" data-tab-id=\"" . $tab->ID . "\"");
echo(">");
foreach ($tab->Groups as $tgroup)
{
$this->RenderRibbonTabGroup($tgroup);
}
echo("</div>");
}
echo("</div>");
if ($this->UserName != null)
{
echo("<span class=\"UserName\">" . $this->UserName . "</span>");
}
echo("<a class=\"HelpButton\" id=\"Ribbon_" . $this->ID . "_HelpButton\" data-tooltip-title=\"" . $this->HelpButton->ToolTipTitle . "\" data-tooltip-content=\"" . $this->HelpButton->ToolTipText . "\"");
if ($this->HelpButton->TargetURL != null)
{
echo(" href=\"" . $this->HelpButton->TargetURL . "\"");
if ($this->HelpButton->TargetFrame != null)
{
echo(" target=\"" . $this->HelpButton->TargetFrame . "\"");
}
}
else
{
echo(" href=\"#\"");
}
if ($this->HelpButton->TargetScript != null)
{
echo(" onclick=\"" . $this->HelpButton->TargetScript . "\"");
}
if ($this->HelpButton->Visible)
{
echo(" style=\"display: inline-block\"");
}
echo(">");
echo("<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMDEQIZ+kwBxAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACPklEQVQoz0WST0gUYRjGf7Nqu4kxg2n+Kd0BIwapGNgQpQ5DpzoEe8ujN7vlsUu0l87VTbpkkGDQYQ0KDyojRGypMEjlSJJjbamZ9H2xa6PQvh0G9T0/v+eB53mNta0qhyfC9p+/Cyvl/dzmz39sV39zuq2ZgXOZxVbr+CXEOJQaB2Blt8bLxR25fN7CtU3MdCLQexBEmpmgzOBAp9GYSR+Bld0awbcdudGXJQjBDyGIEtC1wXM0tm0yPr3ENffMcPOJzGPWNivcfxGJikXGfBHvjsjYlIiKRUREIiUyMioyNqUkUiJ3n76V1Y0Kxvsv2wu7+w05YpPCRJLwYBgm30GxBPl+8FzIFzQjeQBFU6ae1NyH/Zxrm/ghEEOk4NEkFCbADzV+SWOmwcpA0Y/wnCzzH9dJLa7+wkxDEIICogjGpkDF4DlQuGUyt6IJggA/UJgmzM4vU39Qr4qTRIWGGFwHntw2mZzTjIwGKBTW0XCk2prq0Hvg2hoVa1AKYoVnJ4Khh1FiCri2hdaai90d1Of7ThFEGs+Foq9QKIiTSdRzBSRGAHnPJggVV/q6SHW1NxqvFxSuYyatxYnYc+DezewhNDJo4/VbvAlXudCTNYy1rSplvSszn6oMeVn80jrFkiIIE8B1LPL9Fp5rMf5qiasDWdpPtiRgyjD4ulOVZ7PLXM914zkWpmkmL6c1QahYLq/j9tp0trQaNZGjXwWgJoTff8h06TPR6gb22Q5ajjXg9Lbj9mSNVF0DNREA/gPgtSGQXugIvQAAAABJRU5ErkJggg==\" alt=\"Help\" />");
echo("</a>");
echo("</div>");
echo("</div>");
echo("<div id=\"Ribbon_" . $this->ID . "_Spacer\" class=\"RibbonSpacer");
if ($this->Collapsed) echo(" Collapsed");
echo("\">");
}
protected function RenderBeginTag()
{
parent::RenderBeginTag();
echo("<div class=\"RibbonContainer\">");
}
protected function RenderEndTag()
{
parent::RenderEndTag();
echo("</div>");
echo("<div class=\"RibbonTooltip\" id=\"Tooltip\"><div class=\"Title\" id=\"Tooltip_Title\"></div><div class=\"Content\" id=\"Tooltip_Content\"></div><div class=\"ContextHelp\" id=\"Tooltip_ContextHelp\"><span class=\"Separator\">&nbsp;</span><div class=\"Content\">Press F1 for more help.</div></div></div>");
}
}
class RibbonTab
{
public $ID;
public $Title;
public $ImageURL;
public $ToolTipTitle;
public $ToolTipText;
public $Groups;
public $Visible;
public function __construct($id, $title = null, $groups = null, $imageURL = null, $tooltipTitle = null, $tooltipText = null, $visible = true)
{
if ($groups == null) $groups = array();
$this->ID = $id;
$this->Title = $title;
$this->Groups = $groups;
$this->ImageURL = $imageURL;
$this->ToolTipTitle = $tooltipTitle;
$this->ToolTipText = $tooltipText;
$this->Visible = $visible;
}
public function GetTabGroupByID($id)
{
foreach ($this->Groups as $group)
{
if ($group->ID == $id) return $group;
}
return null;
}
}
class RibbonTabGroup
{
public $ID;
public $Title;
public $Items;
public $Visible;
public function __construct($id, $title, $items = null)
{
if ($items == null) $items = array();
$this->ID = $id;
$this->Title = $title;
$this->Items = $items;
$this->Visible = true;
}
}
abstract class RibbonCommand
{
public $ID;
public $Enabled;
public function __construct($id)
{
$this->ID = $id;
$this->Enabled = true;
}
}
class RibbonButtonCommand extends RibbonCommand
{
public $Title;
public $ImageURL;
public $TargetURL;
public $TargetScript;
public $TargetFrame;
public $ToolTipTitle;
public $ToolTipText;
public $Selected;
public function __construct($id, $title, $targetURL = null, $targetScript = null, $imageURL = null, $toolTipTitle = null, $toolTipText = null)
{
parent::__construct($id);
$this->Title = $title;
$this->TargetURL = $targetURL;
$this->TargetScript = $targetScript;
$this->ImageURL = $imageURL;
$this->ToolTipTitle = $toolTipTitle;
$this->ToolTipText = $toolTipText;
}
}
class RibbonDropDownCommand extends RibbonButtonCommand
{
public $Items;
public function __construct($id, $title, $targetURL = null, $targetScript = null, $imageURL = null, $toolTipTitle = null, $toolTipText = null, $commands = null)
{
parent::__construct($id, $title, $targetURL, $targetScript, $imageURL, $toolTipTitle, $toolTipText);
if ($commands == null) $commands = array();
$this->Items = $commands;
}
}
abstract class RibbonItem
{
}
class RibbonCommandReferenceItem extends RibbonItem
{
public $TargetID;
public function __construct($targetID)
{
$this->TargetID = $targetID;
}
}
class RibbonSeparatorItem extends RibbonItem
{
}
class RibbonApplicationMenuSettings
{
public $Title;
public $Commands;
public $ToolTipTitle;
public $ToolTipText;
public function __construct()
{
$this->Commands = array();
}
}
class RibbonHelpButtonSettings
{
public $ToolTipTitle;
public $ToolTipText;
public $TargetURL;
public $TargetFrame;
public $TargetScript;
public $Visible;
}
?>

View File

@ -0,0 +1,19 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
/**
* Provides a page section that can hold any WebControl. Content is rendered to the portion of the master page with the same ID as the PlaceholderID.
*
* @author Michael Becker
* @see SectionPlaceholder
*/
class Section extends WebControl
{
public $PlaceholderID;
}
class SectionPlaceholder extends WebControl
{
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
class Sidebar extends WebControl
{
public function __construct()
{
parent::__construct();
$this->TagName = "nav";
$this->ClassList[] = "Sidebar";
}
}
?>

View File

@ -0,0 +1,91 @@
<?php
namespace Phast\WebControls;
use Phast\Orientation;
use Phast\WebStyleSheetRule;
class SplitContainer extends \Phast\WebControl
{
public $Orientation;
public $PrimaryPanel;
public $SecondaryPanel;
public $SplitterPosition;
public $SplitterWidth;
public function __construct($id)
{
parent::__construct($id);
$this->Orientation = Orientation::Vertical;
$this->PrimaryPanel = new SplitContainerPanel($this, "Primary");
$this->SecondaryPanel = new SplitContainerPanel($this, "Secondary");
$this->SplitterWidth = "4px";
$this->TagName = "div";
}
protected function RenderBeginTag()
{
$this->ClassList[] = "SplitContainer";
switch ($this->Orientation)
{
case Orientation::Horizontal:
{
$this->ClassList[] = "Horizontal";
break;
}
case Orientation::Vertical:
{
$this->ClassList[] = "Vertical";
break;
}
}
parent::RenderBeginTag();
}
protected function RenderEndTag()
{
parent::RenderEndTag();
echo("<script type=\"text/javascript\">var " . $this->ID . " = new SplitContainer('" . $this->ID . "');</script>");
}
}
class SplitContainerPanel extends \Phast\WebControl
{
public $ID;
public $ParentContainer;
public $Visible;
public function __construct($parent, $id)
{
$this->ParentContainer = $parent;
$this->ID = $id;
$this->TagName = "div";
$this->Visible = true;
}
protected function RenderBeginTag()
{
$this->ClassList[] = "SplitContainerPanel";
$this->ClassList[] = $this->ID;
$this->ClientID = "SplitContainer_" . $this->ParentContainer->ID . "_" . $this->ID . "\"";
if ($this->ID == "Primary" && $this->ParentContainer->SplitterPosition != null)
{
$this->StyleRules[] = new WebStyleSheetRule("width", $this->ParentContainer->SplitterPosition);
}
parent::RenderBeginTag();
}
protected function RenderEndTag()
{
parent::RenderEndTag();
if ($this->ID == "Primary")
{
echo("<div class=\"Splitter\" id=\"SplitContainer_" . $this->ParentContainer->ID . "_Splitter\"");
if ($this->ParentContainer->SplitterWidth != null)
{
echo (" style=\"width: " . $this->ParentContainer->SplitterWidth . "\"");
}
echo("><span class=\"SplitterGrip\">&nbsp;</span></div>");
}
}
}
?>

View File

@ -0,0 +1,230 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\HTMLControl;
use Phast\HTMLControls\Anchor;
use Phast\Enumeration;
/**
* Enumeration specifying the position of tabs on a tab container.
* @author Michael Becker
*/
abstract class TabContainerTabPosition extends Enumeration
{
/**
* The tabs are aligned at the top of the tab container, before the tab page content.
* @var TabContainerTabPosition
*/
const Top = 1;
/**
* The tabs are aligned at the bottom of the tab container, after the tab page content.
* @var TabContainerTabPosition
*/
const Bottom = 2;
/**
* The tabs are aligned to the left of the tab container, before the tab page content.
* @var TabContainerTabPosition
*/
const Left = 3;
/**
* The tabs are aligned to the right of the tab container, after the tab page content.
* @var TabContainerTabPosition
*/
const Right = 4;
}
class TabPage
{
public $ID;
public $Title;
public $Controls;
public $Visible;
public $ImageURL;
public $TargetURL;
public $TargetScript;
public function GetControlByID($id)
{
foreach ($this->Controls as $ctl)
{
if ($ctl->ID == $id) return $ctl;
$ctll = $ctl->GetControlByID($id);
if ($ctll != null) return $ctll;
}
return null;
}
public function __construct($id = null, $title = null, $imageURL = null, $targetURL = null, $targetScript = null, $visible = true)
{
$this->ID = $id;
$this->Title = $title;
$this->ImageURL = $imageURL;
$this->TargetURL = $targetURL;
$this->TargetScript = $targetScript;
$this->Visible = $visible;
}
}
class TabContainer extends WebControl
{
public $SelectedTab;
public $SelectedTabID;
public $TabPages;
/**
* Determines the position of the tabs relative to the tab pages.
* @var TabContainerTabPosition
*/
public $TabPosition;
public $OnClientTabChanged;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ParseChildElements = true;
$this->TabPosition = TabContainerTabPosition::Top;
}
public function GetTabByID($id)
{
foreach ($this->TabPages as $tabPage)
{
if ($tabPage->ID == $id) return $tabPage;
}
return null;
}
protected function OnInitialize()
{
$oldtab = $this->SelectedTab;
$this->SelectedTab = $this->GetTabByID($this->GetClientProperty("SelectedTabID"));
if ($this->SelectedTab == null) $this->SelectedTab = $oldtab;
}
protected function RenderBeginTag()
{
if ($this->OnClientTabChanged != null)
{
$this->Attributes[] = new WebControlAttribute("data-onclienttabchanged", $this->OnClientTabChanged);
}
$this->ClassList[] = "TabContainer";
if (is_string($this->TabPosition))
{
switch (strtolower($this->TabPosition))
{
case "left":
{
$this->ClassList[] = "TabPositionLeft";
break;
}
case "top":
{
$this->ClassList[] = "TabPositionTop";
break;
}
case "right":
{
$this->ClassList[] = "TabPositionRight";
break;
}
case "bottom":
{
$this->ClassList[] = "TabPositionBottom";
break;
}
}
}
else
{
switch ($this->TabPosition)
{
case TabContainerTabPosition::Left:
{
$this->ClassList[] = "TabPositionLeft";
break;
}
case TabContainerTabPosition::Top:
{
$this->ClassList[] = "TabPositionTop";
break;
}
case TabContainerTabPosition::Right:
{
$this->ClassList[] = "TabPositionRight";
break;
}
case TabContainerTabPosition::Bottom:
{
$this->ClassList[] = "TabPositionBottom";
break;
}
}
}
$this->Controls = array();
$ulTabs = new HTMLControl("ul");
$ulTabs->ClassList[] = "Tabs";
$j = 0;
foreach ($this->TabPages as $tabPage)
{
$liTab = new HTMLControl("li");
if ((is_bool($tabPage->Visible) && $tabPage->Visible) || (is_string($tabPage->Visible) && $tabPage->Visible != "false"))
{
$liTab->ClassList[] = "Visible";
}
if (($this->SelectedTabID != null && $tabPage->ID == $this->SelectedTabID) || ($this->SelectedTab != null && ($tabPage->ID == $this->SelectedTab->ID)))
{
$liTab->ClassList[] = "Selected";
}
$aTab = new Anchor();
$aTab->Attributes[] = new WebControlAttribute("data-id", $tabPage->ID);
$aTab->TargetURL = $tabPage->TargetURL;
$aTab->InnerHTML = $tabPage->Title;
$liTab->Controls[] = $aTab;
$ulTabs->Controls[] = $liTab;
$j++;
}
$this->Controls[] = $ulTabs;
$divTabPages = new HTMLControl("div");
$divTabPages->ClassList[] = "TabPages";
foreach ($this->TabPages as $tabPage)
{
$divTabPage = new HTMLControl("div");
$divTabPage->ClassList[] = "TabPage";
if (($this->SelectedTabID != null && $tabPage->ID == $this->SelectedTabID) || ($this->SelectedTab != null && ($tabPage->ID == $this->SelectedTab->ID)))
{
$divTabPage->ClassList[] = "Selected";
}
if (isset($tabPage->Content))
{
$divTabPage->Content = $tabPage->Content;
}
foreach ($tabPage->Controls as $ctl)
{
$divTabPage->Controls[] = $ctl;
}
$divTabPages->Controls[] = $divTabPage;
}
$this->Controls[] = $divTabPages;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,87 @@
<?php
namespace Phast\WebControls;
use Phast\System;
use Phast\WebControl;
class TabStripTab
{
public $ID;
public $Title;
public $NavigateURL;
public $OnClientClick;
public $Selected;
public function __construct($id, $title, $navigateURL = null, $onClientClick = null, $selected = false)
{
$this->ID = $id;
$this->Title = $title;
$this->NavigateURL = $navigateURL;
$this->OnClientClick = $onClientClick;
$this->Selected = $selected;
}
}
class TabStrip extends WebControl
{
public $TabPosition;
protected function RenderContent()
{
?>
<div class="TabStrip<?php
switch ($this->TabPosition)
{
case TabContainerTabPosition::Top:
{
echo(" Top");
break;
}
case TabContainerTabPosition::Bottom:
{
echo(" Bottom");
break;
}
case TabContainerTabPosition::Left:
{
echo(" Left");
break;
}
case TabContainerTabPosition::Right:
{
echo(" Right");
break;
}
}?>" id="TabStrip_<?php echo($this->ID); ?>">
<div class="Tabs" id="TabStrip_<?php echo($this->ID); ?>_Tabs">
<?php
foreach ($this->Tabs as $tab)
{
echo("<a id=\"TabStrip_" . $this->ID . "_Tabs_" . $tab->ID . "_Tab\" class=\"Tab");
if ($tab->Selected)
{
echo (" Selected");
}
echo("\"");
if ($tab->OnClientClick != null)
{
echo(" onclick=\"" . $tab->OnClientClick . "\"");
}
if ($tab->NavigateURL != null)
{
echo(" href=\"" . System::ExpandRelativePath($tab->NavigateURL) . "\"");
}
else
{
echo(" href=\"#\"");
}
echo(">");
echo($tab->Title);
echo("</a>");
}
?>
</div>
</div>
<?php
}
}
?>

View File

@ -0,0 +1,206 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\WebControlAttribute;
use Phast\WebScript;
use Phast\WebControls\ListView;
use Phast\WebControls\ListViewColumn;
use Phast\WebControls\ListViewItem;
use Phast\WebControls\ListViewItemColumn;
use Phast\System;
use Phast\HTMLControl;
use Phast\HTMLControls\Anchor;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
class TextBoxItem
{
public $Title;
public $Value;
public $Selected;
public function __construct($title = null, $value = null, $selected = false)
{
$this->Title = $title;
$this->Value = $value;
$this->Selected = $selected;
}
}
class TextBox extends WebControl
{
public $Name;
public $PlaceholderText;
/**
* The items available for selection from this TextBox.
* @var TextBoxItem[]
*/
public $Items;
public $InnerStyle;
public $MultiSelect;
public $RequireSelectionFromChoices;
public $EnableMultipleSelection;
public $ClearOnFocus;
public $OpenWhenFocused;
public $ShowColumnHeaders;
public $SuggestionURL;
public $Text;
public function __construct()
{
parent::__construct();
$this->ShowColumnHeaders = true;
$this->Items = array();
$this->TagName = "div";
$this->ClassList[] = "TextBox";
$this->OpenWhenFocused = true;
$this->MultiSelect = false;
}
protected function OnInitialize()
{
$parent = $this->FindParentPage();
if ($parent != null) $parent->Scripts[] = new WebScript("$(PhastStaticPath)/Scripts/Controls/TextBox.js");
}
protected function RenderBeginTag()
{
$this->Controls = array();
if ($this->RequireSelectionFromChoices)
{
$this->ClassList[] = "RequireSelection";
}
if ($this->ClearOnFocus)
{
$this->ClassList[] = "ClearOnFocus";
}
if ($this->MultiSelect)
{
$this->ClassList[] = "MultiSelect";
}
if ($this->SuggestionURL != null)
{
$this->Attributes[] = new WebControlAttribute("data-suggestion-url", System::ExpandRelativePath($this->SuggestionURL));
}
if ($this->OpenWhenFocused)
{
$this->Attributes[] = new WebControlAttribute("data-auto-open", "true");
}
$divTextboxContent = new HTMLControl("div");
$divTextboxContent->ClassList[] = "TextboxContent";
$spanTextboxSelectedItems = new HTMLControl("span");
$spanTextboxSelectedItems->ClassList[] = "TextboxSelectedItems";
$i = 0;
foreach ($this->Items as $item)
{
if (!$item->Selected) continue;
$spanSelectedItem = new HTMLControl("span");
$spanSelectedItem->ClassList[] = "SelectedItem";
$spanText = new HTMLControl("span");
$spanText->ClassList[] = "Text";
$spanText->InnerHTML = $item->Title;
$spanSelectedItem->Controls[] = $spanText;
$aCloseButton = new Anchor();
$aCloseButton->ClassList[] = "CloseButton";
$spanSelectedItem->Controls[] = $aCloseButton;
$spanTextboxSelectedItems->Controls[] = $spanSelectedItem;
$i++;
}
$divTextboxContent->Controls[] = $spanTextboxSelectedItems;
$inputText = new Input();
$inputText->ID = $this->ID . "_InputElement";
$inputText->Type = InputType::Text;
$inputText->Attributes[] = new WebControlAttribute("autocomplete", "off");
$inputText->Name = $this->Name;
$inputText->PlaceholderText = $this->PlaceholderText;
$inputText->Value = $this->Text;
$inputText->Width = $this->Width;
if ($this->InnerStyle != null)
{
$inputText->Attributes[] = new WebControlAttribute("style", $this->InnerStyle);
}
$divTextboxContent->Controls[] = $inputText;
$this->Controls[] = $divTextboxContent;
$divSuggestionList = new HTMLControl("div");
$divSuggestionList->ClassList[] = "SuggestionList";
$ulSuggestionList = new HTMLControl("ul");
$ulSuggestionList->ClassList[] = "Menu";
$ulSuggestionList->ClassList[] = "Popup";
foreach ($this->Items as $item)
{
$li = new HTMLControl("li");
$li->ClassList[] = "MenuItem";
$li->ClassList[] = "Command";
$li->ClassList[] = "Visible";
$aSuggestionListItem = new Anchor();
$iCheckmark = new HTMLControl("i");
$iCheckmark->ClassList[] = "fa";
$iCheckmark->ClassList[] = "fa-check";
$iCheckmark->ClassList[] = "Checkmark";
$aSuggestionListItem->Controls[] = $iCheckmark;
$spanText = new HTMLControl("span");
$spanText->Content = $item->Title;
$aSuggestionListItem->Controls[] = $spanText;
$aSuggestionListItem->Attributes[] = new WebControlAttribute("data-value", $item->Value);
$li->Controls[] = $aSuggestionListItem;
$ulSuggestionList->Controls[] = $li;
}
$divSuggestionList->Controls[] = $ulSuggestionList;
$divSuggestionListThrobber = new HTMLControl("div");
$divSuggestionListThrobber->ClassList[] = "Throbber";
$divSuggestionList->Controls[] = $divSuggestionListThrobber;
$this->Controls[] = $divSuggestionList;
$selectSuggestionList = new HTMLControl("select");
$selectSuggestionList->ClassList[] = "SuggestionList";
$selectSuggestionList->Attributes[] = new WebControlAttribute("multiple", "multiple");
foreach ($this->Items as $item)
{
$option = new HTMLControl("option");
$option->Attributes[] = new WebControlAttribute("value", $item->Value);
$option->Content = $item->Title;
if ($item->Selected)
{
$option->Attributes[] = new WebControlAttribute("selected", "selected");
}
$selectSuggestionList->Controls[] = $option;
}
$this->Controls[] = $selectSuggestionList;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,56 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\HTMLControl;
class Timeline extends WebControl
{
public $Posts;
public function __construct()
{
$this->ParseChildElements = false;
$this->ClassList[] = "Timeline";
$this->TagName = "div";
}
protected function RenderBeginTag()
{
$this->Controls = array();
foreach ($this->Posts as $post)
{
$divPost = new HTMLControl("div");
$divPost->ClassList[] = "TimelinePost";
$divPostHeader = new HTMLControl("div");
$divPostHeader->ClassList[] = "Header";
$divPost->Controls[] = $divPostHeader;
$divPostContent = new HTMLControl("div");
$divPostContent->ClassList[] = "Content";
$divPost->Controls[] = $divPostContent;
$divPostFooter = new HTMLControl("div");
$divPostFooter->ClassList[] = "Footer";
$divPost->Controls[] = $divPostFooter;
$this->Controls[] = $divPost;
}
parent::RenderBeginTag();
}
}
class TimelinePost
{
public $ID;
public $CreationUserName;
public $CreationUserImageURL;
public $Controls;
public $ViewCount;
public function __construct()
{
$this->ParseChildElements = true;
}
}
?>

View File

@ -0,0 +1,75 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\HTMLControl;
use Phast\Enumeration;
class ToggleSwitchOrientation extends Enumeration
{
/**
* The toggle switch is oriented horizontally.
* @var ToggleSwitchOrientation 1
*/
const Horizontal = 1;
/**
* The toggle switch is oriented vertically.
* @var ToggleSwitchOrientation 2
*/
const Vertical = 2;
}
class ToggleSwitch extends WebControl
{
/**
* The orientation of this ToggleSwitch.
* @var ToggleSwitchOrientation
*/
public $Orientation;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "ToggleSwitch";
}
protected function RenderBeginTag()
{
switch (mvarOrientation)
{
case ToggleSwitchOrientation::Horizontal:
{
$this->ClassList[] = "Horizontal";
break;
}
case ToggleSwitchOrientation::Vertical:
{
$this->ClassList[] = "Vertical";
break;
}
}
$divToggleSwitchInner = new HTMLControl("div");
$divToggleSwitchInner->ClassList[] = "ToggleSwitchInner";
$divToggleOn = new HTMLControl("div");
$divToggleOn->ClassList[] = "ToggleOn";
$divToggleOn->InnerHTML = "On";
$divToggleSwitchInner->Controls[] = $divToggleOn;
$divToggleThumb = new HTMLControl("div");
$divToggleThumb->ClassList[] = "ToggleThumb";
$divToggleSwitchInner->Controls[] = $divToggleThumb;
$divToggleOff = new HTMLControl("div");
$divToggleOff->ClassList[] = "ToggleOff";
$divToggleOff->InnerHTML = "Off";
$divToggleSwitchInner->Controls[] = $divToggleOff;
$this->Controls[] = $divToggleSwitchInner;
parent::RenderBeginTag();
}
}
?>

View File

@ -0,0 +1,37 @@
<?php
namespace Phast\WebControls;
use System;
use Phast\WebControl;
class ToolTip extends WebControl
{
public $Title;
public $Content;
public $Width;
public function __construct($id, $title, $content)
{
parent::__construct($id);
$this->Title = $title;
$this->Content = $content;
}
protected function BeforeContent()
{
?>
<div class="ToolTip" id="ToolTip_<?php echo($this->ID); ?>"<?php if ($this->Width != null) { echo (" style=\"width: " . (is_numeric($this->Width) ? ($this->Width . "px") : $this->Width) . ";\""); } ?>>
<div class="Title" id="ToolTip_<?php echo($this->ID); ?>_Title"><?php echo($this->Title); ?></div>
<div class="Content" id="ToolTip_<?php echo($this->ID); ?>_Content"><?php echo($this->Content); ?></div>
</div>
<div class="ToolTipActivator" id="ToolTip_<?php echo($this->ID); ?>_Activator">
<?php
}
protected function AfterContent()
{
?>
</div>
<script type="text/javascript">var <?php echo($this->ID); ?> = new ToolTip("<?php echo($this->ID); ?>");</script>
<?php
}
}
?>

View File

@ -0,0 +1,181 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\HTMLControl;
use Phast\Enumeration;
use Phast\WebStyleSheetRule;
use Phast\WebControlAttribute;
abstract class TrackBarOrientation extends Enumeration
{
const Horizontal = 1;
const Vertical = 2;
}
class TrackBar extends WebControl
{
/**
* The orientation of this TrackBar.
* @var TrackBarOrientation
*/
public $Orientation;
/**
* The minimum value of this TrackBar.
* @var int
*/
public $MinimumValue;
/**
* The maximum value of this TrackBar.
* @var int
*/
public $MaximumValue;
/**
* True if the value should be shown in the trackbar thumb; false otherwise.
* @var boolean
*/
public $ShowValue;
/**
* The current value of this TrackBar.
* @var int
*/
public $CurrentValue;
/**
* The size of the TrackBar (width when horizontal, height when vertical).
* @var int
*/
public $Size;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "TrackBar";
$this->ShowValue = false;
$this->Size = null;
$this->Orientation = TrackBarOrientation::Horizontal;
}
protected function OnInitialize()
{
$this->Controls = array();
$this->Attributes[] = new WebControlAttribute("data-maximum-value", $this->MaximumValue);
$this->Attributes[] = new WebControlAttribute("data-minimum-value", $this->MinimumValue);
$this->Attributes[] = new WebControlAttribute("data-current-value", $this->CurrentValue);
if ($this->ShowValue)
{
$this->ClassName[] = "ShowValue";
}
if (is_string($this->Orientation))
{
switch (strtolower($this->Orientation))
{
case "horizontal":
{
$this->Orientation = TrackBarOrientation::Horizontal;
break;
}
case "vertical":
{
$this->Orientation = TrackBarOrientation::Vertical;
break;
}
}
}
switch ($this->Orientation)
{
case TrackBarOrientation::Horizontal:
{
$this->ClassList[] = "Horizontal";
break;
}
case TrackBarOrientation::Vertical:
{
$this->ClassList[] = "Vertical";
break;
}
}
if ($this->Size != null)
{
switch ($this->Orientation)
{
case TrackBarOrientation::Horizontal:
{
$this->StyleRules[] = new WebStyleSheetRule("width", $this->Size);
break;
}
case TrackBarOrientation::Vertical:
{
$this->StyleRules[] = new WebStyleSheetRule("height", $this->Size);
break;
}
}
}
$leftPos = (($this->CurrentValue - $this->MinimumValue) / ($this->MaximumValue - $this->MinimumValue)) * 100;
if ($this->Orientation == TrackBarOrientation::Vertical)
{
$leftPos = 100 - $leftPos;
}
$divTrack = new HTMLControl("div");
$divTrack->ClassList[] = "Track";
$divQuantity = new HTMLControl("div");
$divQuantity->ClassList[] = "Quantity";
switch ($this->Orientation)
{
case TrackBarOrientation::Horizontal:
{
$divQuantity->StyleRules[] = new WebStyleSheetRule("width", $leftPos . "%");
break;
}
case TrackBarOrientation::Vertical:
{
$divQuantity->StyleRules[] = new WebStyleSheetRule("top", $leftPos . "%");
break;
}
}
$divTrack->Controls[] = $divQuantity;
$divThumb = new HTMLControl("div");
$divThumb->ClassList[] = "Thumb";
switch ($this->Orientation)
{
case TrackBarOrientation::Horizontal:
{
$divThumb->StyleRules[] = new WebStyleSheetRule("left", $leftPos . "%");
break;
}
case TrackBarOrientation::Vertical:
{
$divThumb->StyleRules[] = new WebStyleSheetRule("top", $leftPos . "%");
break;
}
}
$spanThumbText = new HTMLControl("span");
$spanThumbText->ClassList[] = "Text";
$spanThumbText->InnerHTML = $this->CurrentValue;
$divThumb->Controls[] = $spanThumbText;
$divTrack->Controls[] = $divThumb;
$this->Controls[] = $divTrack;
parent::OnInitialize();
}
}
?>

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