1
0

Merge commit 'upstream/master'

This commit is contained in:
Romain LE DISEZ 2009-09-03 22:28:14 +02:00
commit b5bdbbb86f
381 changed files with 26507 additions and 156 deletions

View File

@ -0,0 +1,55 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Admin_Configure_Controller extends Controller
{
/**
* the index page of the user homes admin
*/
public function index()
{
$form = basket::get_configure_form();
if (request::method() == "post") {
// @todo move the "save" part of this into a separate controller function
access::verify_csrf();
if ($form->validate()) {
basket::extractForm($form);
message::success(t("Basket Module Configured!"));
//url::redirect("admin/recaptcha");
}
}
else
{
basket::populateForm($form);
}
$view = new Admin_View("admin.html");
$view->content = new View("admin_configure.html");
$view->content->form = $form;
//$view->content->products = ORM::factory("product")->orderby("name")->find_all();
print $view;
}
}

View File

@ -0,0 +1,151 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Admin_Product_Lines_Controller extends Controller
{
/**
* the index page of the user homes admin
*/
public function index()
{
$view = new Admin_View("admin.html");
$view->content = new View("admin_product_lines.html");
$view->content->products = ORM::factory("product")->orderby("name")->find_all();
print $view;
}
public function add_product_form() {
print product::get_add_form_admin();
}
public function add_product() {
access::verify_csrf();
$form = product::get_add_form_admin();
$valid = $form->validate();
$name = $form->add_product->inputs["name"]->value;
$product = ORM::factory("product")->where("name", $name)->find();
if ($product->loaded) {
$form->add_product->inputs["name"]->add_error("in_use", 1);
$valid = false;
}
if ($valid) {
$product = product::create(
$name, $form->add_product->cost->value, $form->add_product->description->value);
$product->save();
message::success(t("Created product %product_name", array(
"product_name" => html::clean($product->name))));
print json_encode(array("result" => "success"));
} else {
print json_encode(array("result" => "error",
"form" => $form->__toString()));
}
}
public function delete_product_form($id) {
$product = ORM::factory("product", $id);
if (!$product->loaded) {
kohana::show_404();
}
print product::get_delete_form_admin($product);
}
public function delete_product($id) {
access::verify_csrf();
if ($id == user::active()->id || $id == user::guest()->id) {
access::forbidden();
}
$product = ORM::factory("product", $id);
if (!$product->loaded) {
kohana::show_404();
}
$form = user::get_delete_form_admin($product);
if($form->validate()) {
$name = $product->name;
$product->delete();
} else {
print json_encode(array("result" => "error",
"form" => $form->__toString()));
}
$message = t("Deleted user %product_name", array("product_name" => html::clean($name)));
log::success("user", $message);
message::success($message);
print json_encode(array("result" => "success"));
}
public function edit_product($id) {
access::verify_csrf();
$product = ORM::factory("product", $id);
if (!$product->loaded) {
kohana::show_404();
}
$form = product::get_edit_form_admin($product);
$valid = $form->validate();
if ($valid) {
$new_name = $form->edit_product->inputs["name"]->value;
if ($new_name != $product->name &&
ORM::factory("product")
->where("name", $new_name)
->where("id !=", $product->id)
->find()
->loaded) {
$form->edit_product->inputs["name"]->add_error("in_use", 1);
$valid = false;
} else {
$product->name = $new_name;
}
}
if ($valid) {
$product->cost = $form->edit_product->cost->value;
$product->description = $form->edit_product->description->value;
$product->save();
message::success(t("Changed product %product_name",
array("product_name" => html::clean($product->name))));
print json_encode(array("result" => "success"));
} else {
print json_encode(array("result" => "error",
"form" => $form->__toString()));
}
}
public function edit_product_form($id) {
$product = ORM::factory("product", $id);
if (!$product->loaded) {
kohana::show_404();
}
$form = product::get_edit_form_admin($product);
print $form;
}
}

View File

@ -0,0 +1,222 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Basket_Controller extends Controller {
public function view_basket() {
$template = new Theme_View("page.html", "basket");
$view = new View("view_basket.html");
$view->basket = Session_Basket::get();
$template->content = $view;
print $template;
}
private function getCheckoutForm(){
$form = new Forge("basket/confirm", "", "post", array("id" => "checkout", "name" =>"checkout"));
$group = $form->group("contact")->label(t("Contact Details"));
$group->input("fullname")->label(t("Name"))->id("fullname");
$group->input("house")->label(t("House Number / Name"))->id("house");
$group->input("street")->label(t("Street"))->id("street");
$group->input("suburb")->label(t("Suburb"))->id("suburb");
$group->input("town")->label(t("Town or City"))->id("town");
$group->input("postcode")->label(t("Postcode"))->id("postcode");
$group->input("email")->label(t("E-Mail Address"))->id("email");
$group->input("phone")->label(t("Telephone Number"))->id("phone");
return $form;
}
public function checkout () {
$template = new Theme_View("page.html", "basket");
$view = new View("checkout.html");
$basket = Session_Basket::get();
$form = self::getCheckoutForm();
$form->contact->fullname->value($basket->name);
$form->contact->house->value($basket->house);
$form->contact->street->value($basket->street);
$form->contact->suburb->value($basket->suburb);
$form->contact->town->value($basket->town);
$form->contact->postcode->value($basket->postcode);
$form->contact->email->value($basket->email);
$form->contact->phone->value($basket->phone);
$view->form = $form;
$template->content = $view;
print $template;
}
public function confirm () {
access::verify_csrf();
$form = $this->getCheckoutForm();
$valid = $form->validate();
if ($valid){
$basket = Session_Basket::get();
$basket->name = $form->contact->fullname->value;
$basket->house = $form->contact->house->value;
$basket->street = $form->contact->street->value;
$basket->suburb = $form->contact->suburb->value;
$basket->town = $form->contact->town->value;
$basket->postcode = $form->contact->postcode->value;
$basket->email = $form->contact->email->value;
$basket->phone = $form->contact->phone->value;
$template = new Theme_View("page.html", "basket");
$form = new Forge("basket/complete", "", "post", array("id" => "confirm", "name" =>"confirm"));
$view = new View("confirm_order.html");
$view->basket = $basket;
$template->content = $view;
$view->form = $form;
print $template;
}
else
{
die("Invalid confirmation!");
}
}
public function complete () {
access::verify_csrf();
$basket = Session_Basket::get();
//$admin_address = basket::getEmailAddress();
$admin_email = "Order for :
".$basket->name."
".$basket->house."
".$basket->street."
".$basket->suburb."
".$basket->town."
".$basket->postcode."
".$basket->email."
".$basket->phone."
Placed at ".date("d F Y - H:i" ,time())."
Total Owed ".$basket->cost()." in ".basket::getCurrency()."
Items Ordered:
";
// create the order items
foreach ($basket->contents as $basket_item){
$item = $basket_item->getItem();
$prod = ORM::factory("product", $basket_item->product);
$admin_email = $admin_email."
".$item->title." - ".$item->url()."
".$prod->name." - ".$prod->description."
".$basket_item->quantity." @ ".$prod->cost."
";
}
$from = "From: ".basket::getEmailAddress();
mail(basket::getEmailAddress(), "Order from ".$basket->name, $admin_email, $from);
$basket->clear();
$template = new Theme_View("page.html", "basket");
$view = new View("order_complete.html");
$template->content = $view;
print $template;
}
private function getAddToBasketForm(){
$form = new Forge("basket/add_to_basket", "", "post", array("id" => "gAddToBasketForm"));
$group = $form->group("add_to_basket")->label(t("Add To Basket"));
$group->hidden("id");
$group->dropdown("product")
->label(t("Product"))
->options(product::getProductArray());
$group->input("quantity")->label(t("Quantity"))->id("gQuantity");
$group->submit("")->value(t("Add"));
//$group->submit("proceedToCheckout")->value(t("Proceed To Checkout"));
return $form;
}
public function add_to_basket(){
access::verify_csrf();
$form = self::getAddToBasketForm();
$valid = $form->validate();
if ($valid){
$basket = Session_Basket::getOrCreate();
$basket->add(
$form->add_to_basket->id->value,
$form->add_to_basket->product->value,
$form->add_to_basket->quantity->value);
print json_encode(array("result" => "success"));
}
else
{
log_error("invalid form!");
}
}
public function add_to_basket_ajax($id) {
$view = new View("add_to_basket_ajax.html");
// get the item to add
$item = ORM::factory("item", $id);
if (!$item->loaded)
{
//TODO
die("Not loaded id");
}
// get the basket to add to
$form = self::getAddToBasketForm();
$form->add_to_basket->id->value($id);
$form->add_to_basket->quantity->value(1);
$view->form = $form;
$view->item = $item;
print $view;
}
public function remove_item($key) {
$basket = Session_Basket::getOrCreate();
$basket->remove($key);
url::redirect("basket/view_basket");
}
}

View File

@ -0,0 +1,5 @@
#basket {float:right;}
#add_to_basket {float:right}
#basketForm {max-width:200px}
#basketThumb {float:left; padding:10px 10px 0 0;}
#basketThumb img{max-width:100px;}

View File

@ -0,0 +1,156 @@
<?php
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class basket_Core {
static $currencies = array(
"AUD" => "Australian Dollars",
"CAD" => "Canadian Dollars",
"EUR" => "Euros",
"GBP" => "Pounds Sterling",
"JPY" => "Yen",
"USD" => "U.S. Dollars",
"NZD" => "New Zealand Dollar",
"CHF" => "Swiss Franc",
"HKD" => "Hong Kong Dollar",
"SGD" => "Singapore Dollar",
"SEK" => "Swedish Krona",
"DKK" => "Danish Krone",
"PLN" => "Polish Zloty",
"NOK" => "Norwegian Krone",
"HUF" => "Hungarian Forint",
"CZK" => "Czech Koruna",
"ILS" => "Israeli Shekel",
"MXN" => "Mexican Peso");
static $format= array(
"AUD" => "&#36;",
"CAD" => "&#36;",
"EUR" => "&#8364;",
"GBP" => "&#163;",
"JPY" => "&#165;",
"USD" => "&#36;",
"NZD" => "&#36;",
"CHF" => "",
"HKD" => "&#36;",
"SGD" => "&#36;",
"SEK" => "",
"DKK" => "",
"PLN" => "",
"NOK" => "",
"HUF" => "",
"CZK" => "",
"ILS" => "",
"MXN" => "");
static function get_configure_form() {
$form = new Forge("admin/configure", "", "post", array("id" => "gConfigureForm"));
$group = $form->group("configure")->label(t("Configure Basket"));
$group->input("email")->label(t("Order Email Address"))->id("gOrderEmailAddress");
$group->checkbox("paypal")->label(t("Use Paypal"))->id("gPaypal");
$group->input("paypal_account")->label(t("Paypal Account"))->id("gPaypalAddress");
$group->dropdown("currency")
->label(t("Currency"))
->options(self::$currencies);
$group->submit("")->value(t("Save"));
return $form;
}
static function populateForm($form){
$form->configure->email->value(basket::getEmailAddress());
$form->configure->paypal->checked(basket::isPaypal());
$form->configure->paypal_account->value(basket::getPaypalAccount());
$form->configure->currency->selected(basket::getCurrency());
}
static function extractForm($form){
$email = $form->configure->email->value;
$isPaypal = $form->configure->paypal->value;
$paypal_account = $form->configure->paypal_account->value;
$currency = $form->configure->currency->selected;
basket::setEmailAddress($email);
basket::setPaypal($isPaypal);
basket::setPaypalAccount($paypal_account);
basket::setCurrency($currency);
}
static function getEmailAddress(){
return module::get_var("basket","email");
}
static function isPaypal(){
return module::get_var("basket","paypal");
}
static function getPaypalAccount(){
return module::get_var("basket","paypal_account");
}
static function getCurrency(){
$cur = module::get_var("basket","currency");
if (!isset($cur))
{
$cur = "USD";
}
return $cur;
}
static function formatMoney($money){
return self::$format[self::getCurrency()].number_format($money);
}
static function setEmailAddress($email){
module::set_var("basket","email",$email);
}
static function setPaypal($paypal){
module::set_var("basket","paypal",$paypal);
}
static function setPaypalAccount($paypal_account){
module::set_var("basket","paypal_account",$paypal_account);
}
static function setCurrency($currency){
module::set_var("basket","currency",$currency);
}
static function generatePaypalForm($session_basket){
$form = "
<form action=\"https://www.paypal.com/cgi-bin/webscr\" method=\"post\" name=\"paypal_form\">
<input type=\"hidden\" name=\"cmd\" value=\"_cart\"/>
<input type=\"hidden\" name=\"upload\" value=\"1\"/>
<input type=\"hidden\" name=\"currency_code\" value=\"".self::getCurrency()."\">
<input type=\"hidden\" name=\"business\" value=\"".self::getPaypalAccount()."\"/>";
$id = 1;
foreach ($session_basket->contents as $key => $basket_item){
$form = $form."
<input type=\"hidden\" name=\"item_name_$id\" value=\"".$basket_item->getCode()."\"/>
<input type=\"hidden\" name=\"amount_$id\" value=\"$basket_item->cost_per\"/>
<input type=\"hidden\" name=\"quantity_$id\" value=\"$basket_item->quantity\"/>";
$id++;
}
$form = $form."</form>";
return $form;
}
}

View File

@ -0,0 +1,43 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class basket_event_Core{
/**
* adds the shopping basket administration controls to the admin menu
*/
static function admin_menu($menu, $theme){
$menu->add_after("users_groups",
$basket_menu = Menu::factory("submenu")
->id("basket_menu")
->label(t("Basket")));
$basket_menu->append(
Menu::factory("link")
->id("configure")
->label(t("Configure"))
->url(url::site("admin/configure")));
$basket_menu->append(
Menu::factory("link")
->id("product_line")
->label(t("Product Lines"))
->url(url::site("admin/product_lines")));
}
}

View File

