Working on Web admin

This commit is contained in:
Jérôme Schneider 2012-04-09 16:12:08 +02:00
parent 92b0dc95ef
commit 2133a265d1
48 changed files with 4316 additions and 240 deletions

View file

@ -58,16 +58,6 @@ define("BAIKAL_PATH_WWWROOT", BAIKAL_PATH_CORE . "WWWRoot/");
require_once(BAIKAL_PATH_SPECIFIC . "config.php");
require_once(BAIKAL_PATH_SPECIFIC . "config.system.php");
# Determining baikal protocol, domain and uri-path (looking at BAIKAL_URI)
if($GLOBALS["_SERVER"]["SERVER_NAME"] === "mongoose") { # And not using MONGOOSE_SERVER constant, as it will be defined by Flake, later in the process
define("BAIKAL_DOMAIN", "");
define("BAIKAL_URIPATH", "");
} else {
$aUrlInfo = parse_url(BAIKAL_URI);
define("BAIKAL_DOMAIN", $aUrlInfo["host"]);
define("BAIKAL_URIPATH", $aUrlInfo["path"]);
}
date_default_timezone_set(BAIKAL_TIMEZONE);
# Check if DB exists
@ -88,7 +78,6 @@ if($bShouldCheckEnv === TRUE) {
}
}
if($bShouldCheckEnv === TRUE) {
# Mapping PHP errors to exceptions
function exception_error_handler($errno, $errstr, $errfile, $errline) {
@ -100,5 +89,7 @@ if($bShouldCheckEnv === TRUE) {
error_reporting(E_ALL ^ E_NOTICE);
}
unset($bShouldCheckEnv);
// Autoloader
require_once(BAIKAL_PATH_SABREDAV . 'autoload.php');

View file

@ -0,0 +1,136 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
* All rights reserved
*
* http://baikal.codr.fr
*
* This script is part of the Baïkal Server project. The Baïkal
* Server project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace Baikal\Model;
class Calendar extends \Flake\Core\Model\Db {
const DATATABLE = "calendars";
const PRIMARYKEY = "id";
const LABELFIELD = "displayname";
protected $aData = array(
"principaluri" => "",
"displayname" => "",
"uri" => "",
"ctag" => "",
"description" => "",
"calendarorder" => "",
"calendarcolor" => "",
"timezone" => "",
"components" => "",
);
public static function icon() {
return "icon-calendar";
}
public static function mediumicon() {
return "glyph-calendar";
}
public static function bigicon() {
return "glyph2x-calendar";
}
public function get($sPropName) {
if($sPropName === "todos") {
# TRUE if components contains VTODO, FALSE otherwise
if(($sComponents = $this->get("components")) !== "") {
$aComponents = explode(",", $sComponents);
} else {
$aComponents = array();
}
return in_array("VTODO", $aComponents);
}
return parent::get($sPropName);
}
public function set($sPropName, $sValue) {
if($sPropName === "todos") {
if(($sComponents = $this->get("components")) !== "") {
$aComponents = explode(",", $sComponents);
} else {
$aComponents = array();
}
if($sValue === TRUE) {
if(!in_array("VTODO", $aComponents)) {
$aComponents[] = "VTODO";
}
} else {
if(in_array("VTODO", $aComponents)) {
unset($aComponents[array_search("VTODO", $aComponents)]);
}
}
return parent::set("components", implode(",", $aComponents));
}
return parent::set($sPropName, $sValue);
}
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "uri",
"label" => "Calendar token ID",
"validation" => "required,tokenid"
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "displayname",
"label" => "Display name",
"validation" => "required"
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "description",
"label" => "Description",
"validation" => "required"
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "todos",
"label" => "Todos"
)));
if(!$this->floating()) {
$oMorpho->element("uri")->setOption("readonly", TRUE);
}
return $oMorpho;
}
public function isDefault() {
return $this->get("uri") === "default";
}
}

View file

@ -48,6 +48,16 @@ class User extends \Flake\Core\Model\Db {
->first();
}
public function getCalendarsBaseRequester() {
$oCalendarBaseRequester = \Baikal\Model\Calendar::getBaseRequester();
$oCalendarBaseRequester->addClauseEquals(
"principaluri",
"principals/" . $this->get("username")
);
return $oCalendarBaseRequester;
}
public function initFloating() {
parent::initFloating();
@ -101,11 +111,40 @@ class User extends \Flake\Core\Model\Db {
public function persist() {
$bFloating = $this->floating();
# Persisted first, as Model users loads this data
$this->oIdentityPrincipal->set("uri", "principals/" . $this->get("username"));
$this->oIdentityPrincipal->persist();
parent::persist();
if($bFloating) {
# Creating default calendar for user
$oDefaultCalendar = new \Baikal\Model\Calendar();
$oDefaultCalendar->set(
"principaluri",
"principals/" . $this->get("username")
)->set(
"displayname",
"Default calendar"
)->set(
"uri",
"default"
)->set(
"ctag",
1
)->set(
"description",
"Default calendar"
)->set(
"components",
"VEVENT,VTODO"
);
$oDefaultCalendar->persist();
}
}
public function destroy() {
@ -121,21 +160,13 @@ class User extends \Flake\Core\Model\Db {
return "mailto:" . rawurlencode($this->get("displayname") . " <" . $this->get("email") . ">");
}
public function formForThisModelInstance($options = array()) {
$sClass = get_class($this);
$oForm = new \Formal\Form($sClass, $options);
$oForm->setModelInstance($this);
return $oForm;
}
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "username",
"label" => "Username",
"validation" => "required,unique"
"validation" => "required,tokenid,unique"
)));
$oMorpho->add(new \Formal\Element\Text(array(
@ -174,10 +205,18 @@ class User extends \Flake\Core\Model\Db {
return $oMorpho;
}
public static function getIcon() {
public static function icon() {
return "icon-user";
}
public static function mediumicon() {
return "glyph-user";
}
public static function bigicon() {
return "glyph2x-user";
}
public function getPasswordHashForPassword($sPassword) {
return md5($this->get("username") . ':' . BAIKAL_AUTH_REALM . ':' . $sPassword);
}

View file

@ -28,10 +28,10 @@ namespace BaikalAdmin\Controller;
class Dashboard extends \Flake\Core\Controller {
function execute() {
public function execute() {
}
function render() {
public function render() {
$sLinkUsers = \BaikalAdmin\Controller\Users::link();
$sMessage =<<<MESSAGE

View file

@ -28,10 +28,10 @@ namespace BaikalAdmin\Controller;
class Install extends \Flake\Core\Controller {
function execute() {
public function execute() {
}
function render() {
public function render() {
return "<h2>Install</h2>";
}
}

View file

@ -24,14 +24,14 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\View\User;
namespace BaikalAdmin\Controller;
class Settings extends \Flake\Core\Controller {
public function execute() {
}
class Listing extends \Flake\Core\View {
public function render() {
$oTemplate = new \Flake\Core\Template(BAIKALADMIN_PATH_TEMPLATES . "User/Listing.html", TRUE);
return $oTemplate->parse(array(
"users" => $this->get("users"),
));
return "<h2>Settings</h2>";
}
}

View file

@ -0,0 +1,248 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
* All rights reserved
*
* http://baikal.codr.fr
*
* This script is part of the Baïkal Server project. The Baïkal
* Server project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\Controller\User;
class Calendars extends \Flake\Core\Controller {
protected $aMessages = array();
protected $oModel; # \Baikal\Model\Calendar
protected $oUser; # \Baikal\Model\User
protected $oForm; # \Formal\Form
public function __construct() {
parent::__construct();
if(($iUser = $this->currentUserId()) === FALSE) {
throw new \Exception("BaikalAdmin\Controller\Details::render(): User get-parameter not found.");
}
$this->oUser = new \Baikal\Model\User($iUser);
if(($iCalendar = self::editRequested()) !== FALSE) {
$this->oModel = new \Baikal\Model\Calendar($iCalendar);
$this->initForm();
}
if(($iUser = self::newRequested()) !== FALSE) {
# building floating object
$this->oModel = new \Baikal\Model\Calendar();
$this->oModel->set(
"principaluri",
$this->oUser->get("uri")
);
$this->oModel->set(
"components",
"VEVENT"
);
$this->oModel->set(
"ctag",
"1"
);
$this->initForm();
}
}
public function execute() {
if(($iUser = self::editRequested()) !== FALSE) {
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
if(self::newRequested()) {
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
$this->oForm->setOption(
"action",
$this->linkEdit(
$this->oForm->modelInstance()
)
);
}
}
}
if(($iCalendar = self::deleteRequested()) !== FALSE) {
if(self::deleteConfirmed() !== FALSE) {
# catching Exception thrown when model already destroyed
# happens when user refreshes page on delete-URL, for instance
try {
$oModel = new \Baikal\Model\Calendar($iCalendar);
$oModel->destroy();
} catch(\Exception $e) {
# already deleted; silently discarding
}
# Redirecting to admin home
\Flake\Util\Tools::redirectUsingMeta(self::linkHome());
} else {
$oModel = new \Baikal\Model\Calendar($iCalendar);
$this->aMessages[] = \Formal\Core\Message::warningConfirmMessage(
"Check twice, you're about to delete " . $oModel->label() . "</strong> from the database !",
"<p>You are about to delete a calendar and all it's scheduled events. This operation cannot be undone.</p><p>So, now that you know all that, what shall we do ?</p>",
self::linkDeleteConfirm($oModel),
"Delete <strong><i class='" . $oModel->icon() . " icon-white'></i> " . $oModel->label() . "</strong>",
self::linkHome()
);
}
}
}
public function render() {
$sHtml = "";
# Render list of users
$oCalendars = $this->oUser->getCalendarsBaseRequester()->execute();
$oView = new \BaikalAdmin\View\Calendars\Listing();
$oView->setData("user", $this->oUser);
$oView->setData("calendars", $oCalendars);
$sHtml .= $oView->render();
# Render form
$sHtml .= "<a id='form'></a>";
$sMessages = implode("\n", $this->aMessages);
if(self::newRequested() || self::editRequested()) {
# We have to display the User form
$sHtml .= $this->oForm->render();
} else {
# No form is displayed; simply display messages, if any
$sHtml .= $sMessages;
}
return $sHtml;
}
protected function initForm() {
if($this->editRequested() || $this->newRequested()) {
$aOptions = array(
"closeurl" => $this->linkHome()
);
$this->oForm = $this->oModel->formForThisModelInstance($aOptions);
}
}
protected static function currentUserId() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($iUser = intval($aParams[0])) === 0) {
return FALSE;
}
return $iUser;
}
protected static function newRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
return $aParams[1] === "new";
}
protected static function editRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($aParams[1] === "edit") && intval($aParams[2]) > 0) {
return intval($aParams[2]);
}
return FALSE;
}
protected static function deleteRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($aParams[1] === "delete") && intval($aParams[2]) > 0) {
return intval($aParams[2]);
}
return FALSE;
}
protected static function deleteConfirmed() {
if(($iPrimary = self::deleteRequested()) === FALSE) {
return FALSE;
}
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if($aParams[3] === "confirm") {
return $iPrimary;
}
return FALSE;
}
public static function linkNew() {
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
self::currentUserId(),
"new"
) . "#form";
}
public static function linkEdit(\Baikal\Model\Calendar $oCalendar) {
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
self::currentUserId(),
"edit",
$oCalendar->get("id")
) . "#form";
}
public static function linkDelete(\Baikal\Model\Calendar $oCalendar) {
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
self::currentUserId(),
"delete",
$oCalendar->get("id")
) . "#message";
}
public static function linkDeleteConfirm(\Baikal\Model\Calendar $oCalendar) {
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
self::currentUserId(),
"delete",
$oCalendar->get("id"),
"confirm"
) . "#message";
}
public static function linkHome() {
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
self::currentUserId()
);
}
}