@ -0,0 +1,50 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class basket_installer
{
static function install(){
module::set_version("basket", 1);
}
static function activate() {
$db = Database::instance();
$db->query("CREATE TABLE IF NOT EXISTS {products} (
`id` int(9) NOT NULL auto_increment,
`name` TEXT NOT NULL,
`cost` INTEGER(9) default 0,
`description` varchar(1024),
PRIMARY KEY (`id`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;");
product::create("4x6",5,"4\"x6\" print");
product::create("8x10",25,"8\"x10\" print");
product::create("8x12",30,"8\"x12\" print");
}
static function deactivate(){
$db = Database::instance();
$db->query("DROP TABLE IF EXISTS {products}");
}
}

View File

@ -0,0 +1,46 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class basket_theme_Core {
static function head($theme) {
$theme->css("basket.css");
}
static function header_top($theme) {
$view = new View("basket.html");
$view->basket = Session_Basket::get();
return $view->render();
}
static function admin_head($theme) {
if (strpos(Router::$current_uri, "admin/product_lines") !== false) {
$theme->script("gallery.panel.js");
}
}
static function photo_top($theme)
{
$view = new View("add_to_basket.html");
$view->item = $theme->item();
return $view->render();
}
}

View File

@ -0,0 +1,91 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class product_Core {
static function get_add_form_admin() {
$form = new Forge("admin/product_lines/add_product", "", "post", array("id" => "gAddProductForm"));
$group = $form->group("add_product")->label(t("Add Product"));
$group->input("name")->label(t("Name"))->id("gProductName")
->error_messages("in_use", t("There is already a product with that name"));
$group->input("cost")->label(t("Cost"))->id("gCost");
$group->input("description")->label(t("Description"))->id("gDescription");
$group->submit("")->value(t("Add Product"));
$product = ORM::factory("product");
$form->add_rules_from($product);
return $form;
}
static function get_edit_form_admin($product) {
$form = new Forge("admin/product_lines/edit_product/$product->id", "", "post",
array("id" => "gEditProductForm"));
$group = $form->group("edit_product")->label(t("Edit Product"));
$group->input("name")->label(t("Name"))->id("gProductName")->value($product->name);
$group->inputs["name"]->error_messages(
"in_use", t("There is already a product with that name"));
$group->input("cost")->label(t("Cost"))->id("gCost")->value($product->cost);
$group->input("description")->label(t("Description"))->id("gDescription")->
value($product->description);
$group->submit("")->value(t("Modify Product"));
$form->add_rules_from($product);
return $form;
}
static function get_delete_form_admin($product) {
$form = new Forge("admin/product_lines/delete_product/$product->id", "", "post",
array("id" => "gDeleteProductForm"));
$group = $form->group("delete_product")->label(
t("Are you sure you want to delete product %name?", array("name" => $product->name)));
$group->submit("")->value(t("Delete product %name", array("name" => $product->name)));
return $form;
}
/**
* Create a new product
*
* @param string $name
* @param string $full_name
* @param string $password
* @return User_Model
*/
static function create($name, $cost, $description) {
$product = ORM::factory("product")->where("name", $name)->find();
if ($product->loaded) {
throw new Exception("@todo USER_ALREADY_EXISTS $name");
}
$product->name = $name;
$product->cost = $cost;
$product->description = $description;
$product->save();
return $product;
}
static function getProductArray(){
$products = ORM::factory("product")->find_all();
foreach ($products as $product){
$producta[$product->id] = $product->description." (".basket::formatMoney($product->cost).")";
}
return $producta;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1,152 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class basket_item
{
public $product;
public $item;
public $quantity;
public $cost = 0;
public $cost_per = 0;
public $items;
public function __construct($aProduct, $aItem, $aQuantity){
// TODO check individual product.
$this->product = $aProduct;
$this->item = $aItem;
$this->quantity = $aQuantity;
$this->calculate_cost();
}
private function calculate_cost(){
$prod = ORM::factory("product", $this->product);
$this->cost = $prod->cost * $this->quantity;
$this->cost_per = $prod->cost;
}
public function add($quantity){
$this->quantity += $quantity;
$this->calculate_cost();
}
public function size(){
return $this->quantity;
}
public function getItem(){
$photo = ORM::factory("item", $this->item);
return $photo;
}
public function product_description(){
$prod = ORM::factory("product", $this->product);
return $prod->description;
}
public function getCode(){
$photo = ORM::factory("item", $this->item);
$prod = ORM::factory("product", $this->product);
return $photo->id." - ".$photo->title." - ".$prod->name;
}
}
class Session_Basket_Core {
public $contents = array();
public $name = "";
public $house = "";
public $street = "";
public $suburb = "";
public $town = "";
public $postcode = "";
public $email = "";
public $phone = "";
public function clear(){
if (isset($this->contents)){
foreach ($this->contents as $key => $item){
unset($this->contents[$key]);
}
}
}
private function create_key($product, $id){
return "$product _ $id";
}
public function size(){
$size = 0;
if (isset($this->contents)){
foreach ($this->contents as $product => $basket_item){
$size += $basket_item->size();
}
}
return $size;
}
public function add($id, $product, $quantity){
$key = $this->create_key($product, $id);
if (isset($this->contents[$key])){
$this->contents[$key]->add($id, $quantity);
}
else {
$this->contents[$key] = new basket_item($product, $id, $quantity);
}
}
public function remove($key){
unset($this->contents[$key]);
}
public function cost(){
$cost = 0;
if (isset($this->contents)){
foreach ($this->contents as $product => $basket_item){
$cost += $basket_item->cost;
}
}
return $cost;
}
public static function get(){
return Session::instance()->get("basket");
}
public static function getOrCreate(){
$session = Session::instance();
$basket = $session->get("basket");
if (!$basket)
{
$basket = new Session_Basket();
$session->set("basket", $basket);
}
return $basket;
}
}

View File

@ -0,0 +1,24 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Product_Model extends ORM {
var $rules = array(
"name" => "length[1,32]",
"description" => "length[0,255]");
}

View File

@ -0,0 +1,3 @@
name = "Shopping Basket"
description = "Provides a simple shopping basket and checkout with paypal integration"
version = 1

View File

@ -0,0 +1,8 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="add_to_basket">
<a href="<?= url::site("basket/add_to_basket_ajax/$item->id") ?>"
title="<?= t("Add To Basket") ?>"
class="gDialogLink">
Add To Basket</a>
</div>

View File

@ -0,0 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gAddToBasket">
<div id="basketThumb">
<img src="<?= $item->thumb_url()?>" title="<?= $item->title?>" alt="<?= $item->title?>" />
</div>
<div id="basketForm">
<?= $form ?>
</div>
</div>

View File

@ -0,0 +1,8 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gAdminConfigure">
<h1> <?= t("Configure Shopping Basket") ?> </h1>
<p>
<?= t("Use this page to configure the shopping basket. If you have paypal you can use this to processs the final payments.") ?>
</p>
<?= $form ?>
</div>

View File

@ -0,0 +1,70 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<div class="gBlock">
<a href="<?= url::site("admin/product_lines/add_product_form") ?>"
class="gDialogLink gButtonLink right ui-icon-left ui-state-default ui-corner-all"
title="<?= t("Create a new Product") ?>">
<span class="ui-icon ui-icon-circle-plus"></span>
<?= t("Add a new Product") ?>
</a>
<h2>
<?= t("Product Lines") ?>
</h2>
<div class="gBlockContent">
<table id="gProductAdminList">
<tr>
<th><?= t("Name") ?></th>
<th><?= t("Cost") ?></th>
<th><?= t("Description") ?></th>
<th><?= t("Actions") ?></th>
</tr>
<? foreach ($products as $i => $product): ?>
<tr id="gProduct-<?= $product->id ?>" class="<?= text::alternate("gOddRow", "gEvenRow") ?>">
<td id="product-<?= $product->id ?>" class="core-info ">
<?= html::clean($product->name) ?>
</td>
<td>
<?= basket::formatMoney($product->cost) ?>
</td>
<td>
<?= html::clean($product->description) ?>
</td>
<td class="gActions">
<a href="<?= url::site("admin/product_lines/edit_product_form/$product->id") ?>"
open_text="<?= t("close") ?>"
class="gPanelLink gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-pencil"></span><span class="gButtonText"><?= t("edit") ?></span></a>
<a href="<?= url::site("admin/product_lines/delete_product_form/$product->id") ?>"
class="gDialogLink gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-trash"></span><?= t("delete") ?></a>
</td>
</tr>
<? endforeach ?>
</table>
</div>
</div>

View File

@ -0,0 +1,35 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<div id="basket">
<? if ($theme->page_type != 'basket'): ?>
<? if (isset($basket) && isset($basket->contents)): ?>
<a href="<?= url::site("basket/view_basket") ?>"
title="<?= t("View Basket") ?>">
<img src="<?= url::file("modules/basket/images/basket.png") ?>"><br/>
<?= $basket->size()?> items</a>
<? else: ?>
<a href="<?= url::site("basket/view_basket") ?>"
title="<?= t("View Basket") ?>">
<img src="<?= url::file("modules/basket/images/basket.png") ?>"><br/>
<?= t("Empty") ?></a>
<? endif ?>
<? endif ?>
</div>

View File

@ -0,0 +1,64 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<SCRIPT language="JavaScript">
function ive(s)
{
return (s.indexOf(".")>2)&&(s.indexOf("@")>0);
}
function se(v)
{
v.style.backgroundColor="#FAA";
}
function re(v)
{
v.style.backgroundColor="#FFF";
}
function ci(v)
{
if ((!v.value) || (v.value.length==0)) {se(v);return false;}
re(v);
return true;
}
function so(){
var p=true;
var d=document.checkout;
if(!ci(d.fullname)){p=false;}
if((!ci(d.email))||(!ive(d.email.value))){se(d.email);p=false;}
if(!ci(d.phone)){p=false;}
if (p)
{
d.submit();
}
}
</SCRIPT>
<div class="gBlock">
<?= $form ?>
<h2>Payment Details</h2>
<p>After you have confirmed the order we will get in contact with you to arrange payment.</p>
<a href="<?= url::site("basket/view_basket") ?>" class="left gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-arrow-1-w"></span><?= t("Back to Basket") ?></a>
<a href="javascript: so()" class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Proceed to Confirmation") ?></a>
</div>

View File

@ -0,0 +1,82 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<SCRIPT language="JavaScript">
function so(){document.confirm.submit();}
</SCRIPT>
<?= $form ?>
<div class="gBlock">
<h2>Basket Summary</h2>
<div class="gBlockContent">
<table id="gBasketList">
<tr>
<th><?= t("Name") ?></th>
<th><?= t("Product") ?></th>
<th><?= t("Quantity") ?></th>
<th><?= t("Cost") ?></th>
</tr>
<? foreach ($basket->contents as $key => $prod_details): ?>
<tr id="" class="<?= text::alternate("gOddRow", "gEvenRow") ?>">
<td id="item-<?= $prod_details->item ?>" class="core-info ">
<? $item = $prod_details->getItem(); ?>
<div>
<?= html::clean($item->title) ?>
</div>
</td>
<td>
<?= html::clean($prod_details->product_description()) ?>
</td>
<td>
<?= html::clean($prod_details->quantity) ?>
</td>
<td>
<?= basket::formatMoney($prod_details->cost) ?>
</td>
</tr>
<? endforeach ?>
<tr id="" class="<?= text::alternate("gOddRow", "gEvenRow") ?>">
<td></td><td></td><td>Total Cost</td><td><?= $basket->cost()?></td>
</tr>
</table>
</div>
<table>
<tr><td>
<h2>Delivery Address</h2>
<?= $basket->name ?><br/>
<?= $basket->house ?>,
<?= $basket->street ?><br/>
<?= $basket->suburb ?><br/>
<?= $basket->town ?><br/>
<?= $basket->postcode ?><br/>
</td>
<td>
<h2>Contact Details</h2>
E-mail : <?= $basket->email ?><br/>
Telephone : <?= $basket->phone ?>
</td></tr>
</table>
<a href="<?= url::site("basket/checkout") ?>" class="left gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-arrow-1-w"></span><?= t("Back to Checkout") ?></a>
<a href="javascript: so()" class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Confirm Order") ?></a>
</div>

View File

@ -0,0 +1,24 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<div class="gBlock">
<h2>Thankyou for your order</h2>
You will be contacted soon to arrange payment and delivery.
</div>

View File

@ -0,0 +1,117 @@
<?php defined("SYSPATH") or die("No direct script access.")
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
?>
<div class="gBlock">
<? if (isset($basket->contents ) && count($basket->contents) > 0): ?>
<? if (basket::isPaypal()): ?>
<?= basket::generatePaypalForm($basket) ?>
<script language="JavaScript">
function co(){
var d=document.paypal_form.submit();
}</script>
<a href="javascript:co();"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Pay with Credit Card or Paypal") ?></a>
<a href="<?= url::site("basket/checkout") ?>"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Pay off line") ?></a>
<? else: ?>
<a href="<?= url::site("basket/checkout") ?>"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Proceed to Checkout") ?></a>
<? endif; ?>
<? endif; ?>
<h2>
<?= t("Shopping Basket") ?>
</h2>
<div class="gBlockContent">
<? if (isset($basket->contents ) && count($basket->contents) > 0): ?>
<table id="gBasketList">
<tr>
<th><?= t("Picture") ?></th>
<th><?= t("Product") ?></th>
<th><?= t("Quantity") ?></th>
<th><?= t("Cost") ?></th>
<th><?= t("Actions") ?></th>
</tr>
<? $total=0;?>
<? foreach ($basket->contents as $key => $prod_details): ?>
<tr id="" class="<?= text::alternate("gOddRow", "gEvenRow") ?>">
<td id="item-<?= $prod_details->item ?>" class="core-info ">
<? $item = $prod_details->getItem(); ?>
<div id="basketThumb">
<img src="<?= $item->thumb_url()?>" title="<?= $item->title?>" alt="<?= $item->title?>" />
</div>
</td>
<td>
<?= html::clean($prod_details->product_description()) ?>
</td>
<td>
<?= html::clean($prod_details->quantity) ?>
</td>
<td>
<? $total += $prod_details->cost?>
<?= basket::formatMoney($prod_details->cost) ?>
</td>
<td class="gActions">
<!-- a href="<?= url::site("admin/product_lines/edit_product_form/") ?>"
open_text="<?= t("close") ?>"
class="gPanelLink gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-pencil"></span><span class="gButtonText"><?= t("edit") ?></span></a-->
<a href="<?= url::site("basket/remove_item/$key") ?>"
class="gButtonLink ui-state-default ui-corner-all ui-icon-left">
<span class="ui-icon ui-icon-trash"></span><?= t("Remove") ?></a>
</td>
</tr>
<? endforeach ?>
<tr id="" class="<?= text::alternate("gOddRow", "gEvenRow") ?>">
<td></td><td></td><td>Total Cost</td><td><?= basket::formatMoney($total)?></td><td></td>
</tr>
</table>
<? else: ?>
Shopping Basket is Empty
<? endif; ?>
</div>
<? if (isset($basket->contents ) && count($basket->contents) > 0): ?>
<? if (basket::isPaypal()): ?>
<a href="javascript:co();"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Pay with Credit Card or Paypal") ?></a>
<a href="<?= url::site("basket/checkout") ?>"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Pay off line") ?></a>
<? else: ?>
<a href="<?= url::site("basket/checkout") ?>"
class="right gButtonLink ui-state-default ui-corner-all ui-icon-right">
<span class="ui-icon ui-icon-arrow-1-e"></span><?= t("Proceed to Checkout") ?></a>
<? endif; ?>
<? endif; ?>
</div>

View File

@ -21,6 +21,11 @@ class batchtag_theme_Core {
static function sidebar_blocks($theme) {
// Display form for tagging in the album sidebar.
// Make sure the current page belongs to an item.
if (!$theme->item()) {
return;
}
$item = $theme->item();
// Only display the form in albums that the user has edit permission in.

View File

@ -2,9 +2,9 @@
<div class="gDisplayTagsBlock">
<? for ($counter=0; $counter<count($tags); $counter++) { ?>
<? if ($counter < count($tags)-1) { ?>
<a href="<?= url::site("tags/$tags[$counter]") ?>"><?= p::clean($tags[$counter]->name) ?></a>,
<a href="<?= url::site("tags/$tags[$counter]") ?>"><?= html::clean($tags[$counter]->name) ?></a>,
<? } else {?>
<a href="<?= url::site("tags/$tags[$counter]") ?>"><?= p::clean($tags[$counter]->name) ?></a>
<a href="<?= url::site("tags/$tags[$counter]") ?>"><?= html::clean($tags[$counter]->name) ?></a>
<? } ?>
<? } ?>
</div>

View File

@ -0,0 +1,41 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class editcreation_event_Core {
static function item_edit_form($item, $form) {
// Add a couple of drop-down boxes to allow the user to edit the date
// that $item was created on.
// Inject some css to make everything look right.
print ("<style>\nselect {\ndisplay: inline;\n}\n</style>\n");
// Add the datecreated element to the form.
$form->edit_item->dateselect("datecreated")
->label(t("Created"))
->minutes(1)
->years(1970, date('Y')+1)
->value($item->created);
}
static function item_edit_form_completed($item, $form) {
// Change the item's created field to the specified value.
$item->created = $form->edit_item->datecreated->value;
$item->save();
}
}

View File

@ -0,0 +1,27 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class editcreation_installer {
static function install() {
module::set_version("editcreation", 1);
}
static function uninstall() {
module::delete("editcreation");
}
}

View File

@ -0,0 +1,3 @@
name = "Edit Creation"
description = "Manually edit the creation date of an item in Gallery."
version = 1

View File

@ -82,13 +82,13 @@ class Admin_EmbedLinks_Controller extends Admin_Controller {
array("id" => "gEmbedLinksAdminForm"));
// Make an array for the different types of link codes.
$linkCodes["HTMLCode"] = array("Show HTML Links", module::get_var("embedlinks", "HTMLCode"));
$linkCodes["BBCode"] = array("Show BBCode Links", module::get_var("embedlinks", "BBCode"));
$linkCodes["FullURL"] = array("Show the full URL", module::get_var("embedlinks", "FullURL"));
$linkCodes["HTMLCode"] = array(t("Show HTML Links"), module::get_var("embedlinks", "HTMLCode"));
$linkCodes["BBCode"] = array(t("Show BBCode Links"), module::get_var("embedlinks", "BBCode"));
$linkCodes["FullURL"] = array(t("Show the full URL"), module::get_var("embedlinks", "FullURL"));
// Make an array for the different methods of displaying the links.
$linkDisplays["InPageLinks"] = array("Show Links In The Actual Page", module::get_var("embedlinks", "InPageLinks"));
$linkDisplays["DialogLinks"] = array("Show Links In a Seperate Dialog Box", module::get_var("embedlinks", "DialogLinks"));
$linkDisplays["InPageLinks"] = array(t("Show Links In The Actual Page"), module::get_var("embedlinks", "InPageLinks"));
$linkDisplays["DialogLinks"] = array(t("Show Links In a Seperate Dialog Box"), module::get_var("embedlinks", "DialogLinks"));
// Setup a few checkboxes on the form.
$add_links = $form->group("EmbedLinks");

View File

@ -26,12 +26,29 @@ class EmbedLinks_Controller extends Controller {
$item = ORM::factory("item", $item_id);
access::required("view", $item);
// If the current page is an album, only display two links,
// or else display many.
// If the current page is an album, only display two links.
if ($item->is_album()) {
$linkArray[0] = array("Text:", "<a href=&quot;" . url::abs_site("{$item->type}s/{$item->id}") . "&quot;>Click Here</a>");
$linkArray[1] = array("Thumbnail:", "<a href=&quot;" . url::abs_site("{$item->type}s/{$item->id}") . "&quot;><img src=&quot;" . $item->thumb_url(true) . "&quot;></a>");
$linkTitles[0] = array("Link To This Album:", 2);
// If the item is a movie, don't display resize links, do display an embed link.
} elseif ($item->is_movie()) {
// Link to the current page.
$linkArray[0] = array("Text:", "<a href=&quot;" . url::abs_site("{$item->type}s/{$item->id}") . "&quot;>Click Here</a>");
$linkArray[1] = array("Thumbnail:", "<a href=&quot;" . url::abs_site("{$item->type}s/{$item->id}") . "&quot;><img src=&quot;" . $item->thumb_url(true) . "&quot;></a>");
$linkTitles[0] = array("Link To This Page:", 2);
// If the visitor has suficient privlidges to see the fullsized
// version of the current image, then display links to it.
if (access::can("view_full", $item)) {
$linkArray[2] = array("Text:", "<a href=&quot;" . $item->file_url(true) . "&quot;>Click Here</a>");
$linkArray[3] = array("Thumbnail:", "<a href=&quot;" . $item->file_url(true) . "&quot;><img src=&quot;" . $item->thumb_url(true) . "&quot;></a>");
$linkArray[4] = array("Embed:", "<object width=&quot;" . $item->width . "&quot; height=&quot;" . $item->height . "&quot; data=&quot;" . url::abs_file("lib/flowplayer.swf") . "&quot; type=&quot;application/x-shockwave-flash&quot;><param name=&quot;movie&quot; value=&quot;" . url::abs_file("lib/flowplayer.swf") . "&quot; /><param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /><param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /><param name=&quot;flashvars&quot; value='config={&quot;plugins&quot;:{&quot;pseudo&quot;:{&quot;url&quot;:&quot;flowplayer.h264streaming.swf&quot;},&quot;controls&quot;:{&quot;backgroundColor&quot;:&quot;#000000&quot;,&quot;backgroundGradient&quot;:&quot;low&quot;}},&quot;clip&quot;:{&quot;provider&quot;:&quot;pseudo&quot;,&quot;url&quot;:&quot;" . $item->file_url(true) . "&quot;},&quot;playlist&quot;:[{&quot;provider&quot;:&quot;pseudo&quot;,&quot;url&quot;:&quot;" . $item->file_url(true) . "&quot;}]}' /></object>");
$linkTitles[1] = array("Link To The Video File:", 3);
}
// Or else assume the item is a photo.
} else {
// Link to the current page.
$linkArray[0] = array("Text:", "<a href=&quot;" . url::abs_site("{$item->type}s/{$item->id}") . "&quot;>Click Here</a>");
@ -51,7 +68,7 @@ class EmbedLinks_Controller extends Controller {
$linkArray[6] = array("Text:", "<a href=&quot;" . $item->file_url(true) . "&quot;>Click Here</a>");
$linkArray[7] = array("Thumbnail:", "<a href=&quot;" . $item->file_url(true) . "&quot;><img src=&quot;" . $item->thumb_url(true) . "&quot;></a>");
$linkArray[8] = array("Resized:", "<a href=&quot;" . $item->file_url(true) . "&quot;><img src=&quot;" . $item->resize_url(true) . "&quot;></a>");
$linkTitles[2] = array("Link To The Fullsize Image:", 3);
$linkTitles[2] = array("Link To The Full Size Image:", 3);
}
}
@ -66,12 +83,28 @@ class EmbedLinks_Controller extends Controller {
$item = ORM::factory("item", $item_id);
access::required("view", $item);
// If the current page is an album, only display two links,
// or else display many.
// If the current page is an album, only display two links.
if ($item->is_album()) {
$linkArray[0] = array("Text:", "[url=" . url::abs_site("{$item->type}s/{$item->id}") . "]Click Here[/url]");
$linkArray[1] = array("Thumbnail:", "[url=" . url::abs_site("{$item->type}s/{$item->id}") . "][img]" . $item->thumb_url(true) . "[/img][/url]");
$linkTitles[0] = array("Link To This Album:", 2);
// If the item is a movie, don't display resize links.
} elseif ($item->is_movie()) {
// Link to the current page.
$linkArray[0] = array("Text:", "[url=" . url::abs_site("{$item->type}s/{$item->id}") . "]Click Here[/url]");
$linkArray[1] = array("Thumbnail:", "[url=" . url::abs_site("{$item->type}s/{$item->id}") . "][img]" . $item->thumb_url(true) . "[/img][/url]");
$linkTitles[0] = array("Link To This Page:", 2);
// If the visitor has suficient privlidges to see the fullsized
// version of the current image, then display links to it.
if (access::can("view_full", $item)) {
$linkArray[2] = array("Text:", "[url=" . $item->file_url(true) . "]Click Here[/url]");
$linkArray[3] = array("Thumbnail:", "[url=" . $item->file_url(true) . "][img]" . $item->thumb_url(true) . "[/img][/url]");
$linkTitles[1] = array("Link To The Video File:", 2);
}
// Or else assume the item is a photo.
} else {
// Link to the current page.
$linkArray[0] = array("Text:", "[url=" . url::abs_site("{$item->type}s/{$item->id}") . "]Click Here[/url]");
@ -91,7 +124,7 @@ class EmbedLinks_Controller extends Controller {
$linkArray[6] = array("Text:", "[url=" . $item->file_url(true) . "]Click Here[/url]");
$linkArray[7] = array("Thumbnail:", "[url=" . $item->file_url(true) . "][img]" . $item->thumb_url(true) . "[/img][/url]");
$linkArray[8] = array("Resized:", "[url=" . $item->file_url(true) . "][img]" . $item->resize_url(true) . "[/img][/url]");
$linkTitles[2] = array("Link To The Fullsize Image:", 3);
$linkTitles[2] = array("Link To The Full Size Image:", 3);
}
}
@ -106,12 +139,28 @@ class EmbedLinks_Controller extends Controller {
$item = ORM::factory("item", $item_id);
access::required("view", $item);
// If the current page is an album, only display a URL field,
// or else display a couple of fields.
// If the current page is an album, only display a URL and thumnail fields.
if ($item->is_album()) {
$linkArray[0] = array("Album URL:", url::abs_site("{$item->type}s/{$item->id}"));
$linkArray[1] = array("Thumbnail:", $item->thumb_url(true));
$linkTitles[0] = array("URLs:", 2);
// If the item is a movie, do not display the resize url.
} elseif ($item->is_movie()) {
// Link to the current page.
$linkArray[0] = array("This Page:", url::abs_site("{$item->type}s/{$item->id}"));
$linkArray[1] = array("Thumbnail:", $item->thumb_url(true));
// If the visitor has suficient privlidges to see the fullsized
// version of the current image, then display its URL.
if (access::can("view_full", $item)) {
$linkArray[2] = array("Video File:", $item->file_url(true));
$linkTitles[0] = array("URLs:", 3);
} else {
$linkTitles[0] = array("URLs:", 2);
}
// Or else assume the item is a photo.
} else {
// Link to the current page.
$linkArray[0] = array("This Page:", url::abs_site("{$item->type}s/{$item->id}"));
@ -121,7 +170,7 @@ class EmbedLinks_Controller extends Controller {
// If the visitor has suficient privlidges to see the fullsized
// version of the current image, then display its URL.
if (access::can("view_full", $item)) {
$linkArray[3] = array("Fullsize:", $item->file_url(true));
$linkArray[3] = array("Full Size:", $item->file_url(true));
$linkTitles[0] = array("URLs:", 4);
} else {
$linkTitles[0] = array("URLs:", 3);

View File

@ -23,14 +23,20 @@ input[type="text"] {
<td><input type="text" value="<a href=&quot;<?= url::abs_site("{$item->type}s/{$item->id}") ?>&quot;><img src=&quot;<?= $item->thumb_url(true) ?>&quot;></a>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? if ($item->is_photo()) { ?>
<tr>
<th><?= t("Resized:") ?></th>
<td><input type="text" value="<a href=&quot;<?= url::abs_site("{$item->type}s/{$item->id}") ?>&quot;><img src=&quot;<?= $item->resize_url(true) ?>&quot;></a>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? if (access::can("view_full", $item)) { ?>
<tr>
<th colspan="2"><br/><?= t("Link To The Fullsize Image:") ?></th>
<? if ($item->is_movie()) { ?>
<th colspan="2"><br/><?= t("Link To The Video File:") ?></th>
<? } else { ?>
<th colspan="2"><br/><?= t("Link To The Full Size Image:") ?></th>
<? }?>
</tr>
<tr>
@ -43,12 +49,22 @@ input[type="text"] {
<td><input type="text" value="<a href=&quot;<?= $item->file_url(true) ?>&quot;><img src=&quot;<?= $item->thumb_url(true) ?>&quot;></a>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? if ($item->is_photo()) { ?>
<tr>
<th><?= t("Resized:") ?></th>
<td><input type="text" value="<a href=&quot;<?= $item->file_url(true) ?>&quot;><img src=&quot;<?= $item->resize_url(true) ?>&quot;></a>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? if ($item->is_movie()) { ?>
<tr>
<th><?= t("Embed:") ?></th>
<td><input type="text" value="<object width=&quot;<?= $item->width ?>&quot; height=&quot;<?= $item->height ?>&quot; data=&quot;<?= url::abs_file("lib/flowplayer.swf") ?>&quot; type=&quot;application/x-shockwave-flash&quot;><param name=&quot;movie&quot; value=&quot;<?= url::abs_file("lib/flowplayer.swf") ?>&quot; /><param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /><param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /><param name=&quot;flashvars&quot; value='config={&quot;plugins&quot;:{&quot;pseudo&quot;:{&quot;url&quot;:&quot;flowplayer.h264streaming.swf&quot;},&quot;controls&quot;:{&quot;backgroundColor&quot;:&quot;#000000&quot;,&quot;backgroundGradient&quot;:&quot;low&quot;}},&quot;clip&quot;:{&quot;provider&quot;:&quot;pseudo&quot;,&quot;url&quot;:&quot;<?= $item->file_url(true) ?>&quot;},&quot;playlist&quot;:[{&quot;provider&quot;:&quot;pseudo&quot;,&quot;url&quot;:&quot;<?= $item->file_url(true) ?>&quot;}]}' /></object>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? } ?>
<? if ($item->is_photo()) { ?>
<tr>
<th colspan="2"><br/><?= t("Link To The Resized Image:") ?></th>
</tr>
@ -67,7 +83,7 @@ input[type="text"] {
<th><?= t("Image:") ?></th>
<td><input type="text" value="<img src=&quot;<?= $item->resize_url(true) ?>&quot;>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
</tbody>
</table>
<? } ?>
@ -90,14 +106,20 @@ input[type="text"] {
<td><input type="text" value="[url=<?= url::abs_site("{$item->type}s/{$item->id}") ?>][img]<?= $item->thumb_url(true) ?>[/img][/url]" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? if ($item->is_photo()) { ?>
<tr>
<th><?= t("Resized:") ?></th>
<td><input type="text" value="[url=<?= url::abs_site("{$item->type}s/{$item->id}") ?>][img]<?= $item->resize_url(true) ?>[/img][/url]" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? if (access::can("view_full", $item)) { ?>
<tr>
<th colspan="2"><br/><?= t("Link To The Fullsize Image:") ?></th>
<? if ($item->is_movie()) { ?>
<th colspan="2"><br/><?= t("Link To The Video File:") ?></th>
<? } else { ?>
<th colspan="2"><br/><?= t("Link To The Full Size Image:") ?></th>
<? }?>
</tr>
<tr>
@ -110,12 +132,15 @@ input[type="text"] {
<td><input type="text" value="[url=<?= $item->file_url(true) ?>][img]<?= $item->thumb_url(true) ?>[/img][/url]" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? if ($item->is_photo()) { ?>
<tr>
<th><?= t("Resized:") ?></th>
<td><input type="text" value="[url=<?= $item->file_url(true) ?>][img]<?= $item->resize_url(true) ?>[/img][/url]" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? } ?>
<? if ($item->is_photo()) { ?>
<tr>
<th colspan="2"><br/><?= t("Link To The Resized Image:") ?></th>
</tr>
@ -134,21 +159,11 @@ input[type="text"] {
<th><?= t("Image:") ?></th>
<td><input type="text" value="[img]<?= $item->resize_url(true) ?>[/img]" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
</tbody>
</table>
<? } ?>
<? if (module::get_var("embedlinks", "FullURL")) { ?>
<h3 align="center"><?= t("URLs")?></h3>
<table class="gEmbedLinks">
@ -163,14 +178,20 @@ input[type="text"] {
<td><input type="text" value="<?= $item->thumb_url(true) ?>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? if ($item->is_photo()) { ?>
<tr>
<th><?= t("Resized:") ?></th>
<td><input type="text" value="<?= $item->resize_url(true) ?>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>
<? if (access::can("view_full", $item)) { ?>
<tr>
<th><?= t("Fullsize:") ?></th>
<? if ($item->is_movie()) { ?>
<th><?= t("Video File:") ?></th>
<? } else { ?>
<th><?= t("Full size:") ?></th>
<? } ?>
<td><input type="text" value="<?= $item->file_url(true) ?>" onclick="this.focus(); this.select();" readonly></td>
</tr>
<? } ?>

View File

@ -19,6 +19,8 @@
*/
class itemchecksum_Controller extends Controller {
public function albumcount($album_id) {
// Display the number of non-album items (photos and videos)
// in the specified album ($album_id).
$item = ORM::factory("item")
->viewable()
->where("parent_id", $album_id)
@ -29,6 +31,8 @@ class itemchecksum_Controller extends Controller {
}
public function md5($album_id, $file_name) {
// Locate an item with $file_name in the album $album_id
// and display it's md5 checksum.
$item = ORM::factory("item")
->where("parent_id", $album_id)
->where("name", $file_name)
@ -36,6 +40,9 @@ class itemchecksum_Controller extends Controller {
if (count($item) > 0) {
access::required("view_full", $item[0]);
// If the KeepOriginal module is active, check for/use the
// original image instead of the gallery edited version.
if (module::is_active("keeporiginal")) {
$original_image = VARPATH . "original/" . str_replace(VARPATH . "albums/", "", $item[0]->file_path());
if ($item[0]->is_photo() && file_exists($original_image)) {
@ -52,6 +59,8 @@ class itemchecksum_Controller extends Controller {
}
public function sha1($album_id, $file_name) {
// Locate an item with $file_name in the album $album_id
// and display it's sha-1 checksum.
$item = ORM::factory("item")
->where("parent_id", $album_id)
@ -60,6 +69,9 @@ class itemchecksum_Controller extends Controller {
if (count($item) > 0) {
access::required("view_full", $item[0]);
// If the KeepOriginal module is active, check for/use the
// original image instead of the gallery edited version.
if (module::is_active("keeporiginal")) {
$original_image = VARPATH . "original/" . str_replace(VARPATH . "albums/", "", $item[0]->file_path());
if ($item[0]->is_photo() && file_exists($original_image)) {

View File

@ -1,3 +1,3 @@
name = ItemChecksum
description = Display's a photo or video's MD5 and SHA-1 checksum.
name = "ItemChecksum"
description = "Display's a photo or video's MD5 and SHA-1 checksum."
version = 1

View File

@ -26,13 +26,14 @@ class latestupdates_theme_Core {
$albumID = $theme->item->is_album() ? $theme->item->id : $theme->item->parent_id;
$block = new Block();
$block->css_id = "gUpdates";
$block->css_id = "gUpdatesBlock";
$block->title = t("Updates");
$block->content = new View("latestupdates_block.html");
$block->content->updateLinks = array(
t("Entire Gallery") => url::site("latestupdates/updates"),
t("This Album") => url::site("latestupdates/albums/$albumID")
$block->content->update_links = array(
"Entire Gallery" => url::site("latestupdates/updates"),
"This Album" => url::site("latestupdates/albums/$albumID")
);
return $block;
}
}

View File

@ -1,9 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul id="gUpdates">
<? foreach($updateLinks as $title => $url): ?>
<ul id="gUpdatesList">
<? foreach($update_links as $title => $url): ?>
<li style="clear: both;">
<a href="<?= $url ?>">
<?= $title ?>
<?= t($title) ?>
</a>
</li>
<? endforeach ?>

View File

@ -3,7 +3,7 @@
<div id="gLatestUpdates">
<h1><?= t("Latest Updates") ?></h1>
<? array("term" => p::clean($q)) ?>
<? array("term" => html::clean($q)) ?>
<? if (count($items)): ?>
<ul id="gAlbumGrid">
<? foreach ($items as $item): ?>
@ -15,10 +15,10 @@
<a href="<?= url::site("items/$item->id") ?>">
<?= $item->thumb_img() ?>
<p>
<?= p::clean($item->title) ?>
<?= html::clean($item->title) ?>
</p>
<div>
<?= p::clean($item->description) ?>
<?= html::clean($item->description) ?>
</div>
</a>
</li>

View File

@ -5,28 +5,28 @@
if (count($tags) > 0) {
for ($counter=0; $counter<count($tags); $counter++) {
if ($counter < count($tags)-1) {
$metaTags = $metaTags . p::clean($tags[$counter]->name) . ",";
$metaTags = $metaTags . html::clean($tags[$counter]->name) . ",";
} else {
$metaTags = $metaTags . p::clean($tags[$counter]->name);
$metaTags = $metaTags . html::clean($tags[$counter]->name);
}
}
}
// If $metaTags is empty, use the item's title instead.
if ($metaTags == "") {
$metaTags = p::clean($item->title);
$metaTags = html::clean($item->title);
}
$metaDescription = "";
$metaDescription = trim(nl2br(p::purify($item->description)));
$metaDescription = trim(nl2br(html::purify($item->description)));
// If description is empty, use title instead.
if ($metaDescription == "") {
$metaDescription = p::clean($item->title);
$metaDescription = html::clean($item->title);
}
// If this page belongs to a tag, use the description of the first item instead.
if ($theme->tag()) {
if (count($children) > 0) {
$metaDescription = trim(nl2br(p::purify($children[0]->description)));
$metaDescription = trim(nl2br(html::purify($children[0]->description)));
}
}
// If it's still empty, use $metaTags.

View File

@ -0,0 +1,6 @@
Copy "ico-view-minislideshow.png" into your "themes/CURRENTTHEME/images" folder.
Edit the file "themes/CURRENTTHEME/css/screen.css" to include the following lines:
#gViewMenu #gMiniSlideshowLink {
background-image: url('../images/ico-view-minislideshow.png');
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,127 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Admin_Minislideshow_Controller extends Admin_Controller {
public function index() {
// Generate a new admin page.
$view = new Admin_View("admin.html");
$view->content = new View("admin_minislideshow.html");
$view->content->minislideshow_form = $this->_get_admin_form();
print $view;
}
public function saveprefs() {
// Process the admin form.
// Prevent Cross Site Request Forgery
access::verify_csrf();
// Save user specified settings to the database.
$str_slideshow_url = Input::instance()->post("slideshow_url");
module::set_var("minislideshow", "slideshow_url", $str_slideshow_url);
$str_slideshow_shuffle = Input::instance()->post("shuffle");
module::set_var("minislideshow", "shuffle", $str_slideshow_shuffle);
$str_slideshow_dropshadow = Input::instance()->post("dropshadow");
module::set_var("minislideshow", "dropshadow", $str_slideshow_dropshadow);
$str_slideshow_show_title = Input::instance()->post("show_title");
module::set_var("minislideshow", "show_title", $str_slideshow_show_title);
$str_slideshow_trans_in_type = Input::instance()->post("trans_in_type");
module::set_var("minislideshow", "trans_in_type", $str_slideshow_trans_in_type);
$str_slideshow_trans_out_type = Input::instance()->post("trans_out_type");
module::set_var("minislideshow", "trans_out_type", $str_slideshow_trans_out_type);
$str_slideshow_mask = Input::instance()->post("mask");
module::set_var("minislideshow", "mask", $str_slideshow_mask);
$str_slideshow_use_full_image = Input::instance()->post("use_full_image");
module::set_var("minislideshow", "use_full_image", $str_slideshow_use_full_image);
$str_slideshow_delay = Input::instance()->post("delay");
module::set_var("minislideshow", "delay", $str_slideshow_delay);
// Display a success message and load the admin screen.
message::success(t("Your Settings Have Been Saved."));
$view = new Admin_View("admin.html");
$view->content = new View("admin_minislideshow.html");
$view->content->minislideshow_form = $this->_get_admin_form();
print $view;
}
private function _get_admin_form() {
// Generate a form for configuring the slideshow.
// Make a new Form.
$form = new Forge("admin/minislideshow/saveprefs", "", "post",
array("id" => "gMinislideshowAdminForm"));
// Get location of slideshow files.
$group_slideshow_files = $form->group("Minislideshow");
$group_slideshow_files->input("slideshow_url")
->label(t("URL to your minislideshow.swf"))
->value(module::get_var("minislideshow", "slideshow_url"));
// Get additional settings for the slideshow.
$group_slideshow_settings = $form->group("MinislideshowSettings");
$group_slideshow_settings->label(t("MiniSlide Show Settings"));
$group_slideshow_settings->dropdown('shuffle')
->label(t("Shuffle:"))
->options(array('true'=>'True', ''=>'False'))
->selected(module::get_var("minislideshow", "shuffle"));
$group_slideshow_settings->dropdown('dropshadow')
->label(t("Drop Shadow:"))
->options(array('true'=>'True', ''=>'False'))
->selected(module::get_var("minislideshow", "dropshadow"));
$group_slideshow_settings->dropdown('show_title')
->label(t("Show Title:"))
->options(array('top'=>'Top', 'bottom'=>'Bottom', ''=>'False'))
->selected(module::get_var("minislideshow", "show_title"));
$group_slideshow_settings->dropdown('trans_in_type')
->label(t("Transition In:"))
->options(array('Blinds'=>'Blinds', ''=>'Fade', 'Fly'=>'Fly', 'Iris'=>'Iris', 'Photo'=>'Photo', 'PixelDissolve'=>'Pixel Dissolve', 'Rotate'=>'Rotate', 'Squeeze'=>'Squeeze', 'Wipe'=>'Wipe', 'Zoom'=>'Zoom', 'Random'=>'Random'))
->selected(module::get_var("minislideshow", "trans_in_type"));
$group_slideshow_settings->dropdown('trans_out_type')
->label(t("Transition Out:"))
->options(array('Blinds'=>'Blinds', ''=>'Fade', 'Fly'=>'Fly', 'Iris'=>'Iris', 'Photo'=>'Photo', 'PixelDissolve'=>'Pixel Dissolve', 'Rotate'=>'Rotate', 'Squeeze'=>'Squeeze', 'Wipe'=>'Wipe', 'Zoom'=>'Zoom', 'Random'=>'Random'))
->selected(module::get_var("minislideshow", "trans_out_type"));
$group_slideshow_settings->dropdown('mask')
->label(t("Mask:"))
->options(array(''=>'None', 'circleMask'=>'Circle', 'roundedMask'=>'Rounded Corners', 'starMask'=>'Star'))
->selected(module::get_var("minislideshow", "mask"));
$group_slideshow_settings->dropdown('use_full_image')
->label(t("Use Full Image:"))
->options(array('true', 'false', 'Use Resize'))
->selected(module::get_var("minislideshow", "use_full_image"));
$group_slideshow_settings->input("delay")
->label(t("Delay:"))
->value(module::get_var("minislideshow", "delay"));
// Add a save button to the form.
$form->submit("SaveSettings")->value(t("Save"));
// Return the newly generated form.
return $form;
}
}

View File

@ -0,0 +1,69 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class MiniSlideShow_Controller extends Controller {
public function showslideshow($item_id) {
// Generate the Dialog Box to display the slideshow in.
$view = new View("minislideshow_dialog.html");
// Figure out if the user has the necessary privlidges to view the album.
$item = ORM::factory("item", $item_id);
if ($item->is_album()) {
$view->item_id = $item->id;
} else {
$view->item_id = $item->parent_id;
$item = ORM::factory("item", $item_id);
}
access::required("view", $item);
// Generate additional slideshow parameters from database values.
$slideshow_params = "";
if (module::get_var("minislideshow", "shuffle") != "") {
$slideshow_params = $slideshow_params . "&shuffle=" . module::get_var("minislideshow", "shuffle");
}
if (module::get_var("minislideshow", "dropshadow") != "") {
$slideshow_params = $slideshow_params . "&showDropShadow=" . module::get_var("minislideshow", "dropshadow");
}
if (module::get_var("minislideshow", "show_title") != "") {
$slideshow_params = $slideshow_params . "&showTitle=" . module::get_var("minislideshow", "show_title");
}
if (module::get_var("minislideshow", "trans_in_type") != "") {
$slideshow_params = $slideshow_params . "&transInType=" . module::get_var("minislideshow", "trans_in_type");
}
if (module::get_var("minislideshow", "trans_out_type") != "") {
$slideshow_params = $slideshow_params . "&transOutType=" . module::get_var("minislideshow", "trans_out_type");
}
if (module::get_var("minislideshow", "mask") != "") {
$slideshow_params = $slideshow_params . "&" . module::get_var("minislideshow", "mask") . "=true";
}
if (module::get_var("minislideshow", "use_full_image") != "") {
$slideshow_params = $slideshow_params . "&useFull=true";
if (module::get_var("minislideshow", "use_full_image") == "2") {
$slideshow_params = $slideshow_params . "&useResizes=true";
}
}
if (module::get_var("minislideshow", "delay") != "") {
$slideshow_params = $slideshow_params . "&delay=" . module::get_var("minislideshow", "delay");
}
$view->slideshow_params = $slideshow_params;
// Display the slideshow.
print $view;
}
}

View File

@ -0,0 +1,64 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class minislideshow_event_Core {
static function admin_menu($menu, $theme) {
// Add a menu option to the admin screen for configuring the slideshow.
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("minislideshow")
->label(t("MiniSlide Show settings"))
->url(url::site("admin/minislideshow")));
}
static function module_change($changes) {
// Display a warning message if the RSS module is not installed.
if (!module::is_active("rss") || in_array("rss", $changes->deactivate)) {
site_status::warning(
t("The MiniSlide Show module requires the RSS module. " .
"<a href=\"%url\">Activate the RSS module now</a>",
array("url" => url::site("admin/modules"))),
"minislideshow_needs_rss");
} else {
site_status::clear("minislideshow_needs_rss");
}
}
static function album_menu($menu, $theme) {
// Add an option to access the slideshow from the album view.
$menu
->append(Menu::factory("link")
->id("minislideshow")
->label(t("View MiniSlide Show"))
->url(url::site("minislideshow/showslideshow/" . $theme->item()))
->css_class("gDialogLink")
->css_id("gMiniSlideshowLink"));
}
static function photo_menu($menu, $theme) {
// Add an option to access the slideshow from the photo view.
$menu
->append(Menu::factory("link")
->id("minislideshow")
->label(t("View MiniSlide Show"))
->url(url::site("minislideshow/showslideshow/" . $theme->item()))
->css_class("gDialogLink")
->css_id("gMiniSlideshowLink"));
}
}

View File

@ -0,0 +1,32 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class minislideshow_installer {
static function install() {
module::set_version("minislideshow", 1);
}
static function deactivate() {
site_status::clear("minislideshow_needs_rss");
}
static function uninstall() {
module::delete("minislideshow");
}
}

View File

@ -0,0 +1,3 @@
name = "MiniSlide Show"
description = "Display MiniSlide Show on your Gallery."
version = 1

View File

@ -0,0 +1,5 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gMinislideshowAdmin">
<h2> <?= t("MiniSlide Show Settings") ?> </h2>
<?= $minislideshow_form ?>
</div>

View File

@ -0,0 +1,18 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<style>
input[type="text"] {
width: 95%;
}
</style>
<h1 style="display: none;"><?= t("MiniSlide Show") ?></h1>
<div id="gMiniSlideshow">
<embed src="<?= module::get_var("minislideshow", "slideshow_url") ?>" width="485" height="300"
align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash" name="minislide" wmode="transparent"
allowFullscreen="true" allowScriptAccess="always" quality="high"
flashvars="xmlUrl=<?= url::site("rss/feed/gallery/album/" . $item_id, "http") ?><?=$slideshow_params ?>"></embed>
<table><tr>
<td>Embed:</td>
<td><input type="text" onclick="this.focus(); this.select();" value="<embed src=&quot;<?= module::get_var("minislideshow", "slideshow_url") ?>&quot; width=&quot;485&quot; height=&quot;300&quot; align=&quot;middle&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; type=&quot;application/x-shockwave-flash&quot; name=&quot;minislide&quot; wmode=&quot;transparent&quot; allowFullscreen=&quot;true&quot; allowScriptAccess=&quot;always&quot; quality=&quot;high&quot; flashvars=&quot;xmlUrl=<?= url::site("rss/feed/gallery/album/" . $item_id, "http") ?><?=$slideshow_params ?>&quot;></embed>" readonly></td>
</tr></table>
</div>

View File

@ -0,0 +1,27 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
$config["Cache"] = array(
"SerializerPath" => TMPPATH
);
$config["Attr"] = array(
"EnableID" => true
);

View File

@ -0,0 +1,36 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class purifier {
private static $_purifier = null;
static function purify($dirty_html) {
if (!isset(self::$_purifier)) {
require_once(MODPATH . "purifier/lib/HTMLPurifier/HTMLPurifier.auto.php");
$config = HTMLPurifier_Config::createDefault();
foreach (Kohana::config("purifier") as $category => $key_value) {
foreach ($key_value as $key => $value) {
$config->set("$category.$key", $value);
}
}
self::$_purifier = new HTMLPurifier($config);
}
return self::$_purifier->purify($dirty_html);
}
}

View File

@ -0,0 +1,23 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class purifier_installer {
static function install() {
module::set_version("purifier", 1);
}
}

View File

@ -0,0 +1,11 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* This is a stub include that automatically configures the include path.
*/
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
require_once 'HTMLPurifier/Bootstrap.php';
require_once 'HTMLPurifier.autoload.php';
// vim: et sw=4 sts=4

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* Convenience file that registers autoload handler for HTML Purifier.
*/
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
// We need unregister for our pre-registering functionality
HTMLPurifier_Bootstrap::registerAutoload();
if (function_exists('__autoload')) {
// Be polite and ensure that userland autoload gets retained
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class) {
return HTMLPurifier_Bootstrap::autoload($class);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,23 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* Defines a function wrapper for HTML Purifier for quick use.
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
*/
/**
* Purify HTML.
* @param $html String HTML to purify
* @param $config Configuration to use, can be any value accepted by
* HTMLPurifier_Config::create()
*/
function HTMLPurifier($html, $config = null) {
static $purifier = false;
if (!$purifier) {
$purifier = new HTMLPurifier();
}
return $purifier->purify($html, $config);
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,208 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* This file was auto-generated by generate-includes.php and includes all of
* the core files required by HTML Purifier. Use this if performance is a
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.0.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
* because 'require' not 'require_once' is used.
*
* @warning
* This file requires that the include path contains the HTML Purifier
* library directory; this is not auto-set.
*/
require 'HTMLPurifier.php';
require 'HTMLPurifier/AttrCollections.php';
require 'HTMLPurifier/AttrDef.php';
require 'HTMLPurifier/AttrTransform.php';
require 'HTMLPurifier/AttrTypes.php';
require 'HTMLPurifier/AttrValidator.php';
require 'HTMLPurifier/Bootstrap.php';
require 'HTMLPurifier/Definition.php';
require 'HTMLPurifier/CSSDefinition.php';
require 'HTMLPurifier/ChildDef.php';
require 'HTMLPurifier/Config.php';
require 'HTMLPurifier/ConfigSchema.php';
require 'HTMLPurifier/ContentSets.php';
require 'HTMLPurifier/Context.php';
require 'HTMLPurifier/DefinitionCache.php';
require 'HTMLPurifier/DefinitionCacheFactory.php';
require 'HTMLPurifier/Doctype.php';
require 'HTMLPurifier/DoctypeRegistry.php';
require 'HTMLPurifier/ElementDef.php';
require 'HTMLPurifier/Encoder.php';
require 'HTMLPurifier/EntityLookup.php';
require 'HTMLPurifier/EntityParser.php';
require 'HTMLPurifier/ErrorCollector.php';
require 'HTMLPurifier/ErrorStruct.php';
require 'HTMLPurifier/Exception.php';
require 'HTMLPurifier/Filter.php';
require 'HTMLPurifier/Generator.php';
require 'HTMLPurifier/HTMLDefinition.php';
require 'HTMLPurifier/HTMLModule.php';
require 'HTMLPurifier/HTMLModuleManager.php';
require 'HTMLPurifier/IDAccumulator.php';
require 'HTMLPurifier/Injector.php';
require 'HTMLPurifier/Language.php';
require 'HTMLPurifier/LanguageFactory.php';
require 'HTMLPurifier/Length.php';
require 'HTMLPurifier/Lexer.php';
require 'HTMLPurifier/PercentEncoder.php';
require 'HTMLPurifier/PropertyList.php';
require 'HTMLPurifier/PropertyListIterator.php';
require 'HTMLPurifier/Strategy.php';
require 'HTMLPurifier/StringHash.php';
require 'HTMLPurifier/StringHashParser.php';
require 'HTMLPurifier/TagTransform.php';
require 'HTMLPurifier/Token.php';
require 'HTMLPurifier/TokenFactory.php';
require 'HTMLPurifier/URI.php';
require 'HTMLPurifier/URIDefinition.php';
require 'HTMLPurifier/URIFilter.php';
require 'HTMLPurifier/URIParser.php';
require 'HTMLPurifier/URIScheme.php';
require 'HTMLPurifier/URISchemeRegistry.php';
require 'HTMLPurifier/UnitConverter.php';
require 'HTMLPurifier/VarParser.php';
require 'HTMLPurifier/VarParserException.php';
require 'HTMLPurifier/AttrDef/CSS.php';
require 'HTMLPurifier/AttrDef/Enum.php';
require 'HTMLPurifier/AttrDef/Integer.php';
require 'HTMLPurifier/AttrDef/Lang.php';
require 'HTMLPurifier/AttrDef/Switch.php';
require 'HTMLPurifier/AttrDef/Text.php';
require 'HTMLPurifier/AttrDef/URI.php';
require 'HTMLPurifier/AttrDef/CSS/Number.php';
require 'HTMLPurifier/AttrDef/CSS/AlphaValue.php';
require 'HTMLPurifier/AttrDef/CSS/Background.php';
require 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
require 'HTMLPurifier/AttrDef/CSS/Border.php';
require 'HTMLPurifier/AttrDef/CSS/Color.php';
require 'HTMLPurifier/AttrDef/CSS/Composite.php';
require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
require 'HTMLPurifier/AttrDef/CSS/Font.php';
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require 'HTMLPurifier/AttrDef/HTML/Class.php';
require 'HTMLPurifier/AttrDef/HTML/Color.php';
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require 'HTMLPurifier/AttrDef/HTML/ID.php';
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
require 'HTMLPurifier/AttrDef/HTML/Length.php';
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
require 'HTMLPurifier/AttrDef/URI/Email.php';
require 'HTMLPurifier/AttrDef/URI/Host.php';
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
require 'HTMLPurifier/AttrTransform/Background.php';
require 'HTMLPurifier/AttrTransform/BdoDir.php';
require 'HTMLPurifier/AttrTransform/BgColor.php';
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
require 'HTMLPurifier/AttrTransform/Border.php';
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
require 'HTMLPurifier/AttrTransform/Input.php';
require 'HTMLPurifier/AttrTransform/Lang.php';
require 'HTMLPurifier/AttrTransform/Length.php';
require 'HTMLPurifier/AttrTransform/Name.php';
require 'HTMLPurifier/AttrTransform/NameSync.php';
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
require 'HTMLPurifier/AttrTransform/SafeObject.php';
require 'HTMLPurifier/AttrTransform/SafeParam.php';
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
require 'HTMLPurifier/AttrTransform/Textarea.php';
require 'HTMLPurifier/ChildDef/Chameleon.php';
require 'HTMLPurifier/ChildDef/Custom.php';
require 'HTMLPurifier/ChildDef/Empty.php';
require 'HTMLPurifier/ChildDef/Required.php';
require 'HTMLPurifier/ChildDef/Optional.php';
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
require 'HTMLPurifier/ChildDef/Table.php';
require 'HTMLPurifier/DefinitionCache/Decorator.php';
require 'HTMLPurifier/DefinitionCache/Null.php';
require 'HTMLPurifier/DefinitionCache/Serializer.php';
require 'HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
require 'HTMLPurifier/HTMLModule/Bdo.php';
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Edit.php';
require 'HTMLPurifier/HTMLModule/Forms.php';
require 'HTMLPurifier/HTMLModule/Hypertext.php';
require 'HTMLPurifier/HTMLModule/Image.php';
require 'HTMLPurifier/HTMLModule/Legacy.php';
require 'HTMLPurifier/HTMLModule/List.php';
require 'HTMLPurifier/HTMLModule/Name.php';
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Object.php';
require 'HTMLPurifier/HTMLModule/Presentation.php';
require 'HTMLPurifier/HTMLModule/Proprietary.php';
require 'HTMLPurifier/HTMLModule/Ruby.php';
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
require 'HTMLPurifier/HTMLModule/SafeObject.php';
require 'HTMLPurifier/HTMLModule/Scripting.php';
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
require 'HTMLPurifier/HTMLModule/Tables.php';
require 'HTMLPurifier/HTMLModule/Target.php';
require 'HTMLPurifier/HTMLModule/Text.php';
require 'HTMLPurifier/HTMLModule/Tidy.php';
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
require 'HTMLPurifier/Injector/AutoParagraph.php';
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
require 'HTMLPurifier/Injector/Linkify.php';
require 'HTMLPurifier/Injector/PurifierLinkify.php';
require 'HTMLPurifier/Injector/RemoveEmpty.php';
require 'HTMLPurifier/Injector/SafeObject.php';
require 'HTMLPurifier/Lexer/DOMLex.php';
require 'HTMLPurifier/Lexer/DirectLex.php';
require 'HTMLPurifier/Strategy/Composite.php';
require 'HTMLPurifier/Strategy/Core.php';
require 'HTMLPurifier/Strategy/FixNesting.php';
require 'HTMLPurifier/Strategy/MakeWellFormed.php';
require 'HTMLPurifier/Strategy/RemoveForeignElements.php';
require 'HTMLPurifier/Strategy/ValidateAttributes.php';
require 'HTMLPurifier/TagTransform/Font.php';
require 'HTMLPurifier/TagTransform/Simple.php';
require 'HTMLPurifier/Token/Comment.php';
require 'HTMLPurifier/Token/Tag.php';
require 'HTMLPurifier/Token/Empty.php';
require 'HTMLPurifier/Token/End.php';
require 'HTMLPurifier/Token/Start.php';
require 'HTMLPurifier/Token/Text.php';
require 'HTMLPurifier/URIFilter/DisableExternal.php';
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
require 'HTMLPurifier/URIFilter/Munge.php';
require 'HTMLPurifier/URIScheme/ftp.php';
require 'HTMLPurifier/URIScheme/http.php';
require 'HTMLPurifier/URIScheme/https.php';
require 'HTMLPurifier/URIScheme/mailto.php';
require 'HTMLPurifier/URIScheme/news.php';
require 'HTMLPurifier/URIScheme/nntp.php';
require 'HTMLPurifier/VarParser/Flexible.php';
require 'HTMLPurifier/VarParser/Native.php';

View File

@ -0,0 +1,30 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* Emulation layer for code that used kses(), substituting in HTML Purifier.
*/
require_once dirname(__FILE__) . '/HTMLPurifier.auto.php';
function kses($string, $allowed_html, $allowed_protocols = null) {
$config = HTMLPurifier_Config::createDefault();
$allowed_elements = array();
$allowed_attributes = array();
foreach ($allowed_html as $element => $attributes) {
$allowed_elements[$element] = true;
foreach ($attributes as $attribute => $x) {
$allowed_attributes["$element.$attribute"] = true;
}
}
$config->set('HTML.AllowedElements', $allowed_elements);
$config->set('HTML.AllowedAttributes', $allowed_attributes);
$allowed_schemes = array();
if ($allowed_protocols !== null) {
$config->set('URI.AllowedSchemes', $allowed_protocols);
}
$purifier = new HTMLPurifier($config);
return $purifier->purify($string);
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,11 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* Convenience stub file that adds HTML Purifier's library file to the path
* without any other side-effects.
*/
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
// vim: et sw=4 sts=4

View File

@ -0,0 +1,237 @@
<?php defined("SYSPATH") or die("No direct script access.");
/*! @mainpage
*
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
* HTML and rigorously test, validate and filter it into a version that
* is safe for output onto webpages. It achieves this by:
*
* -# Lexing (parsing into tokens) the document,
* -# Executing various strategies on the tokens:
* -# Removing all elements not in the whitelist,
* -# Making the tokens well-formed,
* -# Fixing the nesting of the nodes, and
* -# Validating attributes of the nodes; and
* -# Generating HTML from the purified tokens.
*
* However, most users will only need to interface with the HTMLPurifier
* and HTMLPurifier_Config.
*/
/*
HTML Purifier 4.0.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
*
* @note There are several points in which configuration can be specified
* for HTML Purifier. The precedence of these (from lowest to
* highest) is as follows:
* -# Instance: new HTMLPurifier($config)
* -# Invocation: purify($html, $config)
* These configurations are entirely independent of each other and
* are *not* merged (this behavior may change in the future).
*
* @todo We need an easier way to inject strategies using the configuration
* object.
*/
class HTMLPurifier
{
/** Version of HTML Purifier */
public $version = '4.0.0';
/** Constant with version of HTML Purifier */
const VERSION = '4.0.0';
/** Global configuration object */
public $config;
/** Array of extra HTMLPurifier_Filter objects to run on HTML, for backwards compatibility */
private $filters = array();
/** Single instance of HTML Purifier */
private static $instance;
protected $strategy, $generator;
/**
* Resultant HTMLPurifier_Context of last run purification. Is an array
* of contexts if the last called method was purifyArray().
*/
public $context;
/**
* Initializes the purifier.
* @param $config Optional HTMLPurifier_Config object for all instances of
* the purifier, if omitted, a default configuration is
* supplied (which can be overridden on a per-use basis).
* The parameter can also be any type that
* HTMLPurifier_Config::create() supports.
*/
public function __construct($config = null) {
$this->config = HTMLPurifier_Config::create($config);
$this->strategy = new HTMLPurifier_Strategy_Core();
}
/**
* Adds a filter to process the output. First come first serve
* @param $filter HTMLPurifier_Filter object
*/
public function addFilter($filter) {
trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
$this->filters[] = $filter;
}
/**
* Filters an HTML snippet/document to be XSS-free and standards-compliant.
*
* @param $html String of HTML to purify
* @param $config HTMLPurifier_Config object for this operation, if omitted,
* defaults to the config object specified during this
* object's construction. The parameter can also be any type
* that HTMLPurifier_Config::create() supports.
* @return Purified HTML
*/
public function purify($html, $config = null) {
// :TODO: make the config merge in, instead of replace
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
// implementation is partially environment dependant, partially
// configuration dependant
$lexer = HTMLPurifier_Lexer::create($config);
$context = new HTMLPurifier_Context();
// setup HTML generator
$this->generator = new HTMLPurifier_Generator($config, $context);
$context->register('Generator', $this->generator);
// set up global context variables
if ($config->get('Core.CollectErrors')) {
// may get moved out if other facilities use it
$language_factory = HTMLPurifier_LanguageFactory::instance();
$language = $language_factory->create($config, $context);
$context->register('Locale', $language);
$error_collector = new HTMLPurifier_ErrorCollector($context);
$context->register('ErrorCollector', $error_collector);
}
// setup id_accumulator context, necessary due to the fact that
// AttrValidator can be called from many places
$id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
$context->register('IDAccumulator', $id_accumulator);
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
// setup filters
$filter_flags = $config->getBatch('Filter');
$custom_filters = $filter_flags['Custom'];
unset($filter_flags['Custom']);
$filters = array();
foreach ($filter_flags as $filter => $flag) {
if (!$flag) continue;
if (strpos($filter, '.') !== false) continue;
$class = "HTMLPurifier_Filter_$filter";
$filters[] = new $class;
}
foreach ($custom_filters as $filter) {
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
$filters[] = $filter;
}
$filters = array_merge($filters, $this->filters);
// maybe prepare(), but later
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
$html = $filters[$i]->preFilter($html, $config, $context);
}
// purified HTML
$html =
$this->generator->generateFromTokens(
// list of tokens
$this->strategy->execute(
// list of un-purified tokens
$lexer->tokenizeHTML(
// un-purified HTML
$html, $config, $context
),
$config, $context
)
);
for ($i = $filter_size - 1; $i >= 0; $i--) {
$html = $filters[$i]->postFilter($html, $config, $context);
}
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
$this->context =& $context;
return $html;
}
/**
* Filters an array of HTML snippets
* @param $config Optional HTMLPurifier_Config object for this operation.
* See HTMLPurifier::purify() for more details.
* @return Array of purified HTML
*/
public function purifyArray($array_of_html, $config = null) {
$context_array = array();
foreach ($array_of_html as $key => $html) {
$array_of_html[$key] = $this->purify($html, $config);
$context_array[$key] = $this->context;
}
$this->context = $context_array;
return $array_of_html;
}
/**
* Singleton for enforcing just one HTML Purifier in your system
* @param $prototype Optional prototype HTMLPurifier instance to
* overload singleton with, or HTMLPurifier_Config
* instance to configure the generated version with.
*/
public static function instance($prototype = null) {
if (!self::$instance || $prototype) {
if ($prototype instanceof HTMLPurifier) {
self::$instance = $prototype;
} elseif ($prototype) {
self::$instance = new HTMLPurifier($prototype);
} else {
self::$instance = new HTMLPurifier();
}
}
return self::$instance;
}
/**
* @note Backwards compatibility, see instance()
*/
public static function getInstance($prototype = null) {
return HTMLPurifier::instance($prototype);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,202 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @file
* This file was auto-generated by generate-includes.php and includes all of
* the core files required by HTML Purifier. This is a convenience stub that
* includes all files using dirname(__FILE__) and require_once. PLEASE DO NOT
* EDIT THIS FILE, changes will be overwritten the next time the script is run.
*
* Changes to include_path are not necessary.
*/
$__dir = dirname(__FILE__);
require_once $__dir . '/HTMLPurifier.php';
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
require_once $__dir . '/HTMLPurifier/AttrDef.php';
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
require_once $__dir . '/HTMLPurifier/AttrTypes.php';
require_once $__dir . '/HTMLPurifier/AttrValidator.php';
require_once $__dir . '/HTMLPurifier/Bootstrap.php';
require_once $__dir . '/HTMLPurifier/Definition.php';
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
require_once $__dir . '/HTMLPurifier/ChildDef.php';
require_once $__dir . '/HTMLPurifier/Config.php';
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
require_once $__dir . '/HTMLPurifier/ContentSets.php';
require_once $__dir . '/HTMLPurifier/Context.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache.php';
require_once $__dir . '/HTMLPurifier/DefinitionCacheFactory.php';
require_once $__dir . '/HTMLPurifier/Doctype.php';
require_once $__dir . '/HTMLPurifier/DoctypeRegistry.php';
require_once $__dir . '/HTMLPurifier/ElementDef.php';
require_once $__dir . '/HTMLPurifier/Encoder.php';
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
require_once $__dir . '/HTMLPurifier/EntityParser.php';
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
require_once $__dir . '/HTMLPurifier/Exception.php';
require_once $__dir . '/HTMLPurifier/Filter.php';
require_once $__dir . '/HTMLPurifier/Generator.php';
require_once $__dir . '/HTMLPurifier/HTMLDefinition.php';
require_once $__dir . '/HTMLPurifier/HTMLModule.php';
require_once $__dir . '/HTMLPurifier/HTMLModuleManager.php';
require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
require_once $__dir . '/HTMLPurifier/Injector.php';
require_once $__dir . '/HTMLPurifier/Language.php';
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
require_once $__dir . '/HTMLPurifier/Length.php';
require_once $__dir . '/HTMLPurifier/Lexer.php';
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
require_once $__dir . '/HTMLPurifier/PropertyList.php';
require_once $__dir . '/HTMLPurifier/PropertyListIterator.php';
require_once $__dir . '/HTMLPurifier/Strategy.php';
require_once $__dir . '/HTMLPurifier/StringHash.php';
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
require_once $__dir . '/HTMLPurifier/TagTransform.php';
require_once $__dir . '/HTMLPurifier/Token.php';
require_once $__dir . '/HTMLPurifier/TokenFactory.php';
require_once $__dir . '/HTMLPurifier/URI.php';
require_once $__dir . '/HTMLPurifier/URIDefinition.php';
require_once $__dir . '/HTMLPurifier/URIFilter.php';
require_once $__dir . '/HTMLPurifier/URIParser.php';
require_once $__dir . '/HTMLPurifier/URIScheme.php';
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
require_once $__dir . '/HTMLPurifier/VarParser.php';
require_once $__dir . '/HTMLPurifier/VarParserException.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Switch.php';
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/AlphaValue.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Background.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Background.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Forms.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeEmbed.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeObject.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
require_once $__dir . '/HTMLPurifier/Strategy/MakeWellFormed.php';
require_once $__dir . '/HTMLPurifier/Strategy/RemoveForeignElements.php';
require_once $__dir . '/HTMLPurifier/Strategy/ValidateAttributes.php';
require_once $__dir . '/HTMLPurifier/TagTransform/Font.php';
require_once $__dir . '/HTMLPurifier/TagTransform/Simple.php';
require_once $__dir . '/HTMLPurifier/Token/Comment.php';
require_once $__dir . '/HTMLPurifier/Token/Tag.php';
require_once $__dir . '/HTMLPurifier/Token/Empty.php';
require_once $__dir . '/HTMLPurifier/Token/End.php';
require_once $__dir . '/HTMLPurifier/Token/Start.php';
require_once $__dir . '/HTMLPurifier/Token/Text.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';

View File

@ -0,0 +1,128 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Defines common attribute collections that modules reference
*/
class HTMLPurifier_AttrCollections
{
/**
* Associative array of attribute collections, indexed by name
*/
public $info = array();
/**
* Performs all expansions on internal data for use by other inclusions
* It also collects all attribute collection extensions from
* modules
* @param $attr_types HTMLPurifier_AttrTypes instance
* @param $modules Hash array of HTMLPurifier_HTMLModule members
*/
public function __construct($attr_types, $modules) {
// load extensions from the modules
foreach ($modules as $module) {
foreach ($module->attr_collections as $coll_i => $coll) {
if (!isset($this->info[$coll_i])) {
$this->info[$coll_i] = array();
}
foreach ($coll as $attr_i => $attr) {
if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
// merge in includes
$this->info[$coll_i][$attr_i] = array_merge(
$this->info[$coll_i][$attr_i], $attr);
continue;
}
$this->info[$coll_i][$attr_i] = $attr;
}
}
}
// perform internal expansions and inclusions
foreach ($this->info as $name => $attr) {
// merge attribute collections that include others
$this->performInclusions($this->info[$name]);
// replace string identifiers with actual attribute objects
$this->expandIdentifiers($this->info[$name], $attr_types);
}
}
/**
* Takes a reference to an attribute associative array and performs
* all inclusions specified by the zero index.
* @param &$attr Reference to attribute array
*/
public function performInclusions(&$attr) {
if (!isset($attr[0])) return;
$merge = $attr[0];
$seen = array(); // recursion guard
// loop through all the inclusions
for ($i = 0; isset($merge[$i]); $i++) {
if (isset($seen[$merge[$i]])) continue;
$seen[$merge[$i]] = true;
// foreach attribute of the inclusion, copy it over
if (!isset($this->info[$merge[$i]])) continue;
foreach ($this->info[$merge[$i]] as $key => $value) {
if (isset($attr[$key])) continue; // also catches more inclusions
$attr[$key] = $value;
}
if (isset($this->info[$merge[$i]][0])) {
// recursion
$merge = array_merge($merge, $this->info[$merge[$i]][0]);
}
}
unset($attr[0]);
}
/**
* Expands all string identifiers in an attribute array by replacing
* them with the appropriate values inside HTMLPurifier_AttrTypes
* @param &$attr Reference to attribute array
* @param $attr_types HTMLPurifier_AttrTypes instance
*/
public function expandIdentifiers(&$attr, $attr_types) {
// because foreach will process new elements we add, make sure we
// skip duplicates
$processed = array();
foreach ($attr as $def_i => $def) {
// skip inclusions
if ($def_i === 0) continue;
if (isset($processed[$def_i])) continue;
// determine whether or not attribute is required
if ($required = (strpos($def_i, '*') !== false)) {
// rename the definition
unset($attr[$def_i]);
$def_i = trim($def_i, '*');
$attr[$def_i] = $def;
}
$processed[$def_i] = true;
// if we've already got a literal object, move on
if (is_object($def)) {
// preserve previous required
$attr[$def_i]->required = ($required || $attr[$def_i]->required);
continue;
}
if ($def === false) {
unset($attr[$def_i]);
continue;
}
if ($t = $attr_types->get($def)) {
$attr[$def_i] = $t;
$attr[$def_i]->required = $required;
} else {
unset($attr[$def_i]);
}
}
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,87 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Base class for all validating attribute definitions.
*
* This family of classes forms the core for not only HTML attribute validation,
* but also any sort of string that needs to be validated or cleaned (which
* means CSS properties and composite definitions are defined here too).
* Besides defining (through code) what precisely makes the string valid,
* subclasses are also responsible for cleaning the code if possible.
*/
abstract class HTMLPurifier_AttrDef
{
/**
* Tells us whether or not an HTML attribute is minimized. Has no
* meaning in other contexts.
*/
public $minimized = false;
/**
* Tells us whether or not an HTML attribute is required. Has no
* meaning in other contexts
*/
public $required = false;
/**
* Validates and cleans passed string according to a definition.
*
* @param $string String to be validated and cleaned.
* @param $config Mandatory HTMLPurifier_Config object.
* @param $context Mandatory HTMLPurifier_AttrContext object.
*/
abstract public function validate($string, $config, $context);
/**
* Convenience method that parses a string as if it were CDATA.
*
* This method process a string in the manner specified at
* <http://www.w3.org/TR/html4/types.html#h-6.2> by removing
* leading and trailing whitespace, ignoring line feeds, and replacing
* carriage returns and tabs with spaces. While most useful for HTML
* attributes specified as CDATA, it can also be applied to most CSS
* values.
*
* @note This method is not entirely standards compliant, as trim() removes
* more types of whitespace than specified in the spec. In practice,
* this is rarely a problem, as those extra characters usually have
* already been removed by HTMLPurifier_Encoder.
*
* @warning This processing is inconsistent with XML's whitespace handling
* as specified by section 3.3.3 and referenced XHTML 1.0 section
* 4.7. However, note that we are NOT necessarily
* parsing XML, thus, this behavior may still be correct. We
* assume that newlines have been normalized.
*/
public function parseCDATA($string) {
$string = trim($string);
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
return $string;
}
/**
* Factory method for creating this class from a string.
* @param $string String construction info
* @return Created AttrDef object corresponding to $string
*/
public function make($string) {
// default implementation, return a flyweight of this object.
// If $string has an effect on the returned object (i.e. you
// need to overload this method), it is best
// to clone or instantiate new copies. (Instantiation is safer.)
return $this;
}
/**
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
* properly. THIS IS A HACK!
*/
protected function mungeRgb($string) {
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,87 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the HTML attribute style, otherwise known as CSS.
* @note We don't implement the whole CSS specification, so it might be
* difficult to reuse this component in the context of validating
* actual stylesheet declarations.
* @note If we were really serious about validating the CSS, we would
* tokenize the styles and then parse the tokens. Obviously, we
* are not doing that. Doing that could seriously harm performance,
* but would make these components a lot more viable for a CSS
* filtering solution.
*/
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
{
public function validate($css, $config, $context) {
$css = $this->parseCDATA($css);
$definition = $config->getCSSDefinition();
// we're going to break the spec and explode by semicolons.
// This is because semicolon rarely appears in escaped form
// Doing this is generally flaky but fast
// IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI
// for details
$declarations = explode(';', $css);
$propvalues = array();
/**
* Name of the current CSS property being validated.
*/
$property = false;
$context->register('CurrentCSSProperty', $property);
foreach ($declarations as $declaration) {
if (!$declaration) continue;
if (!strpos($declaration, ':')) continue;
list($property, $value) = explode(':', $declaration, 2);
$property = trim($property);
$value = trim($value);
$ok = false;
do {
if (isset($definition->info[$property])) {
$ok = true;
break;
}
if (ctype_lower($property)) break;
$property = strtolower($property);
if (isset($definition->info[$property])) {
$ok = true;
break;
}
} while(0);
if (!$ok) continue;
// inefficient call, since the validator will do this again
if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $definition->info[$property]->validate(
$value, $config, $context );
} else {
$result = 'inherit';
}
if ($result === false) continue;
$propvalues[$property] = $result;
}
$context->destroy('CurrentCSSProperty');
// procedure does not write the new CSS simultaneously, so it's
// slightly inefficient, but it's the only way of getting rid of
// duplicates. Perhaps config to optimize it, but not now.
$new_declarations = '';
foreach ($propvalues as $prop => $value) {
$new_declarations .= "$prop:$value;";
}
return $new_declarations ? $new_declarations : false;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
{
public function __construct() {
parent::__construct(false); // opacity is non-negative, but we will clamp it
}
public function validate($number, $config, $context) {
$result = parent::validate($number, $config, $context);
if ($result === false) return $result;
$float = (float) $result;
if ($float < 0.0) $result = '0';
if ($float > 1.0) $result = '1';
return $result;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,87 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates shorthand CSS property background.
* @warning Does not support url tokens that have internal spaces.
*/
class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
{
/**
* Local copy of component validators.
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
*/
protected $info;
public function __construct($config) {
$def = $config->getCSSDefinition();
$this->info['background-color'] = $def->info['background-color'];
$this->info['background-image'] = $def->info['background-image'];
$this->info['background-repeat'] = $def->info['background-repeat'];
$this->info['background-attachment'] = $def->info['background-attachment'];
$this->info['background-position'] = $def->info['background-position'];
}
public function validate($string, $config, $context) {
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') return false;
// munge rgb() decl if necessary
$string = $this->mungeRgb($string);
// assumes URI doesn't have spaces in it
$bits = explode(' ', strtolower($string)); // bits to process
$caught = array();
$caught['color'] = false;
$caught['image'] = false;
$caught['repeat'] = false;
$caught['attachment'] = false;
$caught['position'] = false;
$i = 0; // number of catches
$none = false;
foreach ($bits as $bit) {
if ($bit === '') continue;
foreach ($caught as $key => $status) {
if ($key != 'position') {
if ($status !== false) continue;
$r = $this->info['background-' . $key]->validate($bit, $config, $context);
} else {
$r = $bit;
}
if ($r === false) continue;
if ($key == 'position') {
if ($caught[$key] === false) $caught[$key] = '';
$caught[$key] .= $r . ' ';
} else {
$caught[$key] = $r;
}
$i++;
break;
}
}
if (!$i) return false;
if ($caught['position'] !== false) {
$caught['position'] = $this->info['background-position']->
validate($caught['position'], $config, $context);
}
$ret = array();
foreach ($caught as $value) {
if ($value === false) continue;
$ret[] = $value;
}
if (empty($ret)) return false;
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,126 @@
<?php defined("SYSPATH") or die("No direct script access.");
/* W3C says:
[ // adjective and number must be in correct order, even if
// you could switch them without introducing ambiguity.
// some browsers support that syntax
[
<percentage> | <length> | left | center | right
]
[
<percentage> | <length> | top | center | bottom
]?
] |
[ // this signifies that the vertical and horizontal adjectives
// can be arbitrarily ordered, however, there can only be two,
// one of each, or none at all
[
left | center | right
] ||
[
top | center | bottom
]
]
top, left = 0%
center, (none) = 50%
bottom, right = 100%
*/
/* QuirksMode says:
keyword + length/percentage must be ordered correctly, as per W3C
Internet Explorer and Opera, however, support arbitrary ordering. We
should fix it up.
Minor issue though, not strictly necessary.
*/
// control freaks may appreciate the ability to convert these to
// percentages or something, but it's not necessary
/**
* Validates the value of background-position.
*/
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
{
protected $length;
protected $percentage;
public function __construct() {
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
}
public function validate($string, $config, $context) {
$string = $this->parseCDATA($string);
$bits = explode(' ', $string);
$keywords = array();
$keywords['h'] = false; // left, right
$keywords['v'] = false; // top, bottom
$keywords['c'] = false; // center
$measures = array();
$i = 0;
$lookup = array(
'top' => 'v',
'bottom' => 'v',
'left' => 'h',
'right' => 'h',
'center' => 'c'
);
foreach ($bits as $bit) {
if ($bit === '') continue;
// test for keyword
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
if (isset($lookup[$lbit])) {
$status = $lookup[$lbit];
$keywords[$status] = $lbit;
$i++;
}
// test for length
$r = $this->length->validate($bit, $config, $context);
if ($r !== false) {
$measures[] = $r;
$i++;
}
// test for percentage
$r = $this->percentage->validate($bit, $config, $context);
if ($r !== false) {
$measures[] = $r;
$i++;
}
}
if (!$i) return false; // no valid values were caught
$ret = array();
// first keyword
if ($keywords['h']) $ret[] = $keywords['h'];
elseif (count($measures)) $ret[] = array_shift($measures);
elseif ($keywords['c']) {
$ret[] = $keywords['c'];
$keywords['c'] = false; // prevent re-use: center = center center
}
if ($keywords['v']) $ret[] = $keywords['v'];
elseif (count($measures)) $ret[] = array_shift($measures);
elseif ($keywords['c']) $ret[] = $keywords['c'];
if (empty($ret)) return false;
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,43 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the border property as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
{
/**
* Local copy of properties this property is shorthand for.
*/
protected $info = array();
public function __construct($config) {
$def = $config->getCSSDefinition();
$this->info['border-width'] = $def->info['border-width'];
$this->info['border-style'] = $def->info['border-style'];
$this->info['border-top-color'] = $def->info['border-top-color'];
}
public function validate($string, $config, $context) {
$string = $this->parseCDATA($string);
$string = $this->mungeRgb($string);
$bits = explode(' ', $string);
$done = array(); // segments we've finished
$ret = ''; // return value
foreach ($bits as $bit) {
foreach ($this->info as $propname => $validator) {
if (isset($done[$propname])) continue;
$r = $validator->validate($bit, $config, $context);
if ($r !== false) {
$ret .= $r . ' ';
$done[$propname] = true;
break;
}
}
}
return rtrim($ret);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,78 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates Color as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
{
public function validate($color, $config, $context) {
static $colors = null;
if ($colors === null) $colors = $config->get('Core.ColorKeywords');
$color = trim($color);
if ($color === '') return false;
$lower = strtolower($color);
if (isset($colors[$lower])) return $colors[$lower];
if (strpos($color, 'rgb(') !== false) {
// rgb literal handling
$length = strlen($color);
if (strpos($color, ')') !== $length - 1) return false;
$triad = substr($color, 4, $length - 4 - 1);
$parts = explode(',', $triad);
if (count($parts) !== 3) return false;
$type = false; // to ensure that they're all the same type
$new_parts = array();
foreach ($parts as $part) {
$part = trim($part);
if ($part === '') return false;
$length = strlen($part);
if ($part[$length - 1] === '%') {
// handle percents
if (!$type) {
$type = 'percentage';
} elseif ($type !== 'percentage') {
return false;
}
$num = (float) substr($part, 0, $length - 1);
if ($num < 0) $num = 0;
if ($num > 100) $num = 100;
$new_parts[] = "$num%";
} else {
// handle integers
if (!$type) {
$type = 'integer';
} elseif ($type !== 'integer') {
return false;
}
$num = (int) $part;
if ($num < 0) $num = 0;
if ($num > 255) $num = 255;
$new_parts[] = (string) $num;
}
}
$new_triad = implode(',', $new_parts);
$color = "rgb($new_triad)";
} else {
// hexadecimal handling
if ($color[0] === '#') {
$hex = substr($color, 1);
} else {
$hex = $color;
$color = '#' . $color;
}
$length = strlen($hex);
if ($length !== 3 && $length !== 6) return false;
if (!ctype_xdigit($hex)) return false;
}
return $color;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,38 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Allows multiple validators to attempt to validate attribute.
*
* Composite is just what it sounds like: a composite of many validators.
* This means that multiple HTMLPurifier_AttrDef objects will have a whack
* at the string. If one of them passes, that's what is returned. This is
* especially useful for CSS values, which often are a choice between
* an enumerated set of predefined values or a flexible data type.
*/
class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
{
/**
* List of HTMLPurifier_AttrDef objects that may process strings
* @todo Make protected
*/
public $defs;
/**
* @param $defs List of HTMLPurifier_AttrDef objects
*/
public function __construct($defs) {
$this->defs = $defs;
}
public function validate($string, $config, $context) {
foreach ($this->defs as $i => $def) {
$result = $this->defs[$i]->validate($string, $config, $context);
if ($result !== false) return $result;
}
return false;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,28 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Decorator which enables CSS properties to be disabled for specific elements.
*/
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
{
public $def, $element;
/**
* @param $def Definition to wrap
* @param $element Element to deny
*/
public function __construct($def, $element) {
$this->def = $def;
$this->element = $element;
}
/**
* Checks if CurrentToken is set and equal to $this->element
*/
public function validate($string, $config, $context) {
$token = $context->get('CurrentToken', true);
if ($token && $token->name == $this->element) return false;
return $this->def->validate($string, $config, $context);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,54 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Microsoft's proprietary filter: CSS property
* @note Currently supports the alpha filter. In the future, this will
* probably need an extensible framework
*/
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
{
protected $intValidator;
public function __construct() {
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
}
public function validate($value, $config, $context) {
$value = $this->parseCDATA($value);
if ($value === 'none') return $value;
// if we looped this we could support multiple filters
$function_length = strcspn($value, '(');
$function = trim(substr($value, 0, $function_length));
if ($function !== 'alpha' &&
$function !== 'Alpha' &&
$function !== 'progid:DXImageTransform.Microsoft.Alpha'
) return false;
$cursor = $function_length + 1;
$parameters_length = strcspn($value, ')', $cursor);
$parameters = substr($value, $cursor, $parameters_length);
$params = explode(',', $parameters);
$ret_params = array();
$lookup = array();
foreach ($params as $param) {
list($key, $value) = explode('=', $param);
$key = trim($key);
$value = trim($value);
if (isset($lookup[$key])) continue;
if ($key !== 'opacity') continue;
$value = $this->intValidator->validate($value, $config, $context);
if ($value === false) continue;
$int = (int) $value;
if ($int > 100) $value = '100';
if ($int < 0) $value = '0';
$ret_params[] = "$key=$value";
$lookup[$key] = true;
}
$ret_parameters = implode(',', $ret_params);
$ret_function = "$function($ret_parameters)";
return $ret_function;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,149 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates shorthand CSS property font.
*/
class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
{
/**
* Local copy of component validators.
*
* @note If we moved specific CSS property definitions to their own
* classes instead of having them be assembled at run time by
* CSSDefinition, this wouldn't be necessary. We'd instantiate
* our own copies.
*/
protected $info = array();
public function __construct($config) {
$def = $config->getCSSDefinition();
$this->info['font-style'] = $def->info['font-style'];
$this->info['font-variant'] = $def->info['font-variant'];
$this->info['font-weight'] = $def->info['font-weight'];
$this->info['font-size'] = $def->info['font-size'];
$this->info['line-height'] = $def->info['line-height'];
$this->info['font-family'] = $def->info['font-family'];
}
public function validate($string, $config, $context) {
static $system_fonts = array(
'caption' => true,
'icon' => true,
'menu' => true,
'message-box' => true,
'small-caption' => true,
'status-bar' => true
);
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') return false;
// check if it's one of the keywords
$lowercase_string = strtolower($string);
if (isset($system_fonts[$lowercase_string])) {
return $lowercase_string;
}
$bits = explode(' ', $string); // bits to process
$stage = 0; // this indicates what we're looking for
$caught = array(); // which stage 0 properties have we caught?
$stage_1 = array('font-style', 'font-variant', 'font-weight');
$final = ''; // output
for ($i = 0, $size = count($bits); $i < $size; $i++) {
if ($bits[$i] === '') continue;
switch ($stage) {
// attempting to catch font-style, font-variant or font-weight
case 0:
foreach ($stage_1 as $validator_name) {
if (isset($caught[$validator_name])) continue;
$r = $this->info[$validator_name]->validate(
$bits[$i], $config, $context);
if ($r !== false) {
$final .= $r . ' ';
$caught[$validator_name] = true;
break;
}
}
// all three caught, continue on
if (count($caught) >= 3) $stage = 1;
if ($r !== false) break;
// attempting to catch font-size and perhaps line-height
case 1:
$found_slash = false;
if (strpos($bits[$i], '/') !== false) {
list($font_size, $line_height) =
explode('/', $bits[$i]);
if ($line_height === '') {
// ooh, there's a space after the slash!
$line_height = false;
$found_slash = true;
}
} else {
$font_size = $bits[$i];
$line_height = false;
}
$r = $this->info['font-size']->validate(
$font_size, $config, $context);
if ($r !== false) {
$final .= $r;
// attempt to catch line-height
if ($line_height === false) {
// we need to scroll forward
for ($j = $i + 1; $j < $size; $j++) {
if ($bits[$j] === '') continue;
if ($bits[$j] === '/') {
if ($found_slash) {
return false;
} else {
$found_slash = true;
continue;
}
}
$line_height = $bits[$j];
break;
}
} else {
// slash already found
$found_slash = true;
$j = $i;
}
if ($found_slash) {
$i = $j;
$r = $this->info['line-height']->validate(
$line_height, $config, $context);
if ($r !== false) {
$final .= '/' . $r;
}
}
$final .= ' ';
$stage = 2;
break;
}
return false;
// attempting to catch font-family
case 2:
$font_family =
implode(' ', array_slice($bits, $i, $size - $i));
$r = $this->info['font-family']->validate(
$font_family, $config, $context);
if ($r !== false) {
$final .= $r . ' ';
// processing completed successfully
return rtrim($final);
}
return false;
}
}
return false;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,90 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a font family list according to CSS spec
* @todo whitelisting allowed fonts would be nice
*/
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
static $generic_names = array(
'serif' => true,
'sans-serif' => true,
'monospace' => true,
'fantasy' => true,
'cursive' => true
);
// assume that no font names contain commas in them
$fonts = explode(',', $string);
$final = '';
foreach($fonts as $font) {
$font = trim($font);
if ($font === '') continue;
// match a generic name
if (isset($generic_names[$font])) {
$final .= $font . ', ';
continue;
}
// match a quoted name
if ($font[0] === '"' || $font[0] === "'") {
$length = strlen($font);
if ($length <= 2) continue;
$quote = $font[0];
if ($font[$length - 1] !== $quote) continue;
$font = substr($font, 1, $length - 2);
$new_font = '';
for ($i = 0, $c = strlen($font); $i < $c; $i++) {
if ($font[$i] === '\\') {
$i++;
if ($i >= $c) {
$new_font .= '\\';
break;
}
if (ctype_xdigit($font[$i])) {
$code = $font[$i];
for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
if (!ctype_xdigit($font[$i])) break;
$code .= $font[$i];
}
// We have to be extremely careful when adding
// new characters, to make sure we're not breaking
// the encoding.
$char = HTMLPurifier_Encoder::unichr(hexdec($code));
if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue;
$new_font .= $char;
if ($i < $c && trim($font[$i]) !== '') $i--;
continue;
}
if ($font[$i] === "\n") continue;
}
$new_font .= $font[$i];
}
$font = $new_font;
}
// $font is a pure representation of the font name
if (ctype_alnum($font) && $font !== '') {
// very simple font, allow it in unharmed
$final .= $font . ', ';
continue;
}
// complicated font, requires quoting
// armor single quotes and new lines
$font = str_replace("\\", "\\\\", $font);
$font = str_replace("'", "\\'", $font);
$final .= "'$font', ";
}
$final = rtrim($final, ', ');
if ($final === '') return false;
return $final;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,40 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Decorator which enables !important to be used in CSS values.
*/
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
{
public $def, $allow;
/**
* @param $def Definition to wrap
* @param $allow Whether or not to allow !important
*/
public function __construct($def, $allow = false) {
$this->def = $def;
$this->allow = $allow;
}
/**
* Intercepts and removes !important if necessary
*/
public function validate($string, $config, $context) {
// test for ! and important tokens
$string = trim($string);
$is_important = false;
// :TODO: optimization: test directly for !important and ! important
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
$temp = rtrim(substr($string, 0, -9));
// use a temp, because we might want to restore important
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
$string = rtrim(substr($temp, 0, -1));
$is_important = true;
}
}
$string = $this->def->validate($string, $config, $context);
if ($this->allow && $is_important) $string .= ' !important';
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,47 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Represents a Length as defined by CSS.
*/
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
{
protected $min, $max;
/**
* @param HTMLPurifier_Length $max Minimum length, or null for no bound. String is also acceptable.
* @param HTMLPurifier_Length $max Maximum length, or null for no bound. String is also acceptable.
*/
public function __construct($min = null, $max = null) {
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
}
public function validate($string, $config, $context) {
$string = $this->parseCDATA($string);
// Optimizations
if ($string === '') return false;
if ($string === '0') return '0';
if (strlen($string) === 1) return false;
$length = HTMLPurifier_Length::make($string);
if (!$length->isValid()) return false;
if ($this->min) {
$c = $length->compareTo($this->min);
if ($c === false) return false;
if ($c < 0) return false;
}
if ($this->max) {
$c = $length->compareTo($this->max);
if ($c === false) return false;
if ($c > 0) return false;
}
return $length->toString();
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,78 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates shorthand CSS property list-style.
* @warning Does not support url tokens that have internal spaces.
*/
class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
{
/**
* Local copy of component validators.
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
*/
protected $info;
public function __construct($config) {
$def = $config->getCSSDefinition();
$this->info['list-style-type'] = $def->info['list-style-type'];
$this->info['list-style-position'] = $def->info['list-style-position'];
$this->info['list-style-image'] = $def->info['list-style-image'];
}
public function validate($string, $config, $context) {
// regular pre-processing
$string = $this->parseCDATA($string);
if ($string === '') return false;
// assumes URI doesn't have spaces in it
$bits = explode(' ', strtolower($string)); // bits to process
$caught = array();
$caught['type'] = false;
$caught['position'] = false;
$caught['image'] = false;
$i = 0; // number of catches
$none = false;
foreach ($bits as $bit) {
if ($i >= 3) return; // optimization bit
if ($bit === '') continue;
foreach ($caught as $key => $status) {
if ($status !== false) continue;
$r = $this->info['list-style-' . $key]->validate($bit, $config, $context);
if ($r === false) continue;
if ($r === 'none') {
if ($none) continue;
else $none = true;
if ($key == 'image') continue;
}
$caught[$key] = $r;
$i++;
break;
}
}
if (!$i) return false;
$ret = array();
// construct type
if ($caught['type']) $ret[] = $caught['type'];
// construct image
if ($caught['image']) $ret[] = $caught['image'];
// construct position
if ($caught['position']) $ret[] = $caught['position'];
if (empty($ret)) return false;
return implode(' ', $ret);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,58 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Framework class for strings that involve multiple values.
*
* Certain CSS properties such as border-width and margin allow multiple
* lengths to be specified. This class can take a vanilla border-width
* definition and multiply it, usually into a max of four.
*
* @note Even though the CSS specification isn't clear about it, inherit
* can only be used alone: it will never manifest as part of a multi
* shorthand declaration. Thus, this class does not allow inherit.
*/
class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
{
/**
* Instance of component definition to defer validation to.
* @todo Make protected
*/
public $single;
/**
* Max number of values allowed.
* @todo Make protected
*/
public $max;
/**
* @param $single HTMLPurifier_AttrDef to multiply
* @param $max Max number of values allowed (usually four)
*/
public function __construct($single, $max = 4) {
$this->single = $single;
$this->max = $max;
}
public function validate($string, $config, $context) {
$string = $this->parseCDATA($string);
if ($string === '') return false;
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
$length = count($parts);
$final = '';
for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) {
if (ctype_space($parts[$i])) continue;
$result = $this->single->validate($parts[$i], $config, $context);
if ($result !== false) {
$final .= $result . ' ';
$num++;
}
}
if ($final === '') return false;
return rtrim($final);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,69 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a number as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
{
/**
* Bool indicating whether or not only positive values allowed.
*/
protected $non_negative = false;
/**
* @param $non_negative Bool indicating whether negatives are forbidden
*/
public function __construct($non_negative = false) {
$this->non_negative = $non_negative;
}
/**
* @warning Some contexts do not pass $config, $context. These
* variables should not be used without checking HTMLPurifier_Length
*/
public function validate($number, $config, $context) {
$number = $this->parseCDATA($number);
if ($number === '') return false;
if ($number === '0') return '0';
$sign = '';
switch ($number[0]) {
case '-':
if ($this->non_negative) return false;
$sign = '-';
case '+':
$number = substr($number, 1);
}
if (ctype_digit($number)) {
$number = ltrim($number, '0');
return $number ? $sign . $number : '0';
}
// Period is the only non-numeric character allowed
if (strpos($number, '.') === false) return false;
list($left, $right) = explode('.', $number, 2);
if ($left === '' && $right === '') return false;
if ($left !== '' && !ctype_digit($left)) return false;
$left = ltrim($left, '0');
$right = rtrim($right, '0');
if ($right === '') {
return $left ? $sign . $left : '0';
} elseif (!ctype_digit($right)) {
return false;
}
return $sign . $left . '.' . $right;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,40 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a Percentage as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef
{
/**
* Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation
*/
protected $number_def;
/**
* @param Bool indicating whether to forbid negative values
*/
public function __construct($non_negative = false) {
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
}
public function validate($string, $config, $context) {
$string = $this->parseCDATA($string);
if ($string === '') return false;
$length = strlen($string);
if ($length === 1) return false;
if ($string[$length - 1] !== '%') return false;
$number = substr($string, 0, $length - 1);
$number = $this->number_def->validate($number, $config, $context);
if ($number === false) return false;
return "$number%";
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,38 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the value for the CSS property text-decoration
* @note This class could be generalized into a version that acts sort of
* like Enum except you can compound the allowed values.
*/
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
static $allowed_values = array(
'line-through' => true,
'overline' => true,
'underline' => true,
);
$string = strtolower($this->parseCDATA($string));
if ($string === 'none') return $string;
$parts = explode(' ', $string);
$final = '';
foreach ($parts as $part) {
if (isset($allowed_values[$part])) {
$final .= $part . ' ';
}
}
$final = rtrim($final);
if ($final === '') return false;
return $final;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,56 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a URI in CSS syntax, which uses url('http://example.com')
* @note While theoretically speaking a URI in a CSS document could
* be non-embedded, as of CSS2 there is no such usage so we're
* generalizing it. This may need to be changed in the future.
* @warning Since HTMLPurifier_AttrDef_CSS blindly uses semicolons as
* the separator, you cannot put a literal semicolon in
* in the URI. Try percent encoding it, in that case.
*/
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
{
public function __construct() {
parent::__construct(true); // always embedded
}
public function validate($uri_string, $config, $context) {
// parse the URI out of the string and then pass it onto
// the parent object
$uri_string = $this->parseCDATA($uri_string);
if (strpos($uri_string, 'url(') !== 0) return false;
$uri_string = substr($uri_string, 4);
$new_length = strlen($uri_string) - 1;
if ($uri_string[$new_length] != ')') return false;
$uri = trim(substr($uri_string, 0, $new_length));
if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) {
$quote = $uri[0];
$new_length = strlen($uri) - 1;
if ($uri[$new_length] !== $quote) return false;
$uri = substr($uri, 1, $new_length - 1);
}
$keys = array( '(', ')', ',', ' ', '"', "'");
$values = array('\\(', '\\)', '\\,', '\\ ', '\\"', "\\'");
$uri = str_replace($values, $keys, $uri);
$result = parent::validate($uri, $config, $context);
if ($result === false) return false;
// escape necessary characters according to CSS spec
// except for the comma, none of these should appear in the
// URI at all
$result = str_replace($keys, $values, $result);
return "url($result)";
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,65 @@
<?php defined("SYSPATH") or die("No direct script access.");
// Enum = Enumerated
/**
* Validates a keyword against a list of valid values.
* @warning The case-insensitive compare of this function uses PHP's
* built-in strtolower and ctype_lower functions, which may
* cause problems with international comparisons
*/
class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
{
/**
* Lookup table of valid values.
* @todo Make protected
*/
public $valid_values = array();
/**
* Bool indicating whether or not enumeration is case sensitive.
* @note In general this is always case insensitive.
*/
protected $case_sensitive = false; // values according to W3C spec
/**
* @param $valid_values List of valid values
* @param $case_sensitive Bool indicating whether or not case sensitive
*/
public function __construct(
$valid_values = array(), $case_sensitive = false
) {
$this->valid_values = array_flip($valid_values);
$this->case_sensitive = $case_sensitive;
}
public function validate($string, $config, $context) {
$string = trim($string);
if (!$this->case_sensitive) {
// we may want to do full case-insensitive libraries
$string = ctype_lower($string) ? $string : strtolower($string);
}
$result = isset($this->valid_values[$string]);
return $result ? $string : false;
}
/**
* @param $string In form of comma-delimited list of case-insensitive
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
* case sensitive
*/
public function make($string) {
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
$string = substr($string, 2);
$sensitive = true;
} else {
$sensitive = false;
}
$values = explode(',', $string);
return new HTMLPurifier_AttrDef_Enum($values, $sensitive);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,28 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a boolean attribute
*/
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
{
protected $name;
public $minimized = true;
public function __construct($name = false) {$this->name = $name;}
public function validate($string, $config, $context) {
if (empty($string)) return false;
return $this->name;
}
/**
* @param $string Name of attribute
*/
public function make($string) {
return new HTMLPurifier_AttrDef_HTML_Bool($string);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,34 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Implements special behavior for class attribute (normally NMTOKENS)
*/
class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens
{
protected function split($string, $config, $context) {
// really, this twiddle should be lazy loaded
$name = $config->getDefinition('HTML')->doctype->name;
if ($name == "XHTML 1.1" || $name == "XHTML 2.0") {
return parent::split($string, $config, $context);
} else {
return preg_split('/\s+/', $string);
}
}
protected function filter($tokens, $config, $context) {
$allowed = $config->get('Attr.AllowedClasses');
$forbidden = $config->get('Attr.ForbiddenClasses');
$ret = array();
foreach ($tokens as $token) {
if (
($allowed === null || isset($allowed[$token])) &&
!isset($forbidden[$token]) &&
// We need this O(n) check because of PHP's array
// implementation that casts -0 to 0.
!in_array($token, $ret, true)
) {
$ret[] = $token;
}
}
return $ret;
}
}

View File

@ -0,0 +1,32 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a color according to the HTML spec.
*/
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
static $colors = null;
if ($colors === null) $colors = $config->get('Core.ColorKeywords');
$string = trim($string);
if (empty($string)) return false;
if (isset($colors[$string])) return $colors[$string];
if ($string[0] === '#') $hex = substr($string, 1);
else $hex = $string;
$length = strlen($hex);
if ($length !== 3 && $length !== 6) return false;
if (!ctype_xdigit($hex)) return false;
if ($length === 3) $hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
return "#$hex";
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Special-case enum attribute definition that lazy loads allowed frame targets
*/
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
{
public $valid_values = false; // uninitialized value
protected $case_sensitive = false;
public function __construct() {}
public function validate($string, $config, $context) {
if ($this->valid_values === false) $this->valid_values = $config->get('Attr.AllowedFrameTargets');
return parent::validate($string, $config, $context);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,70 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the HTML attribute ID.
* @warning Even though this is the id processor, it
* will ignore the directive Attr:IDBlacklist, since it will only
* go according to the ID accumulator. Since the accumulator is
* automatically generated, it will have already absorbed the
* blacklist. If you're hacking around, make sure you use load()!
*/
class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
{
// ref functionality disabled, since we also have to verify
// whether or not the ID it refers to exists
public function validate($id, $config, $context) {
if (!$config->get('Attr.EnableID')) return false;
$id = trim($id); // trim it first
if ($id === '') return false;
$prefix = $config->get('Attr.IDPrefix');
if ($prefix !== '') {
$prefix .= $config->get('Attr.IDPrefixLocal');
// prevent re-appending the prefix
if (strpos($id, $prefix) !== 0) $id = $prefix . $id;
} elseif ($config->get('Attr.IDPrefixLocal') !== '') {
trigger_error('%Attr.IDPrefixLocal cannot be used unless '.
'%Attr.IDPrefix is set', E_USER_WARNING);
}
//if (!$this->ref) {
$id_accumulator =& $context->get('IDAccumulator');
if (isset($id_accumulator->ids[$id])) return false;
//}
// we purposely avoid using regex, hopefully this is faster
if (ctype_alpha($id)) {
$result = true;
} else {
if (!ctype_alpha(@$id[0])) return false;
$trim = trim( // primitive style of regexps, I suppose
$id,
'A..Za..z0..9:-._'
);
$result = ($trim === '');
}
$regexp = $config->get('Attr.IDBlacklistRegexp');
if ($regexp && preg_match($regexp, $id)) {
return false;
}
if (/*!$this->ref && */$result) $id_accumulator->add($id);
// if no change was made to the ID, return the result
// else, return the new id if stripping whitespace made it
// valid, or return false.
return $result ? $id : false;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,41 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the HTML type length (not to be confused with CSS's length).
*
* This accepts integer pixels or percentages as lengths for certain
* HTML attributes.
*/
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
{
public function validate($string, $config, $context) {
$string = trim($string);
if ($string === '') return false;
$parent_result = parent::validate($string, $config, $context);
if ($parent_result !== false) return $parent_result;
$length = strlen($string);
$last_char = $string[$length - 1];
if ($last_char !== '%') return false;
$points = substr($string, 0, $length - 1);
if (!is_numeric($points)) return false;
$points = (int) $points;
if ($points < 0) return '0%';
if ($points > 100) return '100%';
return ((string) $points) . '%';
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,53 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a rel/rev link attribute against a directive of allowed values
* @note We cannot use Enum because link types allow multiple
* values.
* @note Assumes link types are ASCII text
*/
class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
{
/** Name config attribute to pull. */
protected $name;
public function __construct($name) {
$configLookup = array(
'rel' => 'AllowedRel',
'rev' => 'AllowedRev'
);
if (!isset($configLookup[$name])) {
trigger_error('Unrecognized attribute name for link '.
'relationship.', E_USER_ERROR);
return;
}
$this->name = $configLookup[$name];
}
public function validate($string, $config, $context) {
$allowed = $config->get('Attr.' . $this->name);
if (empty($allowed)) return false;
$string = $this->parseCDATA($string);
$parts = explode(' ', $string);
// lookup to prevent duplicates
$ret_lookup = array();
foreach ($parts as $part) {
$part = strtolower(trim($part));
if (!isset($allowed[$part])) continue;
$ret_lookup[$part] = true;
}
if (empty($ret_lookup)) return false;
$string = implode(' ', array_keys($ret_lookup));
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,41 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a MultiLength as defined by the HTML spec.
*
* A multilength is either a integer (pixel count), a percentage, or
* a relative number.
*/
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
{
public function validate($string, $config, $context) {
$string = trim($string);
if ($string === '') return false;
$parent_result = parent::validate($string, $config, $context);
if ($parent_result !== false) return $parent_result;
$length = strlen($string);
$last_char = $string[$length - 1];
if ($last_char !== '*') return false;
$int = substr($string, 0, $length - 1);
if ($int == '') return '*';
if (!is_numeric($int)) return false;
$int = (int) $int;
if ($int < 0) return false;
if ($int == 0) return '0';
if ($int == 1) return '*';
return ((string) $int) . '*';
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,52 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates contents based on NMTOKENS attribute type.
*/
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
$string = trim($string);
// early abort: '' and '0' (strings that convert to false) are invalid
if (!$string) return false;
$tokens = $this->split($string, $config, $context);
$tokens = $this->filter($tokens, $config, $context);
if (empty($tokens)) return false;
return implode(' ', $tokens);
}
/**
* Splits a space separated list of tokens into its constituent parts.
*/
protected function split($string, $config, $context) {
// OPTIMIZABLE!
// do the preg_match, capture all subpatterns for reformulation
// we don't support U+00A1 and up codepoints or
// escaping because I don't know how to do that with regexps
// and plus it would complicate optimization efforts (you never
// see that anyway).
$pattern = '/(?:(?<=\s)|\A)'. // look behind for space or string start
'((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)'.
'(?:(?=\s)|\z)/'; // look ahead for space or string end
preg_match_all($pattern, $string, $matches);
return $matches[1];
}
/**
* Template method for removing certain tokens based on arbitrary criteria.
* @note If we wanted to be really functional, we'd do an array_filter
* with a callback. But... we're not.
*/
protected function filter($tokens, $config, $context) {
return $tokens;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,48 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates an integer representation of pixels according to the HTML spec.
*/
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
{
protected $max;
public function __construct($max = null) {
$this->max = $max;
}
public function validate($string, $config, $context) {
$string = trim($string);
if ($string === '0') return $string;
if ($string === '') return false;
$length = strlen($string);
if (substr($string, $length - 2) == 'px') {
$string = substr($string, 0, $length - 2);
}
if (!is_numeric($string)) return false;
$int = (int) $string;
if ($int < 0) return '0';
// upper-bound value, extremely high values can
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
// WARNING, above link WILL crash you if you're using Windows
if ($this->max !== null && $int > $this->max) return (string) $this->max;
return (string) $int;
}
public function make($string) {
if ($string === '') $max = null;
else $max = (int) $string;
$class = get_class($this);
return new $class($max);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,73 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates an integer.
* @note While this class was modeled off the CSS definition, no currently
* allowed CSS uses this type. The properties that do are: widows,
* orphans, z-index, counter-increment, counter-reset. Some of the
* HTML attributes, however, find use for a non-negative version of this.
*/
class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
{
/**
* Bool indicating whether or not negative values are allowed
*/
protected $negative = true;
/**
* Bool indicating whether or not zero is allowed
*/
protected $zero = true;
/**
* Bool indicating whether or not positive values are allowed
*/
protected $positive = true;
/**
* @param $negative Bool indicating whether or not negative values are allowed
* @param $zero Bool indicating whether or not zero is allowed
* @param $positive Bool indicating whether or not positive values are allowed
*/
public function __construct(
$negative = true, $zero = true, $positive = true
) {
$this->negative = $negative;
$this->zero = $zero;
$this->positive = $positive;
}
public function validate($integer, $config, $context) {
$integer = $this->parseCDATA($integer);
if ($integer === '') return false;
// we could possibly simply typecast it to integer, but there are
// certain fringe cases that must not return an integer.
// clip leading sign
if ( $this->negative && $integer[0] === '-' ) {
$digits = substr($integer, 1);
if ($digits === '0') $integer = '0'; // rm minus sign for zero
} elseif( $this->positive && $integer[0] === '+' ) {
$digits = $integer = substr($integer, 1); // rm unnecessary plus
} else {
$digits = $integer;
}
// test if it's numeric
if (!ctype_digit($digits)) return false;
// perform scope tests
if (!$this->zero && $integer == 0) return false;
if (!$this->positive && $integer > 0) return false;
if (!$this->negative && $integer < 0) return false;
return $integer;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,73 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates the HTML attribute lang, effectively a language code.
* @note Built according to RFC 3066, which obsoleted RFC 1766
*/
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
$string = trim($string);
if (!$string) return false;
$subtags = explode('-', $string);
$num_subtags = count($subtags);
if ($num_subtags == 0) return false; // sanity check
// process primary subtag : $subtags[0]
$length = strlen($subtags[0]);
switch ($length) {
case 0:
return false;
case 1:
if (! ($subtags[0] == 'x' || $subtags[0] == 'i') ) {
return false;
}
break;
case 2:
case 3:
if (! ctype_alpha($subtags[0]) ) {
return false;
} elseif (! ctype_lower($subtags[0]) ) {
$subtags[0] = strtolower($subtags[0]);
}
break;
default:
return false;
}
$new_string = $subtags[0];
if ($num_subtags == 1) return $new_string;
// process second subtag : $subtags[1]
$length = strlen($subtags[1]);
if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) {
return $new_string;
}
if (!ctype_lower($subtags[1])) $subtags[1] = strtolower($subtags[1]);
$new_string .= '-' . $subtags[1];
if ($num_subtags == 2) return $new_string;
// process all other subtags, index 2 and up
for ($i = 2; $i < $num_subtags; $i++) {
$length = strlen($subtags[$i]);
if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) {
return $new_string;
}
if (!ctype_lower($subtags[$i])) {
$subtags[$i] = strtolower($subtags[$i]);
}
$new_string .= '-' . $subtags[$i];
}
return $new_string;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,34 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Decorator that, depending on a token, switches between two definitions.
*/
class HTMLPurifier_AttrDef_Switch
{
protected $tag;
protected $withTag, $withoutTag;
/**
* @param string $tag Tag name to switch upon
* @param HTMLPurifier_AttrDef $with_tag Call if token matches tag
* @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token
*/
public function __construct($tag, $with_tag, $without_tag) {
$this->tag = $tag;
$this->withTag = $with_tag;
$this->withoutTag = $without_tag;
}
public function validate($string, $config, $context) {
$token = $context->get('CurrentToken', true);
if (!$token || $token->name !== $this->tag) {
return $this->withoutTag->validate($string, $config, $context);
} else {
return $this->withTag->validate($string, $config, $context);
}
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,15 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates arbitrary text according to the HTML spec.
*/
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context) {
return $this->parseCDATA($string);
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,77 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a URI as defined by RFC 3986.
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
*/
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
{
protected $parser;
protected $embedsResource;
/**
* @param $embeds_resource_resource Does the URI here result in an extra HTTP request?
*/
public function __construct($embeds_resource = false) {
$this->parser = new HTMLPurifier_URIParser();
$this->embedsResource = (bool) $embeds_resource;
}
public function make($string) {
$embeds = (bool) $string;
return new HTMLPurifier_AttrDef_URI($embeds);
}
public function validate($uri, $config, $context) {
if ($config->get('URI.Disable')) return false;
$uri = $this->parseCDATA($uri);
// parse the URI
$uri = $this->parser->parse($uri);
if ($uri === false) return false;
// add embedded flag to context for validators
$context->register('EmbeddedURI', $this->embedsResource);
$ok = false;
do {
// generic validation
$result = $uri->validate($config, $context);
if (!$result) break;
// chained filtering
$uri_def = $config->getDefinition('URI');
$result = $uri_def->filter($uri, $config, $context);
if (!$result) break;
// scheme-specific validation
$scheme_obj = $uri->getSchemeObj($config, $context);
if (!$scheme_obj) break;
if ($this->embedsResource && !$scheme_obj->browsable) break;
$result = $scheme_obj->validate($uri, $config, $context);
if (!$result) break;
// Post chained filtering
$result = $uri_def->postFilter($uri, $config, $context);
if (!$result) break;
// survived gauntlet
$ok = true;
} while (false);
$context->destroy('EmbeddedURI');
if (!$ok) return false;
// back to string
return $uri->toString();
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.");
abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
{
/**
* Unpacks a mailbox into its display-name and address
*/
function unpack($string) {
// needs to be implemented
}
}
// sub-implementations
// vim: et sw=4 sts=4

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Primitive email validation class based on the regexp found at
* http://www.regular-expressions.info/email.html
*/
class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
{
public function validate($string, $config, $context) {
// no support for named mailboxes i.e. "Bob <bob@example.com>"
// that needs more percent encoding to be done
if ($string == '') return false;
$string = trim($string);
$result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string);
return $result ? $string : false;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,62 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
*/
class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
{
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
*/
protected $ipv4;
/**
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
*/
protected $ipv6;
public function __construct() {
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
}
public function validate($string, $config, $context) {
$length = strlen($string);
if ($string === '') return '';
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
//IPv6
$ip = substr($string, 1, $length - 2);
$valid = $this->ipv6->validate($ip, $config, $context);
if ($valid === false) return false;
return '['. $valid . ']';
}
// need to do checks on unusual encodings too
$ipv4 = $this->ipv4->validate($string, $config, $context);
if ($ipv4 !== false) return $ipv4;
// A regular domain name.
// This breaks I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode. If there's complaining we'll
// try to fix things into an international friendly form.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$and = '[a-z0-9-]'; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an($and*$an)?";
// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
$toplabel = "$a($and*$an)?";
// hostname = *( domainlabel "." ) toplabel [ "." ]
$match = preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string);
if (!$match) return false;
return $string;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,39 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates an IPv4 address
* @author Feyd @ forums.devnetwork.net (public domain)
*/
class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
{
/**
* IPv4 regex, protected so that IPv6 can reuse it
*/
protected $ip4;
public function validate($aIP, $config, $context) {
if (!$this->ip4) $this->_loadRegex();
if (preg_match('#^' . $this->ip4 . '$#s', $aIP))
{
return $aIP;
}
return false;
}
/**
* Lazy load function to prevent regex from being stuffed in
* cache.
*/
protected function _loadRegex() {
$oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255
$this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})";
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,99 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Validates an IPv6 address.
* @author Feyd @ forums.devnetwork.net (public domain)
* @note This function requires brackets to have been removed from address
* in URI.
*/
class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
{
public function validate($aIP, $config, $context) {
if (!$this->ip4) $this->_loadRegex();
$original = $aIP;
$hex = '[0-9a-fA-F]';
$blk = '(?:' . $hex . '{1,4})';
$pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128
// prefix check
if (strpos($aIP, '/') !== false)
{
if (preg_match('#' . $pre . '$#s', $aIP, $find))
{
$aIP = substr($aIP, 0, 0-strlen($find[0]));
unset($find);
}
else
{
return false;
}
}
// IPv4-compatiblity check
if (preg_match('#(?<=:'.')' . $this->ip4 . '$#s', $aIP, $find))
{
$aIP = substr($aIP, 0, 0-strlen($find[0]));
$ip = explode('.', $find[0]);
$ip = array_map('dechex', $ip);
$aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3];
unset($find, $ip);
}
// compression check
$aIP = explode('::', $aIP);
$c = count($aIP);
if ($c > 2)
{
return false;
}
elseif ($c == 2)
{
list($first, $second) = $aIP;
$first = explode(':', $first);
$second = explode(':', $second);
if (count($first) + count($second) > 8)
{
return false;
}
while(count($first) < 8)
{
array_push($first, '0');
}
array_splice($first, 8 - count($second), 8, $second);
$aIP = $first;
unset($first,$second);
}
else
{
$aIP = explode(':', $aIP[0]);
}
$c = count($aIP);
if ($c != 8)
{
return false;
}
// All the pieces should be 16-bit hex strings. Are they?
foreach ($aIP as $piece)
{
if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece)))
{
return false;
}
}
return $original;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,56 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Processes an entire attribute array for corrections needing multiple values.
*
* Occasionally, a certain attribute will need to be removed and popped onto
* another value. Instead of creating a complex return syntax for
* HTMLPurifier_AttrDef, we just pass the whole attribute array to a
* specialized object and have that do the special work. That is the
* family of HTMLPurifier_AttrTransform.
*
* An attribute transformation can be assigned to run before or after
* HTMLPurifier_AttrDef validation. See HTMLPurifier_HTMLDefinition for
* more details.
*/
abstract class HTMLPurifier_AttrTransform
{
/**
* Abstract: makes changes to the attributes dependent on multiple values.
*
* @param $attr Assoc array of attributes, usually from
* HTMLPurifier_Token_Tag::$attr
* @param $config Mandatory HTMLPurifier_Config object.
* @param $context Mandatory HTMLPurifier_Context object
* @returns Processed attribute array.
*/
abstract public function transform($attr, $config, $context);
/**
* Prepends CSS properties to the style attribute, creating the
* attribute if it doesn't exist.
* @param $attr Attribute array to process (passed by reference)
* @param $css CSS to prepend
*/
public function prependCSS(&$attr, $css) {
$attr['style'] = isset($attr['style']) ? $attr['style'] : '';
$attr['style'] = $css . $attr['style'];
}
/**
* Retrieves and removes an attribute
* @param $attr Attribute array to process (passed by reference)
* @param $key Key of attribute to confiscate
*/
public function confiscateAttr(&$attr, $key) {
if (!isset($attr[$key])) return null;
$value = $attr[$key];
unset($attr[$key]);
return $value;
}
}
// vim: et sw=4 sts=4

View File

@ -0,0 +1,23 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Pre-transform that changes proprietary background attribute to CSS.
*/
class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform {
public function transform($attr, $config, $context) {
if (!isset($attr['background'])) return $attr;
$background = $this->confiscateAttr($attr, 'background');
// some validation should happen here
$this->prependCSS($attr, "background-image:url($background);");
return $attr;
}
}
// vim: et sw=4 sts=4

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