View file

@ -28,7 +28,6 @@ namespace BaikalAdmin\Controller;
class Users extends \Flake\Core\Controller {
const BASEPATH = "/admin/";
protected $aMessages = array();
public function __construct() {
@ -46,14 +45,14 @@ class Users extends \Flake\Core\Controller {
}
}
function execute() {
public function execute() {
if(($iUser = self::editRequested()) !== FALSE) {
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
if($this->newRequested()) {
if(self::newRequested()) {
if($this->oForm->submitted()) {
$this->oForm->execute();
@ -61,7 +60,7 @@ class Users extends \Flake\Core\Controller {
$this->oForm->setOption(
"action",
$this->linkEdit(
$this->oForm->getModelInstance()
$this->oForm->modelInstance()
)
);
}
@ -88,17 +87,42 @@ class Users extends \Flake\Core\Controller {
$oUser = new \Baikal\Model\User($iUser);
$this->aMessages[] = \Formal\Core\Message::warningConfirmMessage(
"Check twice, you're about to delete " . $oUser->get("username") . "</strong> from the database !",
"Check twice, you're about to delete " . $oUser->label() . "</strong> from the database !",
"<p>You are about to delete a user and all it's calendars / contacts. This operation cannot be undone.</p><p>So, now that you know all that, what shall we do ?</p>",
self::linkDeleteConfirm($oUser),
"Delete <strong><i class='" . $oUser->getIcon() . " icon-white'></i> " . $oUser->getLabel() . "</strong>",
"Delete <strong><i class='" . $oUser->icon() . " icon-white'></i> " . $oUser->label() . "</strong>",
self::link()
);
}
}
}
function initForm() {
public function render() {
$sHtml = "";
# Render list of users
$oUsers = \Baikal\Model\User::getBaseRequester()->execute();
$oView = new \BaikalAdmin\View\Users\Listing();
$oView->setData("users", $oUsers);
$sHtml .= $oView->render();
# Render form
$sHtml .= "<a id='form'></a>";
$sMessages = implode("\n", $this->aMessages);
if(self::newRequested() || self::editRequested()) {
# We have to display the User form
$sHtml .= $this->oForm->render();
} else {
# No form is displayed; simply display messages, if any
$sHtml .= $sMessages;
}
return $sHtml;
}
protected function initForm() {
if($this->editRequested() || $this->newRequested()) {
$aOptions = array(
"closeurl" => self::link()
@ -108,7 +132,7 @@ class Users extends \Flake\Core\Controller {
}
}
public static function editRequested() {
protected static function editRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($aParams[0] === "edit") && intval($aParams[1]) > 0) {
return intval($aParams[1]);
@ -117,7 +141,7 @@ class Users extends \Flake\Core\Controller {
return FALSE;
}
public static function deleteRequested() {
protected static function deleteRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($aParams[0] === "delete") && intval($aParams[1]) > 0) {
return intval($aParams[1]);
@ -126,7 +150,7 @@ class Users extends \Flake\Core\Controller {
return FALSE;
}
public static function deleteConfirmed() {
protected static function deleteConfirmed() {
if(($iUser = self::deleteRequested()) === FALSE) {
return FALSE;
}
@ -139,67 +163,37 @@ class Users extends \Flake\Core\Controller {
return FALSE;
}
public static function newRequested() {
protected static function newRequested() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
return $aParams[0] === "new";
}
function render() {
$sHtml = "";
# Render list of users
$oUsers = \Baikal\Model\User::getBaseRequester()->execute();
$oView = new \BaikalAdmin\View\User\Listing();
$oView->setData("users", $oUsers);
$sHtml .= $oView->render();
# Render form
$sHtml .= "<a id='edituser'></a>";
$sMessages = implode("\n", $this->aMessages);
if(($iUser = self::editRequested()) !== FALSE) {
# We have to display the edition form for the requested user
$oUser = new \Baikal\Model\User($iUser);
$oView = new \BaikalAdmin\View\User\Form();
$oView->setData("user", $oUser);
$sHtml .= $this->oForm->render();
$sHtml .= $oView->render();
} elseif(self::newRequested()) {
$sHtml .= $this->oForm->render();
} else {
# No form is displayed
# Simply display messages, if any
$sHtml .= $sMessages;
}
return $sHtml;
}
public static function link() {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildRouteForController("\BaikalAdmin\Controller\Users");
}
public static function linkNew() {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildCurrentRoute("new") . "#edituser";
return $GLOBALS["ROUTER"]::buildRouteForController(get_called_class(), "new") . "#form";
}
public static function linkEdit(\Baikal\Model\User $user) {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildCurrentRoute("edit", $user->get("id")) . "#edituser";
return $GLOBALS["ROUTER"]::buildRouteForController(get_called_class(), "edit", $user->get("id")) . "#form";
}
public static function linkDelete(\Baikal\Model\User $user) {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildCurrentRoute("delete", $user->get("id")) . "#message";
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
"delete",
$user->get("id")
) . "#message";
}
public static function linkDeleteConfirm(\Baikal\Model\User $user) {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildCurrentRoute("delete", $user->get("id"), "confirm") . "#message";
return $GLOBALS["ROUTER"]::buildRouteForController(
get_called_class(),
"delete",
$user->get("id"),
"confirm"
) . "#message";
}
public static function linkDetails(\Baikal\Model\User $user) {
return BAIKAL_URI . BAIKALADMIN_URIPATH . $GLOBALS["ROUTER"]::buildCurrentRoute("details", $user->get("id"));
public static function linkCalendars(\Baikal\Model\User $user) {
return $GLOBALS["ROUTER"]::buildRouteForController('\BaikalAdmin\Controller\User\Calendars', $user->get("id"));
}
}

View file

@ -41,6 +41,7 @@ require_once(dirname(__FILE__) . '/ClassLoader.php');
# Relative to BAIKAL_URI; so that BAIKAL_URI . BAIKALADMIN_URIPATH corresponds to the full URL to Baïkal admin
define("BAIKALADMIN_URIPATH", "admin/");
$GLOBALS["ROUTER"]::setURIPath(BAIKALADMIN_URIPATH);
# Include BaikalAdmin Framework config
require_once(BAIKALADMIN_PATH_ROOT . "config.php");

View file

@ -24,21 +24,12 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\Controller;
namespace BaikalAdmin\Core;
class Details extends \Flake\Core\Controller {
function execute() {
}
function render() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
if(($iUser = intval($aParams[0])) === 0) {
throw new \Exception("BaikalAdmin\Controller\Details::render(): User get-parameter not found.");
}
$oUser = new \Baikal\Model\User($iUser);
return "<h2>Details for user " . $oUser->getLabel() . "</h2>";
class View extends \Flake\Core\View {
public function templatesPath() {
$sViewName = get_class($this);
$sTemplate = str_replace("\\", "/", substr($sViewName, strlen("BaikalAdmin\\View\\"))) . ".html";
return BAIKALADMIN_PATH_TEMPLATES . $sTemplate;
}
}

View file

@ -0,0 +1,461 @@
#!/usr/bin/env php
<?php
define("COLUMNS", 10);
define("ROWS", 35);
define("MATRIXWIDTH", 400);
define("MATRIXHEIGHT", 1400);
echo generateSprite(getSymbols(), COLUMNS, ROWS, MATRIXWIDTH, MATRIXHEIGHT, "glyph-");
function getSymbols() {
# Glyphicons Png names, without extension
return array(
"000_glass",
"001_leaf",
"002_dog",
"003_user",
"004_girl",
"005_car",
"006_user_add",
"007_user_remove",
"008_film",
"009_magic",
"010_envelope",
"011_camera",
"012_heart",
"013_beach_umbrella",
"014_train",
"015_print",
"016_bin",
"017_music",
"018_note",
"019_cogwheel",
"020_home",
"021_snowflake",
"022_fire",
"023_cogwheels",
"024_parents",
"025_binoculars",
"026_road",
"027_search",
"028_cars",
"029_notes_2",
"030_pencil",
"031_bus",
"032_wifi_alt",
"033_luggage",
"034_old_man",
"035_woman",
"036_file",
"037_credit",
"038_airplane",
"039_notes",
"040_stats",
"041_charts",
"042_pie_chart",
"043_group",
"044_keys",
"045_calendar",
"046_router",
"047_camera_small",
"048_dislikes",
"049_star",
"050_link",
"051_eye_open",
"052_eye_close",
"053_alarm",
"054_clock",
"055_stopwatch",
"056_projector",
"057_history",
"058_truck",
"059_cargo",
"060_compass",
"061_keynote",
"062_attach",
"063_power",
"064_lightbulb",
"065_tag",
"066_tags",
"067_cleaning",
"068_ruller",
"069_gift",
"070_umbrella",
"071_book",
"072_bookmark",
"073_signal",
"074_cup",
"075_stroller",
"076_headphones",
"077_headset",
"078_warning_sign",
"079_signal",
"080_retweet",
"081_refresh",
"082_roundabout",
"083_random",
"084_heat",
"085_repeat",
"086_display",
"087_log_book",
"088_adress_book",
"089_magnet",
"090_table",
"091_adjust",
"092_tint",
"093_crop",
"094_vector_path_square",
"095_vector_path_circle",
"096_vector_path_polygon",
"097_vector_path_line",
"098_vector_path_curve",
"099_vector_path_all",
"100_font",
"101_italic",
"102_bold",
"103_text_underline",
"104_text_strike",
"105_text_height",
"106_text_width",
"107_text_resize",
"108_left_indent",
"109_right_indent",
"110_align_left",
"111_align_center",
"112_align_right",
"113_justify",
"114_list",
"115_text_smaller",
"116_text_bigger",
"117_embed",
"118_embed_close",
"119_adjust",
"120_message_full",
"121_message_empty",
"122_message_in",
"123_message_out",
"124_message_plus",
"125_message_minus",
"126_message_ban",
"127_message_flag",
"128_message_lock",
"129_message_new",
"130_inbox",
"131_inbox_plus",
"132_inbox_minus",
"133_inbox_lock",
"134_inbox_in",
"135_inbox_out",
"136_computer_locked",
"137_computer_service",
"138_computer_proces",
"139_phone",
"140_database_lock",
"141_database_plus",
"142_database_minus",
"143_database_ban",
"144_folder_open",
"145_folder_plus",
"146_folder_minus",
"147_folder_lock",
"148_folder_flag",
"149_folder_new",
"150_check",
"151_edit",
"152_new_window",
"153_more_windows",
"154_show_big_thumbnails",
"155_show_thumbnails",
"156_show_thumbnails_with_lines",
"157_show_lines",
"158_playlist",
"159_picture",
"160_imac",
"161_macbook",
"162_ipad",
"163_iphone",
"164_iphone_transfer",
"165_iphone_exchange",
"166_ipod",
"167_ipod_shuffle",
"168_ear_plugs",
"169_albums",
"170_step_backward",
"171_fast_backward",
"172_rewind",
"173_play",
"174_pause",
"175_stop",
"176_forward",
"177_fast_forward",
"178_step_forward",
"179_eject",
"180_facetime_video",
"181_download_alt",
"182_mute",
"183_volume_down",
"184_volume_up",
"185_screenshot",
"186_move",
"187_more",
"188_brightness_reduce",
"189_brightness_increase",
"190_circle_plus",
"191_circle_minus",
"192_circle_remove",
"193_circle_ok",
"194_circle_question_mark",
"195_circle_info",
"196_circle_exclamation_mark",
"197_remove",
"198_ok",
"199_ban",
"200_download",
"201_upload",
"202_shopping_cart",
"203_lock",
"204_unlock",
"205_electricity",
"206_ok_2",
"207_remove_2",
"208_cart_out",
"209_cart_in",
"210_left_arrow",
"211_right_arrow",
"212_down_arrow",
"213_up_arrow",
"214_resize_small",
"215_resize_full",
"216_circle_arrow_left",
"217_circle_arrow_right",
"218_circle_arrow_right",
"219_circle_arrow_right",
"220_play_button",
"221_unshare",
"222_share",
"223_thin_right_arrow",
"224_thin_arrow_left",
"225_bluetooth",
"226_euro",
"227_usd",
"228_bp",
"229_retweet_2",
"230_moon",
"231_sun",
"232_cloud",
"233_direction",
"234_brush",
"235_pen",
"236_zoom_in",
"237_zoom_out",
"238_pin",
"239_riflescope",
"240_rotation_lock",
"241_flash",
"242_google_maps",
"243_anchor",
"244_conversation",
"245_chat",
"246_male",
"247_female",
"248_asterisk",
"249_divide",
"250_snorkel_diving",
"251_scuba_diving",
"252_oxygen_bottle",
"253_fins",
"254_fishes",
"255_boat",
"256_delete_point",
"257_sheriffs_-star",
"258_qrcode",
"259_barcode",
"260_pool",
"261_buoy",
"262_spade",
"263_bank",
"264_vcard",
"265_electrical_plug",
"266_flag",
"267_credit_card",
"268_keyboard_wireless",
"269_keyboard_wired",
"270_shield",
"271_ring",
"272_cake",
"273_drink",
"274_beer",
"275_fast_food",
"276_cutlery",
"277_pizza",
"278_birthday_cake",
"279_tablet",
"280_settings",
"281_bullets",
"282_cardio",
"283_t-shirt",
"284_pants",
"285_sweater",
"286_fabric",
"287_leather",
"288_scissors",
"289_podium",
"290_skull",
"291_celebration",
"292_tea_kettle",
"293_french_press",
"294_coffe_cup",
"295_pot",
"296_grater",
"297_kettle",
"298_hospital",
"299_hospital_h",
"300_microphone",
"301_webcam",
"302_temple_christianity_church",
"303_temple_islam",
"304_temple_hindu",
"305_temple_buddhist",
"306_electrical_socket_eu",
"307_electrical_socket_us",
"308_bomb",
"309_comments",
"310_flower",
"311_baseball",
"312_rugby",
"313_ax",
"314_table_tennis",
"315_bowling",
"316_tree_conifer",
"317_tree_deciduous",
"318_more-items",
"319_sort",
"320_facebook",
"321_twitter_t",
"322_twitter",
"323_buzz",
"324_vimeo",
"325_flickr",
"326_last_fm",
"327_rss",
"328_skype",
"329_e-mail",
"330_instapaper",
"331_evernote",
"332_xing",
"333_zootool",
"334_dribbble",
"335_deviantart",
"336_read_it_later",
"337_linked_in",
"338_forrst",
"339_pinboard",
"340_behance",
"341_github",
"342_youtube",
"343_skitch",
"344_4square",
"345_quora",
"346_google_plus",
"347_spootify",
"348_stumbleupon",
"349_readability",
);
}
function generateSprite($aSymbols, $iCols, $iRows, $iPngWidth, $iPngHeight, $sClassPrefix) {
$iKey = 0;
$aSprites = array();
$iSymbolWidth = $iPngWidth / $iCols;
$iSymbolHeight = $iPngHeight / $iRows;
foreach($aSymbols as $sSymbol) {
$aParts = explode("_", strtolower($sSymbol));
array_shift($aParts);
$sClass = $sClassPrefix . implode("-", $aParts);
$iRowNum = intval($iKey / $iCols);
$iColNum = $iKey % $iCols;
$iX = $iColNum * $iSymbolWidth;
$iY = $iRowNum * $iSymbolHeight;
$aSprites[] = array(
"class" => $sClass,
"x" => round($iX),
"y" => round($iY),
"width" => ceil($iSymbolWidth),
"height" => ceil($iSymbolHeight)
);
$iKey++;
}
##########################################################################
# Generate CSS
$iSpriteWidth = ceil($iSymbolWidth);
$iSpriteHeight = ceil($iSymbolHeight);
$sCss =<<<CSS
.btn-large [class^="{$sClassPrefix}"] {
margin-top: 1px;
}
.btn-small [class^="{$sClassPrefix}"] {
margin-top: -1px;
}
.nav-list [class^="{$sClassPrefix}"] {
margin-right: 2px;
}
[class^="{$sClassPrefix}"],
[class*=" {$sClassPrefix}"] {
display: inline-block;
width: {$iSpriteWidth}px;
height: {$iSpriteHeight}px;
line-height: {$iSpriteHeight}px;
vertical-align: text-top;
background-image: url("{$sClassPrefix}dark.png");
background-position: {$iSpriteWidth}px {$iSpriteHeight}px;
background-repeat: no-repeat;
*margin-right: .3em;
}
[class^="{$sClassPrefix}"]:last-child,
[class*=" {$sClassPrefix}"]:last-child {
*margin-left: 0;
}
.{$sClassPrefix}white {
background-image: url("{$sClassPrefix}white.png");
}
CSS;
reset($aSprites);
foreach($aSprites as $iKey => $aSprite) {
$iX = (-1 * intval($aSprite["x"]));
$iY = (-1 * intval($aSprite["y"]));
if($iX < 0) {
$iX .= "px";
}
if($iY < 0) {
$iY .= "px";
}
$sCss .= <<<CSS
.{$aSprite["class"]} {
background-position: {$iX} {$iY};
}
CSS;
}
$sCss = "\n" . "/* " . count($aSprites) . " glyphs, generated on " . strftime("%Y-%m-%d %H:%M:%S") . "; C=" . $iCols . "; R=" . $iRows . "; W=" . $iPngWidth . "; H=" . $iPngHeight . "; PREFIX=" . $sClassPrefix . " */\n" . $sCss;
return $sCss;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View file

@ -0,0 +1,47 @@
<style type="text/css">
.no-border-left { border-left: none !important;}
.col-displayname { width: 20%;}
.col-description { width: 55%;}
.col-actions { width: 25%;}
p.lead { line-height: 40px;}
table p {
margin-bottom: 0;
}
</style>
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-calendar"></i>Calendars</h1>
<p class="lead">Manage Calendars for<i class="<?= $user->mediumicon() ?>"></i><strong><?= $user->label() ?></strong>.</p>
<p class="pull-left"><a href="<?= \BaikalAdmin\Controller\Users::link() ?>" class="btn"><i class="icon-chevron-left"></i> Back to users list</a></p>
<p class="pull-right"><a class="btn btn btn-inverse" href="<?= \BaikalAdmin\Controller\User\Calendars::linkNew() ?>"><i class="icon-white <?= \Baikal\Model\Calendar::icon() ?>"></i> + Add calendar</a></p>
</header>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Display name</th>
<th>Description</th>
<th class="no-border-left"></th>
</tr>
</thead>
<tbody>
<?
foreach($calendars as $calendar):
$linkedit = \BaikalAdmin\Controller\User\Calendars::linkEdit($calendar);
$linkdelete = \BaikalAdmin\Controller\User\Calendars::linkDelete($calendar);
?>
<tr>
<td class="col-displayname"><i class="<?= $calendar->icon() ?>"></i><?= $calendar->label() ?></td>
<td class="col-description"><?= $calendar->get("description") ?></td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn btn-primary" href="<?= $linkedit ?>"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="<?= $linkdelete ?>"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
<? endforeach ?>
</tbody>
</table>

View file

@ -9,6 +9,8 @@
<!-- Le styles -->
<link href="res/core/TwitterBootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/Templates/Page/style.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro-2x.css" rel="stylesheet" />
<link href="res/core/TwitterBootstrap/css/bootstrap-responsive.css" rel="stylesheet" />
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
@ -26,12 +28,12 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{adminurl}">Baïkal Admin</a>
<a class="brand" href="{homelink}">Baïkal Admin</a>
<div class="nav-collapse">
<ul class="nav">
<li class="active"><a href="{baseurl}">Home</a></li>
<li><a href="#about">Users</a></li>
<li><a href="#contact">Settings</a></li>
<li class="active"><a href="{homelink}">Home</a></li>
<li><a href="{userslink}">Users</a></li>
<li><a href="{settingslink}">Settings</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -1,5 +1,10 @@
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
background: url('page-bg.png') repeat center top;
}
.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th {
background-color: rgb(240, 240, 240);
}
/* Jumbotrons
@ -8,11 +13,10 @@ body {
position: relative;
}
.jumbotron h1 {
margin-bottom: 9px;
font-size: 81px;
font-size: 70px;
font-weight: bold;
letter-spacing: -1px;
line-height: 1;
line-height: 90px;
}
.jumbotron p {
margin-bottom: 18px;

View file

@ -1,40 +0,0 @@
<style type="text/css">
.col-id { width: 2%;}
.col-username { width: 65%;}
.no-border-left { border-left: none !important;}
</style>
<header class="jumbotron subhead" id="overview">
<h1>Users</h1>
<p class="lead pull-left">Browse, create, update and delete Baïkal user accounts.</p>
<p class="pull-right"><a class="btn" href="<?= \BaikalAdmin\Controller\Users::linkNew() ?>"><i class="<?= \Baikal\Model\User::getIcon() ?>"></i> + Add user</a></p>
</header>
<table class="table table-bordered table-striped">
<!--tr>
<th class="col-id">#ID</th>
<th class="col-user"></th>
<th class="col-actions no-border-left"></th>
</tr-->
<? foreach($users as $user) {
$linkdetails = \BaikalAdmin\Controller\Users::linkDetails($user);
$linkedit = \BaikalAdmin\Controller\Users::linkEdit($user);
$linkdelete = \BaikalAdmin\Controller\Users::linkDelete($user);
$mailtouri = $user->getMailtoURI();
?>
<tr>
<!--td class="col-id"><?= $user->get("id"); ?></td-->
<td class="col-username">
<i class="icon-user"></i> <strong><?= $user->get("username"); ?></strong><br />
<?= $user->get("displayname"); ?> <a href="<?= $mailtouri ?>">&lt;<?= $user->get("email"); ?>&gt;</a>
</td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn" href="<?= $linkdetails ?>"><i class="icon-calendar"></i> + <i class="icon-book"></i></a></nobr>
<nobr><a class="btn btn-primary" href="<?= $linkedit ?>"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="<?= $linkdelete ?>"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
<? } ?>
</table>

View file

@ -0,0 +1,44 @@
<style type="text/css">
.col-id { width: 2%;}
.col-username { width: 45%;}
.no-border-left { border-left: none !important;}
p.lead { line-height: 40px;}
table p {
margin-bottom: 0;
}
</style>
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-group"></i>Users</h1>
<p class="lead pull-left">Manage Baïkal user accounts, and associated resources.</p>
<p class="lead pull-right"><a class="btn btn btn-inverse" href="<?= \BaikalAdmin\Controller\Users::linkNew() ?>"><i class="icon-white <?= \Baikal\Model\User::icon() ?>"></i> + Add user</a></p>
</header>
<table class="table table-bordered table-striped">
<?
foreach($users as $user):
$linkcalendars = \BaikalAdmin\Controller\Users::linkCalendars($user);
# $linkcontacts = \BaikalAdmin\Controller\Users::linkContacts($user);
$linkedit = \BaikalAdmin\Controller\Users::linkEdit($user);
$linkdelete = \BaikalAdmin\Controller\Users::linkDelete($user);
$mailtouri = $user->getMailtoURI();
?>
<tr>
<td class="col-username">
<i class="icon-user"></i> <strong><?= $user->get("username"); ?></strong><br />
<?= $user->get("displayname"); ?> <a href="<?= $mailtouri ?>">&lt;<?= $user->get("email"); ?>&gt;</a>
</td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn" href="<?= $linkcalendars ?>"><i class="<?= \Baikal\Model\Calendar::icon() ?>"></i> Calendars</a></nobr>
<nobr><a class="btn" href="<?= $linkcontacts ?>"><i class="icon-book"></i> Contacts</a></nobr>
<nobr><a class="btn btn-primary" href="<?= $linkedit ?>"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="<?= $linkdelete ?>"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
<? endforeach ?>
</table>

View file

@ -26,9 +26,9 @@
namespace BaikalAdmin\Route;
class Details {
class Settings {
public static function execute(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Details());
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Settings());
}
}

View file

@ -24,18 +24,11 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\View\User;
namespace BaikalAdmin\Route\User;
class Form extends \Flake\Core\View {
public function render() {
$oTemplate = new \Flake\Core\Template(BAIKALADMIN_PATH_TEMPLATES . "User/Form.html", TRUE);
$oUser = $this->get("user");
return $oTemplate->parse(array(
"user" => $oUser,
"linkcancel" => \BaikalAdmin\Controller\Users::link(),
"action" => \BaikalAdmin\Controller\Users::linkEdit($oUser),
"messages" => $this->get("messages"),
));
class Calendars {
public static function execute(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\User\Calendars());
}
}

View file

@ -0,0 +1,30 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
* All rights reserved
*
* http://baikal.codr.fr
*
* This script is part of the Baïkal Server project. The Baïkal
* Server project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\View\Calendars;
class Listing extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
* All rights reserved
*
* http://baikal.codr.fr
*
* This script is part of the Baïkal Server project. The Baïkal
* Server project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace BaikalAdmin\View\Users;
class Listing extends \BaikalAdmin\Core\View {
}

View file

@ -29,6 +29,7 @@ define("BAIKALADMIN_PATH_TEMPLATES", BAIKALADMIN_PATH_ROOT . "Resources/Template
$GLOBALS["ROUTES"] = array(
"default" => "\BaikalAdmin\Route\Dashboard",
"users" => "\BaikalAdmin\Route\Users",
"users/details" => "\BaikalAdmin\Route\Details",
"install" => "\BaikalAdmin\Route\Install"
"users/calendars" => "\BaikalAdmin\Route\User\Calendars",
"install" => "\BaikalAdmin\Route\Install",
"settings" => "\BaikalAdmin\Route\Settings"
);

View file

@ -44,10 +44,18 @@ $oPage->setTitle("Baïkal Web Admin");
$oPage->setBaseUrl(BAIKAL_URI);
$sControllerForDefaultRoute = $GLOBALS["ROUTER"]::getControllerForRoute("default");
$oPage->zone("adminurl")->addBlock(new \Flake\Controller\HtmlBlock(
$oPage->zone("homelink")->addBlock(new \Flake\Controller\HtmlBlock(
$sControllerForDefaultRoute::link()
));
$oPage->zone("userslink")->addBlock(new \Flake\Controller\HtmlBlock(
\BaikalAdmin\Controller\Users::link()
));
$oPage->zone("settingslink")->addBlock(new \Flake\Controller\HtmlBlock(
\BaikalAdmin\Controller\Settings::link()
));
# Route the request
$GLOBALS["ROUTER"]::route($oPage);

View file

@ -72,4 +72,15 @@ date_default_timezone_set(FLAKE_TIMEZONE);
$GLOBALS["DB"] = new \Flake\Core\Database\Sqlite();
$GLOBALS["DB"]->init(FLAKE_DB_FILEPATH);
$GLOBALS["TEMPLATESTACK"] = array();
$GLOBALS["TEMPLATESTACK"] = array();
# Determining baikal protocol, domain and uri-path (looking at BAIKAL_URI)
if($GLOBALS["_SERVER"]["SERVER_NAME"] === "mongoose") { # And not using MONGOOSE_SERVER constant, as it will be defined by Flake, later in the process
define("FLAKE_DOMAIN", "");
define("FLAKE_URIPATH", "");
} else {
$aUrlInfo = parse_url(BAIKAL_URI);
define("FLAKE_DOMAIN", $aUrlInfo["host"]);
define("FLAKE_URIPATH", \Flake\Util\Tools::stripBeginSlash($aUrlInfo["path"]));
unset($aUrlInfo);
}

View file

@ -34,9 +34,7 @@ abstract class Controller extends \Flake\Core\FLObject {
$this->aParams = $aParams;
}
abstract function execute();
abstract function render();
static function link(/*[$sParam, $sParam2, ...]*/) {
public static function link(/*[$sParam, $sParam2, ...]*/) {
return static::buildRoute();
}
@ -46,4 +44,7 @@ abstract class Controller extends \Flake\Core\FLObject {
array_unshift($aParams, $sController); # Injecting current controller as first param
return call_user_func_array($GLOBALS["ROUTER"] . "::buildRouteForController", $aParams);
}
public abstract function execute();
public abstract function render();
}

View file

@ -51,16 +51,36 @@ abstract class Model extends \Flake\Core\FLObject {
throw new \Exception("\Flake\Core\Model->set(): property " . htmlspecialchars($sPropName) . " does not exist on " . get_class($this));
}
public function getLabel() {
public function label() {
return $this->get($this::LABELFIELD);
}
public static function getIcon() {
public static function icon() {
return "icon-book";
}
public static function getHumanName() {
public static function mediumicon() {
return "glyph-book";
}
public static function bigicon() {
return "glyph2x-book";
}
public static function humanName() {
$aRes = explode("\\", get_called_class());
return array_pop($aRes);
}
public function formForThisModelInstance($options = array()) {
$sClass = get_class($this);
$oForm = new \Formal\Form($sClass, $options);
$oForm->setModelInstance($this);
return $oForm;
}
public function formMorphologyForThisModelInstance() {
throw new \Exception(get_class($this) . ": No form morphology provided for Model.");
}
}

View file

@ -31,7 +31,7 @@ abstract class Requester extends \Flake\Core\FLObject {
$this->sModelClass = $sModelClass;
}
public function addClause($sField, $sValue) {
protected function addClause($sField, $sValue) {
$this->addClauseEquals($sField, $sValue);
return $this;
}

View file

@ -26,7 +26,7 @@
namespace Flake\Core;
class View extends \Flake\Core\FLObject {
abstract class View extends \Flake\Core\FLObject {
protected $aData;
public function __construct() {
@ -48,4 +48,12 @@ class View extends \Flake\Core\FLObject {
return FALSE;
}
public function render() {
$sTemplatePath = $this->templatesPath();
$oTemplate = new \Flake\Core\Template($this->templatesPath(), TRUE);
return $oTemplate->parse($this->getData());
}
public abstract function templatesPath();
}

View file

@ -28,6 +28,8 @@ namespace Flake\Util;
abstract class Router extends \Flake\Core\FLObject {
static $sURIPath = "";
/* ----------------------- COMMON METHODS ------------------------------*/
private function __construct() {
@ -92,6 +94,14 @@ abstract class Router extends \Flake\Core\FLObject {
return call_user_func_array($GLOBALS["ROUTER"] . "::buildRoute", $aParams);
}
public static function setURIPath($sURIPath) {
static::$sURIPath = $sURIPath;
}
public static function getUriPath() {
return FLAKE_URIPATH . static::$sURIPath;
}
/* ----------------------- CHANGING METHODS ----------------------------*/
# this method is likely to change with every Router implementation
@ -105,10 +115,16 @@ abstract class Router extends \Flake\Core\FLObject {
}
if($sRoute === "default" && empty($aParams)) {
return "/";
$sUrl = "/";
} else {
$sUrl = "/" . $sRoute . "/" . $sParams;
}
return "/" . $sRoute . "/" . $sParams;
if(self::getUriPath() !== "") {
$sUrl = "/" . self::getUriPath() . $sUrl;
}
return $sUrl;
}
# should be abstract, but is not, because of PHP's strict standards

View file

@ -70,13 +70,32 @@ class QuestionMarkRewrite extends \Flake\Util\Router {
public static function buildRoute($sRoute /* [, $sParam, $sParam2, ...] */) {
$aParams = func_get_args();
$sUrl = call_user_func_array("parent::buildRoute", $aParams);
array_shift($aParams); # Stripping $sRoute
if($sUrl === "/") {
return "";
$sParams = implode("/", $aParams);
if(trim($sParams) !== "") {
$sParams .= "/";
}
return "?" . $sUrl;
if($sRoute === "default" && empty($aParams)) {
$sUrl = "/";
} else {
$sUrl = "/" . $sRoute . "/" . $sParams;
}
if(self::getUriPath() === "") {
if($sUrl !== "/") {
$sUrl = "?" . $sUrl;
}
} else {
if($sUrl !== "/") {
$sUrl = "/" . self::getUriPath() . "?" . $sUrl;
} else {
$sUrl = "/" . self::getUriPath();
}
}
return $sUrl;
}
public static function getURLParams() {

View file

@ -73,8 +73,22 @@ class Tools extends \Flake\Core\FLObject {
$result.= '<tr><td valign="top"><font face="Verdana,Arial" size="1">'.htmlspecialchars((string)$key).'</font></td><td>';
if (is_array($array_in[$key])) {
$result.= \Flake\Util\Tools::view_array($array_in[$key]);
} else
$result.= '<font face="Verdana,Arial" size="1" color="red">'.nl2br(htmlspecialchars((string)$val)).'<br /></font>';
} else {
if(is_object($val)) {
if(method_exists($val, "__toString")) {
$sWhat = nl2br(htmlspecialchars((string)$val));
} else {
$sWhat = nl2br(htmlspecialchars(get_class($val)));
}
} elseif(is_bool($val)) {
$sWhat = ($val === TRUE ? "boolean:TRUE" : "boolean:FALSE");
} else {
$sWhat = nl2br(htmlspecialchars((string)$val));
}
$result .= '<font face="Verdana,Arial" size="1" color="red">' . $sWhat . '<br /></font>';
}
$result.= '</td></tr>';
}
$result.= '</table>';

View file

@ -0,0 +1,67 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
* All rights reserved
*
* http://baikal.codr.fr
*
* This script is part of the Baïkal Server project. The Baïkal
* Server project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
namespace Formal\Element;
class Checkbox extends \Formal\Element {
public function setValue($sValue) {
# Boolean
$this->sValue = ((intval($sValue) === 1));
}
public function render() {
$disabled = "";
$inputclass = "";
$groupclass = "";
$value = $this->value();
$checked = ($value === TRUE ? " checked=\"checked\" " : "");
$label = $this->option("label");
$prop = $this->option("prop");
if($this->option("readonly") === TRUE) {
$inputclass .= " disabled";
$disabled = " disabled";
}
if($this->option("error") === TRUE) {
$groupclass .= " error";
}
$sHtml =<<<HTML
<div class="control-group{$groupclass}">
<label class="control-label" for="displayname">{$label}</label>
<div class="controls">
<input type="checkbox" class="input-xlarge{$inputclass}" id="{$prop}" name="{$prop}" value="1"{$checked}{$disabled}/>
</div>
</div>
HTML;
return $sHtml;
}
}

View file

@ -26,40 +26,9 @@
namespace Formal\Element;
class Password extends \Formal\Element {
class Password extends \Formal\Element\Text {
public function render() {
$disabled = "";
$inputclass = "";
$groupclass = "";
$placeholder = "";
$value = htmlspecialchars($this->value());
$label = $this->option("label");
$prop = $this->option("prop");
$placeholder = $this->option("placeholder");
if($this->option("readonly") === TRUE) {
$inputclass .= " disabled";
$disabled = " disabled";
}
if($this->option("error") === TRUE) {
$groupclass .= " error";
}
if(($sPlaceHolder = trim($this->option("placeholder"))) !== "") {
$placeholder = " placeholder=\"" . htmlspecialchars($sPlaceHolder) . "\" ";
}
$sHtml =<<<HTML
<div class="control-group{$groupclass}">
<label class="control-label" for="displayname">{$label}</label>
<div class="controls">
<input type="password" class="input-xlarge{$inputclass}" id="{$prop}" name="{$prop}" value="{$value}"{$disabled}{$placeholder}/>
</div>
</div>
HTML;
return $sHtml;
protected function inputtype() {
return "password";
}
}

View file

@ -28,13 +28,20 @@ namespace Formal\Element;
class Text extends \Formal\Element {
protected function inputtype() {
return "text";
}
public function render() {
$value = htmlspecialchars($this->value());
$label = $this->option("label");
$prop = $this->option("prop");
$disabled = "";
$inputclass = "";
$groupclass = "";
$placeholder = "";
$value = htmlspecialchars($this->value());
$label = $this->option("label");
$prop = $this->option("prop");
$placeholder = $this->option("placeholder");
if($this->option("readonly") === TRUE) {
$inputclass .= " disabled";
@ -45,11 +52,17 @@ class Text extends \Formal\Element {
$groupclass .= " error";
}
if(($sPlaceHolder = trim($this->option("placeholder"))) !== "") {
$placeholder = " placeholder=\"" . htmlspecialchars($sPlaceHolder) . "\" ";
}
$sInputType = $this->inputtype();
$sHtml =<<<HTML
<div class="control-group{$groupclass}">
<label class="control-label" for="displayname">{$label}</label>
<div class="controls">
<input type="text" class="input-xlarge{$inputclass}" id="{$prop}" name="{$prop}" value="{$value}"{$disabled} />
<input type="{$sInputType}" class="input-xlarge{$inputclass}" id="{$prop}" name="{$prop}" value="{$value}"{$disabled}{$placeholder}/>
</div>
</div>
HTML;

View file

@ -74,7 +74,7 @@ class Form {
$this->oElements->reset();
foreach($this->oElements as $oElement) {
$oElement->setValue(
$this->getModelInstance()->get(
$this->modelInstance()->get(
$oElement->option("prop")
)
);
@ -83,25 +83,26 @@ class Form {
# Displayed form title is generated depending on modelInstance floatingness
if($this->floatingModelInstance()) {
$this->sDisplayTitle = "Creating new " . $this->getModelInstance()->getHumanName();
$this->sDisplayTitle = "Creating new<i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->humanName() . "</strong>";
} else {
$this->sDisplayTitle = "Editing " . $this->getModelInstance()->getHumanName() . " <strong>" . $this->getModelInstance()->getLabel() . "</strong>";
# This is changed if form is persisted, after persistance, to reflect possible change in model instance label
$this->sDisplayTitle = "Editing " . $this->modelInstance()->humanName() . "<i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->label() . "</strong>";
}
return $this;
}
public function getModelInstance() {
public function modelInstance() {
return $this->oModelInstance;
}
public function floatingModelInstance() {
return $this->getModelInstance()->floating();
return $this->modelInstance()->floating();
}
public function execute() {
# Obtaining morphology from model object
$oMorpho = $this->getModelInstance()->formMorphologyForThisModelInstance();
$oMorpho = $this->modelInstance()->formMorphologyForThisModelInstance();
$this->aErrors = array();
$oMorpho->elements()->reset();
@ -119,7 +120,7 @@ class Form {
$sValue = $oElement->value();
$this->getModelInstance()->set(
$this->modelInstance()->set(
$sPropName,
$sValue
);
@ -178,15 +179,21 @@ class Form {
if($this->floatingModelInstance()) {
$this->sDisplayMessage = \Formal\Core\Message::notice(
$this->getModelInstance()->getHumanName() . " <i class='" . $this->getModelInstance()->getIcon() . "'></i> <strong>" . $this->getModelInstance()->getLabel() . "</strong> has been created."
$this->modelInstance()->humanName() . " <i class='" . $this->modelInstance()->icon() . "'></i> <strong>" . $this->modelInstance()->label() . "</strong> has been created."
);
$bWasFloating = TRUE;
} else {
$bWasFloating = FALSE;
$this->sDisplayMessage = \Formal\Core\Message::notice(
"Changes on <i class='" . $this->getModelInstance()->getIcon() . "'></i> <strong>" . $this->getModelInstance()->getLabel() . "</strong> have been saved."
"Changes on <i class='" . $this->modelInstance()->icon() . "'></i> <strong>" . $this->modelInstance()->label() . "</strong> have been saved."
);
}
$this->getModelInstance()->persist();
$this->modelInstance()->persist();
if($bWasFloating === FALSE) {
# Title is generated now, as submitted data might have changed the model instance label
$this->sDisplayTitle = "Editing " . $this->modelInstance()->humanName() . "<strong><i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->label() . "</strong>";
}
$this->bPersisted = TRUE;
} else {
$this->bPersisted = FALSE;
@ -227,10 +234,24 @@ class Form {
}
public function validateUnique($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
$oColl = $this->getModelInstance()->getBaseRequester()->addClauseEquals(
$oModelInstance = $this->modelInstance();
$oRequest = $oModelInstance->getBaseRequester()->addClauseEquals(
$oElement->option("prop"),
$sValue
)->execute();
);
if(!$oModelInstance->floating()) {
# checking id only if model instance is not floating
$oRequest->addClauseNotEquals(
$oModelInstance::PRIMARYKEY,
$oModelInstance->get(
$oModelInstance::PRIMARYKEY
)
);
}
$oColl = $oRequest->execute();
if($oColl->count() > 0) {
return "<strong>" . $oElement->option("label") . "</strong> has to be unique. Given value is not available.";
@ -239,6 +260,14 @@ class Form {
return TRUE;
}
public function validateTokenid($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
if(!preg_match("/^[a-z0-9\-]+$/", $sValue)) {
return "<strong>" . $oElement->option("label") . "</strong> is not valid. Allowed characters are digits, lowercase letters and the dash symbol '-'.";
}
return TRUE;
}
public function postValue($sPropName) {
return \Flake\Util\Tools::POST($sPropName);
}
@ -246,7 +275,7 @@ class Form {
public function render() {
$aHtml = array();
$oMorpho = $this->getModelInstance()->formMorphologyForThisModelInstance();
$oMorpho = $this->modelInstance()->formMorphologyForThisModelInstance();
$oMorpho->elements()->reset();
foreach($oMorpho->elements() as $oElement) {
@ -256,7 +285,7 @@ class Form {
# And obtained from Model instance
$oElement->setValue(
$this->getModelInstance()->get(
$this->modelInstance()->get(
$oElement->option("prop")
)
);
@ -297,7 +326,7 @@ class Form {
<form class="form-horizontal" action="{$sActionUrl}" method="post" enctype="multipart/formdata">
<input type="hidden" name="{$sSubmittedFlagName}" value="1" />
<fieldset>
<legend>{$this->sDisplayTitle}</legend>
<legend style="line-height: 40px;">{$this->sDisplayTitle}</legend>
{$this->sDisplayMessage}
{$elements}
<div class="form-actions">

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -33,7 +33,7 @@
define("BAIKAL_TIMEZONE", "Europe/Paris");
# Absolute Baïkal URI; end with slash; includes protocol (http:// or https://), port (optional) and subfolders if any
if($_SERVER["SERVER_NAME"] === "mongoose") {
if(array_key_exists("SERVER_NAME", $_SERVER) && $_SERVER["SERVER_NAME"] === "mongoose") {
define("BAIKAL_URI", "/");
} elseif(array_key_exists("HTTP_HOST", $_SERVER) && $_SERVER["HTTP_HOST"] === "subbaikal.jeromeschneider.fr") {
define("BAIKAL_URI", "http://subbaikal.jeromeschneider.fr/html/");

Binary file not shown.

View file

@ -0,0 +1,381 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Glyphro 2x</title>
<base href="http://baikal.jeromeschneider.fr/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Le styles -->
<link href="res/core/TwitterBootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/Templates/Page/style.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro-2x.css" rel="stylesheet" />
<link href="res/core/TwitterBootstrap/css/bootstrap-responsive.css" rel="stylesheet" />
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<i class="glyph2x-glass"></i>
<i class="glyph2x-leaf"></i>
<i class="glyph2x-dog"></i>
<i class="glyph2x-user"></i>
<i class="glyph2x-girl"></i>
<i class="glyph2x-car"></i>
<i class="glyph2x-user-add"></i>
<i class="glyph2x-user-remove"></i>
<i class="glyph2x-film"></i>
<i class="glyph2x-magic"></i>
<i class="glyph2x-envelope"></i>
<i class="glyph2x-camera"></i>
<i class="glyph2x-heart"></i>
<i class="glyph2x-beach-umbrella"></i>
<i class="glyph2x-train"></i>
<i class="glyph2x-print"></i>
<i class="glyph2x-bin"></i>
<i class="glyph2x-music"></i>
<i class="glyph2x-note"></i>
<i class="glyph2x-cogwheel"></i>
<i class="glyph2x-home"></i>
<i class="glyph2x-snowflake"></i>
<i class="glyph2x-fire"></i>
<i class="glyph2x-cogwheels"></i>
<i class="glyph2x-parents"></i>
<i class="glyph2x-binoculars"></i>
<i class="glyph2x-road"></i>
<i class="glyph2x-search"></i>
<i class="glyph2x-cars"></i>
<i class="glyph2x-notes-2"></i>
<i class="glyph2x-pencil"></i>
<i class="glyph2x-bus"></i>
<i class="glyph2x-wifi-alt"></i>
<i class="glyph2x-luggage"></i>
<i class="glyph2x-old-man"></i>
<i class="glyph2x-woman"></i>
<i class="glyph2x-file"></i>
<i class="glyph2x-credit"></i>
<i class="glyph2x-airplane"></i>
<i class="glyph2x-notes"></i>
<i class="glyph2x-stats"></i>
<i class="glyph2x-charts"></i>
<i class="glyph2x-pie-chart"></i>
<i class="glyph2x-group"></i>
<i class="glyph2x-keys"></i>
<i class="glyph2x-calendar"></i>
<i class="glyph2x-router"></i>
<i class="glyph2x-camera-small"></i>
<i class="glyph2x-dislikes"></i>
<i class="glyph2x-star"></i>
<i class="glyph2x-link"></i>
<i class="glyph2x-eye-open"></i>
<i class="glyph2x-eye-close"></i>
<i class="glyph2x-alarm"></i>
<i class="glyph2x-clock"></i>
<i class="glyph2x-stopwatch"></i>
<i class="glyph2x-projector"></i>
<i class="glyph2x-history"></i>
<i class="glyph2x-truck"></i>
<i class="glyph2x-cargo"></i>
<i class="glyph2x-compass"></i>
<i class="glyph2x-keynote"></i>
<i class="glyph2x-attach"></i>
<i class="glyph2x-power"></i>
<i class="glyph2x-lightbulb"></i>
<i class="glyph2x-tag"></i>
<i class="glyph2x-tags"></i>
<i class="glyph2x-cleaning"></i>
<i class="glyph2x-ruller"></i>
<i class="glyph2x-gift"></i>
<i class="glyph2x-umbrella"></i>
<i class="glyph2x-book"></i>
<i class="glyph2x-bookmark"></i>
<i class="glyph2x-signal"></i>
<i class="glyph2x-cup"></i>
<i class="glyph2x-stroller"></i>
<i class="glyph2x-headphones"></i>
<i class="glyph2x-headset"></i>
<i class="glyph2x-warning-sign"></i>
<i class="glyph2x-signal"></i>
<i class="glyph2x-retweet"></i>
<i class="glyph2x-refresh"></i>
<i class="glyph2x-roundabout"></i>
<i class="glyph2x-random"></i>
<i class="glyph2x-heat"></i>
<i class="glyph2x-repeat"></i>
<i class="glyph2x-display"></i>
<i class="glyph2x-log-book"></i>
<i class="glyph2x-adress-book"></i>
<i class="glyph2x-magnet"></i>
<i class="glyph2x-table"></i>
<i class="glyph2x-adjust"></i>
<i class="glyph2x-tint"></i>
<i class="glyph2x-crop"></i>
<i class="glyph2x-vector-path-square"></i>
<i class="glyph2x-vector-path-circle"></i>
<i class="glyph2x-vector-path-polygon"></i>
<i class="glyph2x-vector-path-line"></i>
<i class="glyph2x-vector-path-curve"></i>
<i class="glyph2x-vector-path-all"></i>
<i class="glyph2x-font"></i>
<i class="glyph2x-italic"></i>
<i class="glyph2x-bold"></i>
<i class="glyph2x-text-underline"></i>
<i class="glyph2x-text-strike"></i>
<i class="glyph2x-text-height"></i>
<i class="glyph2x-text-width"></i>
<i class="glyph2x-text-resize"></i>
<i class="glyph2x-left-indent"></i>
<i class="glyph2x-right-indent"></i>
<i class="glyph2x-align-left"></i>
<i class="glyph2x-align-center"></i>
<i class="glyph2x-align-right"></i>
<i class="glyph2x-justify"></i>
<i class="glyph2x-list"></i>
<i class="glyph2x-text-smaller"></i>
<i class="glyph2x-text-bigger"></i>
<i class="glyph2x-embed"></i>
<i class="glyph2x-embed-close"></i>
<i class="glyph2x-adjust"></i>
<i class="glyph2x-message-full"></i>
<i class="glyph2x-message-empty"></i>
<i class="glyph2x-message-in"></i>
<i class="glyph2x-message-out"></i>
<i class="glyph2x-message-plus"></i>
<i class="glyph2x-message-minus"></i>
<i class="glyph2x-message-ban"></i>
<i class="glyph2x-message-flag"></i>
<i class="glyph2x-message-lock"></i>
<i class="glyph2x-message-new"></i>
<i class="glyph2x-inbox"></i>
<i class="glyph2x-inbox-plus"></i>
<i class="glyph2x-inbox-minus"></i>
<i class="glyph2x-inbox-lock"></i>
<i class="glyph2x-inbox-in"></i>
<i class="glyph2x-inbox-out"></i>
<i class="glyph2x-computer-locked"></i>
<i class="glyph2x-computer-service"></i>
<i class="glyph2x-computer-proces"></i>
<i class="glyph2x-phone"></i>
<i class="glyph2x-database-lock"></i>
<i class="glyph2x-database-plus"></i>
<i class="glyph2x-database-minus"></i>
<i class="glyph2x-database-ban"></i>
<i class="glyph2x-folder-open"></i>
<i class="glyph2x-folder-plus"></i>
<i class="glyph2x-folder-minus"></i>
<i class="glyph2x-folder-lock"></i>
<i class="glyph2x-folder-flag"></i>
<i class="glyph2x-folder-new"></i>
<i class="glyph2x-check"></i>
<i class="glyph2x-edit"></i>
<i class="glyph2x-new-window"></i>
<i class="glyph2x-more-windows"></i>
<i class="glyph2x-show-big-thumbnails"></i>
<i class="glyph2x-show-thumbnails"></i>
<i class="glyph2x-show-thumbnails-with-lines"></i>
<i class="glyph2x-show-lines"></i>
<i class="glyph2x-playlist"></i>
<i class="glyph2x-picture"></i>
<i class="glyph2x-imac"></i>
<i class="glyph2x-macbook"></i>
<i class="glyph2x-ipad"></i>
<i class="glyph2x-iphone"></i>
<i class="glyph2x-iphone-transfer"></i>
<i class="glyph2x-iphone-exchange"></i>
<i class="glyph2x-ipod"></i>
<i class="glyph2x-ipod-shuffle"></i>
<i class="glyph2x-ear-plugs"></i>
<i class="glyph2x-albums"></i>
<i class="glyph2x-step-backward"></i>
<i class="glyph2x-fast-backward"></i>
<i class="glyph2x-rewind"></i>
<i class="glyph2x-play"></i>
<i class="glyph2x-pause"></i>
<i class="glyph2x-stop"></i>
<i class="glyph2x-forward"></i>
<i class="glyph2x-fast-forward"></i>
<i class="glyph2x-step-forward"></i>
<i class="glyph2x-eject"></i>
<i class="glyph2x-facetime-video"></i>
<i class="glyph2x-download-alt"></i>
<i class="glyph2x-mute"></i>
<i class="glyph2x-volume-down"></i>
<i class="glyph2x-volume-up"></i>
<i class="glyph2x-screenshot"></i>
<i class="glyph2x-move"></i>
<i class="glyph2x-more"></i>
<i class="glyph2x-brightness-reduce"></i>
<i class="glyph2x-brightness-increase"></i>
<i class="glyph2x-circle-plus"></i>
<i class="glyph2x-circle-minus"></i>
<i class="glyph2x-circle-remove"></i>
<i class="glyph2x-circle-ok"></i>
<i class="glyph2x-circle-question-mark"></i>
<i class="glyph2x-circle-info"></i>
<i class="glyph2x-circle-exclamation-mark"></i>
<i class="glyph2x-remove"></i>
<i class="glyph2x-ok"></i>
<i class="glyph2x-ban"></i>
<i class="glyph2x-download"></i>
<i class="glyph2x-upload"></i>
<i class="glyph2x-shopping-cart"></i>
<i class="glyph2x-lock"></i>
<i class="glyph2x-unlock"></i>
<i class="glyph2x-electricity"></i>
<i class="glyph2x-ok-2"></i>
<i class="glyph2x-remove-2"></i>
<i class="glyph2x-cart-out"></i>
<i class="glyph2x-cart-in"></i>
<i class="glyph2x-left-arrow"></i>
<i class="glyph2x-right-arrow"></i>
<i class="glyph2x-down-arrow"></i>
<i class="glyph2x-up-arrow"></i>
<i class="glyph2x-resize-small"></i>
<i class="glyph2x-resize-full"></i>
<i class="glyph2x-circle-arrow-left"></i>
<i class="glyph2x-circle-arrow-right"></i>
<i class="glyph2x-circle-arrow-right"></i>
<i class="glyph2x-circle-arrow-right"></i>
<i class="glyph2x-play-button"></i>
<i class="glyph2x-unshare"></i>
<i class="glyph2x-share"></i>
<i class="glyph2x-thin-right-arrow"></i>
<i class="glyph2x-thin-arrow-left"></i>
<i class="glyph2x-bluetooth"></i>
<i class="glyph2x-euro"></i>
<i class="glyph2x-usd"></i>
<i class="glyph2x-bp"></i>
<i class="glyph2x-retweet-2"></i>
<i class="glyph2x-moon"></i>
<i class="glyph2x-sun"></i>
<i class="glyph2x-cloud"></i>
<i class="glyph2x-direction"></i>
<i class="glyph2x-brush"></i>
<i class="glyph2x-pen"></i>
<i class="glyph2x-zoom-in"></i>
<i class="glyph2x-zoom-out"></i>
<i class="glyph2x-pin"></i>
<i class="glyph2x-riflescope"></i>
<i class="glyph2x-rotation-lock"></i>
<i class="glyph2x-flash"></i>
<i class="glyph2x-google-maps"></i>
<i class="glyph2x-anchor"></i>
<i class="glyph2x-conversation"></i>
<i class="glyph2x-chat"></i>
<i class="glyph2x-male"></i>
<i class="glyph2x-female"></i>
<i class="glyph2x-asterisk"></i>
<i class="glyph2x-divide"></i>
<i class="glyph2x-snorkel-diving"></i>
<i class="glyph2x-scuba-diving"></i>
<i class="glyph2x-oxygen-bottle"></i>
<i class="glyph2x-fins"></i>
<i class="glyph2x-fishes"></i>
<i class="glyph2x-boat"></i>
<i class="glyph2x-delete-point"></i>
<i class="glyph2x-sheriffs--star"></i>
<i class="glyph2x-qrcode"></i>
<i class="glyph2x-barcode"></i>
<i class="glyph2x-pool"></i>
<i class="glyph2x-buoy"></i>
<i class="glyph2x-spade"></i>
<i class="glyph2x-bank"></i>
<i class="glyph2x-vcard"></i>
<i class="glyph2x-electrical-plug"></i>
<i class="glyph2x-flag"></i>
<i class="glyph2x-credit-card"></i>
<i class="glyph2x-keyboard-wireless"></i>
<i class="glyph2x-keyboard-wired"></i>
<i class="glyph2x-shield"></i>
<i class="glyph2x-ring"></i>
<i class="glyph2x-cake"></i>
<i class="glyph2x-drink"></i>
<i class="glyph2x-beer"></i>
<i class="glyph2x-fast-food"></i>
<i class="glyph2x-cutlery"></i>
<i class="glyph2x-pizza"></i>
<i class="glyph2x-birthday-cake"></i>
<i class="glyph2x-tablet"></i>
<i class="glyph2x-settings"></i>
<i class="glyph2x-bullets"></i>
<i class="glyph2x-cardio"></i>
<i class="glyph2x-t-shirt"></i>
<i class="glyph2x-pants"></i>
<i class="glyph2x-sweater"></i>
<i class="glyph2x-fabric"></i>
<i class="glyph2x-leather"></i>
<i class="glyph2x-scissors"></i>
<i class="glyph2x-podium"></i>
<i class="glyph2x-skull"></i>
<i class="glyph2x-celebration"></i>
<i class="glyph2x-tea-kettle"></i>
<i class="glyph2x-french-press"></i>
<i class="glyph2x-coffe-cup"></i>
<i class="glyph2x-pot"></i>
<i class="glyph2x-grater"></i>
<i class="glyph2x-kettle"></i>
<i class="glyph2x-hospital"></i>
<i class="glyph2x-hospital-h"></i>
<i class="glyph2x-microphone"></i>
<i class="glyph2x-webcam"></i>
<i class="glyph2x-temple-christianity-church"></i>
<i class="glyph2x-temple-islam"></i>
<i class="glyph2x-temple-hindu"></i>
<i class="glyph2x-temple-buddhist"></i>
<i class="glyph2x-electrical-socket-eu"></i>
<i class="glyph2x-electrical-socket-us"></i>
<i class="glyph2x-bomb"></i>
<i class="glyph2x-comments"></i>
<i class="glyph2x-flower"></i>
<i class="glyph2x-baseball"></i>
<i class="glyph2x-rugby"></i>
<i class="glyph2x-ax"></i>
<i class="glyph2x-table-tennis"></i>
<i class="glyph2x-bowling"></i>
<i class="glyph2x-tree-conifer"></i>
<i class="glyph2x-tree-deciduous"></i>
<i class="glyph2x-more-items"></i>
<i class="glyph2x-sort"></i>
<i class="glyph2x-facebook"></i>
<i class="glyph2x-twitter-t"></i>
<i class="glyph2x-twitter"></i>
<i class="glyph2x-buzz"></i>
<i class="glyph2x-vimeo"></i>
<i class="glyph2x-flickr"></i>
<i class="glyph2x-last-fm"></i>
<i class="glyph2x-rss"></i>
<i class="glyph2x-skype"></i>
<i class="glyph2x-e-mail"></i>
<i class="glyph2x-instapaper"></i>
<i class="glyph2x-evernote"></i>
<i class="glyph2x-xing"></i>
<i class="glyph2x-zootool"></i>
<i class="glyph2x-dribbble"></i>
<i class="glyph2x-deviantart"></i>
<i class="glyph2x-read-it-later"></i>
<i class="glyph2x-linked-in"></i>
<i class="glyph2x-forrst"></i>
<i class="glyph2x-pinboard"></i>
<i class="glyph2x-behance"></i>
<i class="glyph2x-github"></i>
<i class="glyph2x-youtube"></i>
<i class="glyph2x-skitch"></i>
<i class="glyph2x-4square"></i>
<i class="glyph2x-quora"></i>
<i class="glyph2x-google-plus"></i>
<i class="glyph2x-spootify"></i>
<i class="glyph2x-stumbleupon"></i>
<i class="glyph2x-readability"></i>
</div> <!-- /container -->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="res/core/TwitterBootstrap/js/jquery-1.7.1.min.js"></script>
<script src="res/core/TwitterBootstrap/js/bootstrap.min.js"></script>
</body>
</html>

View file

@ -0,0 +1,381 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Glyphro</title>
<base href="http://baikal.jeromeschneider.fr/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Le styles -->
<link href="res/core/TwitterBootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/Templates/Page/style.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro-2x.css" rel="stylesheet" />
<link href="res/core/TwitterBootstrap/css/bootstrap-responsive.css" rel="stylesheet" />
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<i class="glyph-glass"></i>
<i class="glyph-leaf"></i>
<i class="glyph-dog"></i>
<i class="glyph-user"></i>
<i class="glyph-girl"></i>
<i class="glyph-car"></i>
<i class="glyph-user-add"></i>
<i class="glyph-user-remove"></i>
<i class="glyph-film"></i>
<i class="glyph-magic"></i>
<i class="glyph-envelope"></i>
<i class="glyph-camera"></i>
<i class="glyph-heart"></i>
<i class="glyph-beach-umbrella"></i>
<i class="glyph-train"></i>
<i class="glyph-print"></i>
<i class="glyph-bin"></i>
<i class="glyph-music"></i>
<i class="glyph-note"></i>
<i class="glyph-cogwheel"></i>
<i class="glyph-home"></i>
<i class="glyph-snowflake"></i>
<i class="glyph-fire"></i>
<i class="glyph-cogwheels"></i>
<i class="glyph-parents"></i>
<i class="glyph-binoculars"></i>
<i class="glyph-road"></i>
<i class="glyph-search"></i>
<i class="glyph-cars"></i>
<i class="glyph-notes-2"></i>
<i class="glyph-pencil"></i>
<i class="glyph-bus"></i>
<i class="glyph-wifi-alt"></i>
<i class="glyph-luggage"></i>
<i class="glyph-old-man"></i>
<i class="glyph-woman"></i>
<i class="glyph-file"></i>
<i class="glyph-credit"></i>
<i class="glyph-airplane"></i>
<i class="glyph-notes"></i>
<i class="glyph-stats"></i>
<i class="glyph-charts"></i>
<i class="glyph-pie-chart"></i>
<i class="glyph-group"></i>
<i class="glyph-keys"></i>
<i class="glyph-calendar"></i>
<i class="glyph-router"></i>
<i class="glyph-camera-small"></i>
<i class="glyph-dislikes"></i>
<i class="glyph-star"></i>
<i class="glyph-link"></i>
<i class="glyph-eye-open"></i>
<i class="glyph-eye-close"></i>
<i class="glyph-alarm"></i>
<i class="glyph-clock"></i>
<i class="glyph-stopwatch"></i>
<i class="glyph-projector"></i>
<i class="glyph-history"></i>
<i class="glyph-truck"></i>
<i class="glyph-cargo"></i>
<i class="glyph-compass"></i>
<i class="glyph-keynote"></i>
<i class="glyph-attach"></i>
<i class="glyph-power"></i>
<i class="glyph-lightbulb"></i>
<i class="glyph-tag"></i>
<i class="glyph-tags"></i>
<i class="glyph-cleaning"></i>
<i class="glyph-ruller"></i>
<i class="glyph-gift"></i>
<i class="glyph-umbrella"></i>
<i class="glyph-book"></i>
<i class="glyph-bookmark"></i>
<i class="glyph-signal"></i>
<i class="glyph-cup"></i>
<i class="glyph-stroller"></i>
<i class="glyph-headphones"></i>
<i class="glyph-headset"></i>
<i class="glyph-warning-sign"></i>
<i class="glyph-signal"></i>
<i class="glyph-retweet"></i>
<i class="glyph-refresh"></i>
<i class="glyph-roundabout"></i>
<i class="glyph-random"></i>
<i class="glyph-heat"></i>
<i class="glyph-repeat"></i>
<i class="glyph-display"></i>
<i class="glyph-log-book"></i>
<i class="glyph-adress-book"></i>
<i class="glyph-magnet"></i>
<i class="glyph-table"></i>
<i class="glyph-adjust"></i>
<i class="glyph-tint"></i>
<i class="glyph-crop"></i>
<i class="glyph-vector-path-square"></i>
<i class="glyph-vector-path-circle"></i>
<i class="glyph-vector-path-polygon"></i>
<i class="glyph-vector-path-line"></i>
<i class="glyph-vector-path-curve"></i>
<i class="glyph-vector-path-all"></i>
<i class="glyph-font"></i>
<i class="glyph-italic"></i>
<i class="glyph-bold"></i>
<i class="glyph-text-underline"></i>
<i class="glyph-text-strike"></i>
<i class="glyph-text-height"></i>
<i class="glyph-text-width"></i>
<i class="glyph-text-resize"></i>
<i class="glyph-left-indent"></i>
<i class="glyph-right-indent"></i>
<i class="glyph-align-left"></i>
<i class="glyph-align-center"></i>
<i class="glyph-align-right"></i>
<i class="glyph-justify"></i>
<i class="glyph-list"></i>
<i class="glyph-text-smaller"></i>
<i class="glyph-text-bigger"></i>
<i class="glyph-embed"></i>
<i class="glyph-embed-close"></i>
<i class="glyph-adjust"></i>
<i class="glyph-message-full"></i>
<i class="glyph-message-empty"></i>
<i class="glyph-message-in"></i>
<i class="glyph-message-out"></i>
<i class="glyph-message-plus"></i>
<i class="glyph-message-minus"></i>
<i class="glyph-message-ban"></i>
<i class="glyph-message-flag"></i>
<i class="glyph-message-lock"></i>
<i class="glyph-message-new"></i>
<i class="glyph-inbox"></i>
<i class="glyph-inbox-plus"></i>
<i class="glyph-inbox-minus"></i>
<i class="glyph-inbox-lock"></i>
<i class="glyph-inbox-in"></i>
<i class="glyph-inbox-out"></i>
<i class="glyph-computer-locked"></i>
<i class="glyph-computer-service"></i>
<i class="glyph-computer-proces"></i>
<i class="glyph-phone"></i>
<i class="glyph-database-lock"></i>
<i class="glyph-database-plus"></i>
<i class="glyph-database-minus"></i>
<i class="glyph-database-ban"></i>
<i class="glyph-folder-open"></i>
<i class="glyph-folder-plus"></i>
<i class="glyph-folder-minus"></i>
<i class="glyph-folder-lock"></i>
<i class="glyph-folder-flag"></i>
<i class="glyph-folder-new"></i>
<i class="glyph-check"></i>
<i class="glyph-edit"></i>
<i class="glyph-new-window"></i>
<i class="glyph-more-windows"></i>
<i class="glyph-show-big-thumbnails"></i>
<i class="glyph-show-thumbnails"></i>
<i class="glyph-show-thumbnails-with-lines"></i>
<i class="glyph-show-lines"></i>
<i class="glyph-playlist"></i>
<i class="glyph-picture"></i>
<i class="glyph-imac"></i>
<i class="glyph-macbook"></i>
<i class="glyph-ipad"></i>
<i class="glyph-iphone"></i>
<i class="glyph-iphone-transfer"></i>
<i class="glyph-iphone-exchange"></i>
<i class="glyph-ipod"></i>
<i class="glyph-ipod-shuffle"></i>
<i class="glyph-ear-plugs"></i>
<i class="glyph-albums"></i>
<i class="glyph-step-backward"></i>
<i class="glyph-fast-backward"></i>
<i class="glyph-rewind"></i>
<i class="glyph-play"></i>
<i class="glyph-pause"></i>
<i class="glyph-stop"></i>
<i class="glyph-forward"></i>
<i class="glyph-fast-forward"></i>
<i class="glyph-step-forward"></i>
<i class="glyph-eject"></i>
<i class="glyph-facetime-video"></i>
<i class="glyph-download-alt"></i>
<i class="glyph-mute"></i>
<i class="glyph-volume-down"></i>
<i class="glyph-volume-up"></i>
<i class="glyph-screenshot"></i>
<i class="glyph-move"></i>
<i class="glyph-more"></i>
<i class="glyph-brightness-reduce"></i>
<i class="glyph-brightness-increase"></i>
<i class="glyph-circle-plus"></i>
<i class="glyph-circle-minus"></i>
<i class="glyph-circle-remove"></i>
<i class="glyph-circle-ok"></i>
<i class="glyph-circle-question-mark"></i>
<i class="glyph-circle-info"></i>
<i class="glyph-circle-exclamation-mark"></i>
<i class="glyph-remove"></i>
<i class="glyph-ok"></i>
<i class="glyph-ban"></i>
<i class="glyph-download"></i>
<i class="glyph-upload"></i>
<i class="glyph-shopping-cart"></i>
<i class="glyph-lock"></i>
<i class="glyph-unlock"></i>
<i class="glyph-electricity"></i>
<i class="glyph-ok-2"></i>
<i class="glyph-remove-2"></i>
<i class="glyph-cart-out"></i>
<i class="glyph-cart-in"></i>
<i class="glyph-left-arrow"></i>
<i class="glyph-right-arrow"></i>
<i class="glyph-down-arrow"></i>
<i class="glyph-up-arrow"></i>
<i class="glyph-resize-small"></i>
<i class="glyph-resize-full"></i>
<i class="glyph-circle-arrow-left"></i>
<i class="glyph-circle-arrow-right"></i>
<i class="glyph-circle-arrow-right"></i>
<i class="glyph-circle-arrow-right"></i>
<i class="glyph-play-button"></i>
<i class="glyph-unshare"></i>
<i class="glyph-share"></i>
<i class="glyph-thin-right-arrow"></i>
<i class="glyph-thin-arrow-left"></i>
<i class="glyph-bluetooth"></i>
<i class="glyph-euro"></i>
<i class="glyph-usd"></i>
<i class="glyph-bp"></i>
<i class="glyph-retweet-2"></i>
<i class="glyph-moon"></i>
<i class="glyph-sun"></i>
<i class="glyph-cloud"></i>
<i class="glyph-direction"></i>
<i class="glyph-brush"></i>
<i class="glyph-pen"></i>
<i class="glyph-zoom-in"></i>
<i class="glyph-zoom-out"></i>
<i class="glyph-pin"></i>
<i class="glyph-riflescope"></i>
<i class="glyph-rotation-lock"></i>
<i class="glyph-flash"></i>
<i class="glyph-google-maps"></i>
<i class="glyph-anchor"></i>
<i class="glyph-conversation"></i>
<i class="glyph-chat"></i>
<i class="glyph-male"></i>
<i class="glyph-female"></i>
<i class="glyph-asterisk"></i>
<i class="glyph-divide"></i>
<i class="glyph-snorkel-diving"></i>
<i class="glyph-scuba-diving"></i>
<i class="glyph-oxygen-bottle"></i>
<i class="glyph-fins"></i>
<i class="glyph-fishes"></i>
<i class="glyph-boat"></i>
<i class="glyph-delete-point"></i>
<i class="glyph-sheriffs--star"></i>
<i class="glyph-qrcode"></i>
<i class="glyph-barcode"></i>
<i class="glyph-pool"></i>
<i class="glyph-buoy"></i>
<i class="glyph-spade"></i>
<i class="glyph-bank"></i>
<i class="glyph-vcard"></i>
<i class="glyph-electrical-plug"></i>
<i class="glyph-flag"></i>
<i class="glyph-credit-card"></i>
<i class="glyph-keyboard-wireless"></i>
<i class="glyph-keyboard-wired"></i>
<i class="glyph-shield"></i>
<i class="glyph-ring"></i>
<i class="glyph-cake"></i>
<i class="glyph-drink"></i>
<i class="glyph-beer"></i>
<i class="glyph-fast-food"></i>
<i class="glyph-cutlery"></i>
<i class="glyph-pizza"></i>
<i class="glyph-birthday-cake"></i>
<i class="glyph-tablet"></i>
<i class="glyph-settings"></i>
<i class="glyph-bullets"></i>
<i class="glyph-cardio"></i>
<i class="glyph-t-shirt"></i>
<i class="glyph-pants"></i>
<i class="glyph-sweater"></i>
<i class="glyph-fabric"></i>
<i class="glyph-leather"></i>
<i class="glyph-scissors"></i>
<i class="glyph-podium"></i>
<i class="glyph-skull"></i>
<i class="glyph-celebration"></i>
<i class="glyph-tea-kettle"></i>
<i class="glyph-french-press"></i>
<i class="glyph-coffe-cup"></i>
<i class="glyph-pot"></i>
<i class="glyph-grater"></i>
<i class="glyph-kettle"></i>
<i class="glyph-hospital"></i>
<i class="glyph-hospital-h"></i>
<i class="glyph-microphone"></i>
<i class="glyph-webcam"></i>
<i class="glyph-temple-christianity-church"></i>
<i class="glyph-temple-islam"></i>
<i class="glyph-temple-hindu"></i>
<i class="glyph-temple-buddhist"></i>
<i class="glyph-electrical-socket-eu"></i>
<i class="glyph-electrical-socket-us"></i>
<i class="glyph-bomb"></i>
<i class="glyph-comments"></i>
<i class="glyph-flower"></i>
<i class="glyph-baseball"></i>
<i class="glyph-rugby"></i>
<i class="glyph-ax"></i>
<i class="glyph-table-tennis"></i>
<i class="glyph-bowling"></i>
<i class="glyph-tree-conifer"></i>
<i class="glyph-tree-deciduous"></i>
<i class="glyph-more-items"></i>
<i class="glyph-sort"></i>
<i class="glyph-facebook"></i>
<i class="glyph-twitter-t"></i>
<i class="glyph-twitter"></i>
<i class="glyph-buzz"></i>
<i class="glyph-vimeo"></i>
<i class="glyph-flickr"></i>
<i class="glyph-last-fm"></i>
<i class="glyph-rss"></i>
<i class="glyph-skype"></i>
<i class="glyph-e-mail"></i>
<i class="glyph-instapaper"></i>
<i class="glyph-evernote"></i>
<i class="glyph-xing"></i>
<i class="glyph-zootool"></i>
<i class="glyph-dribbble"></i>
<i class="glyph-deviantart"></i>
<i class="glyph-read-it-later"></i>
<i class="glyph-linked-in"></i>
<i class="glyph-forrst"></i>
<i class="glyph-pinboard"></i>
<i class="glyph-behance"></i>
<i class="glyph-github"></i>
<i class="glyph-youtube"></i>
<i class="glyph-skitch"></i>
<i class="glyph-4square"></i>
<i class="glyph-quora"></i>
<i class="glyph-google-plus"></i>
<i class="glyph-spootify"></i>
<i class="glyph-stumbleupon"></i>
<i class="glyph-readability"></i>
</div> <!-- /container -->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="res/core/TwitterBootstrap/js/jquery-1.7.1.min.js"></script>
<script src="res/core/TwitterBootstrap/js/bootstrap.min.js"></script>
</body>
</html>