1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/baikal_ynh.git synced 2024-09-03 18:16:11 +02:00

initial commit

Creating package structure, from flat baikal package 0.2.7
This commit is contained in:
aquaxp 2014-03-20 19:35:00 +07:00
commit ac771654e2
880 changed files with 232726 additions and 0 deletions

5
README.md Normal file
View file

@ -0,0 +1,5 @@
Baïkal for YunoHost
----------------------
Lightweight CalDAV+CardDAV server
http://baikal-server.com/

0
conf/nginx.conf Normal file
View file

0
manifest.json Normal file
View file

0
scripts/install Normal file
View file

0
scripts/remove Normal file
View file

0
scripts/upgrade Normal file
View file

4
sources/ChangeLog.md Normal file
View file

@ -0,0 +1,4 @@
# 0.2.5
Upgraded SabreDAV from 1.8.0 to 1.8.6
Baïkal releases are now based on composer thanks to @evert

29
sources/Core/Distrib.php Normal file
View file

@ -0,0 +1,29 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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!
#################################################################
define("BAIKAL_VERSION", "0.2.7");
define("BAIKAL_HOMEPAGE", "http://baikal-server.com");
define("PROJECT_PACKAGE", "flat");

View file

@ -0,0 +1,81 @@
<?php
namespace Baikal\Core;
/**
* This is an authentication backend that uses a database to manage passwords.
*
* Format of the database tables must match to the one of \Sabre\DAV\Auth\Backend\PDO
*
* @copyright Copyright (C) 2013 Lukasz Janyst. All rights reserved.
* @author Lukasz Janyst <ljanyst@buggybrain.net>
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class PDOBasicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
/**
* Reference to PDO connection
*
* @var PDO
*/
protected $pdo;
/**
* PDO table name we'll be using
*
* @var string
*/
protected $tableName;
/**
* Authentication realm
*
* @var string
*/
protected $authRealm;
/**
* Creates the backend object.
*
* If the filename argument is passed in, it will parse out the specified file fist.
*
* @param PDO $pdo
* @param string $tableName The PDO table name to use
*/
public function __construct(\PDO $pdo, $authRealm, $tableName = 'users') {
$this->pdo = $pdo;
$this->tableName = $tableName;
$this->authRealm = $authRealm;
}
/**
* Validates a username and password
*
* This method should return true or false depending on if login
* succeeded.
*
* @param string $username
* @param string $password
* @return bool
*/
public function validateUserPass($username, $password) {
$stmt = $this->pdo->prepare('SELECT username, digesta1 FROM '.$this->tableName.' WHERE username = ?');
$stmt->execute(array($username));
$result = $stmt->fetchAll();
if (!count($result)) return false;
$hash = md5( $username . ':' . $this->authRealm . ':' . $password );
if( $result[0]['digesta1'] == $hash )
{
$this->currentUser = $username;
return true;
}
return false;
}
}

View file

@ -0,0 +1,623 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Core;
class Tools {
public static function &db() {
return $GLOBALS["pdo"];
}
public static function assertEnvironmentIsOk() {
# Asserting Baikal Context
if(!defined("BAIKAL_CONTEXT") || BAIKAL_CONTEXT !== TRUE) {
die("Bootstrap.php may not be included outside the Baikal context");
}
# Asserting PDO
if(!defined('PDO::ATTR_DRIVER_NAME')) {
die('Baikal Fatal Error: PDO is unavailable. It\'s required by Baikal.');
}
# Asserting PDO::SQLite or PDO::MySQL
$aPDODrivers = \PDO::getAvailableDrivers();
if(!in_array('sqlite', $aPDODrivers) && !in_array('mysql', $aPDODrivers)) {
die('<strong>Baikal Fatal Error</strong>: Both <strong>PDO::sqlite</strong> and <strong>PDO::mysql</strong> are unavailable. One of them at least is required by Baikal.');
}
}
public static function configureEnvironment() {
set_exception_handler('\Baikal\Core\Tools::handleException');
ini_set("error_reporting", E_ALL);
}
public static function handleException($exception) {
echo "<pre>" . $exception . "<pre>";
}
public static function assertBaikalIsOk() {
# DB connexion has not been asserted earlier by Flake, to give us a chance to trigger the install tool
# We assert it right now
if(!\Flake\Framework::isDBInitialized() && (!defined("BAIKAL_CONTEXT_INSTALL") || BAIKAL_CONTEXT_INSTALL === FALSE)) {
throw new \Exception("<strong>Fatal error</strong>: no connection to a database is available.");
}
# Asserting that the database is structurally complete
#if(($aMissingTables = self::isDBStructurallyComplete($GLOBALS["DB"])) !== TRUE) {
# throw new \Exception("<strong>Fatal error</strong>: Database is not structurally complete; missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong>");
#}
# Asserting config file exists
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
throw new \Exception("Specific/config.php does not exist. Please use the Install tool to create it.");
}
# Asserting config file is readable
if(!is_readable(PROJECT_PATH_SPECIFIC . "config.php")) {
throw new \Exception("Specific/config.php is not readable. Please give read permissions to httpd user on file 'Specific/config.php'.");
}
# Asserting config file is writable
if(!is_writable(PROJECT_PATH_SPECIFIC . "config.php")) {
throw new \Exception("Specific/config.php is not writable. Please give write permissions to httpd user on file 'Specific/config.php'.");
}
# Asserting system config file exists
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
throw new \Exception("Specific/config.system.php does not exist. Please use the Install tool to create it.");
}
# Asserting system config file is readable
if(!is_readable(PROJECT_PATH_SPECIFIC . "config.system.php")) {
throw new \Exception("Specific/config.system.php is not readable. Please give read permissions to httpd user on file 'Specific/config.system.php'.");
}
# Asserting system config file is writable
if(!is_writable(PROJECT_PATH_SPECIFIC . "config.system.php")) {
throw new \Exception("Specific/config.system.php is not writable. Please give write permissions to httpd user on file 'Specific/config.system.php'.");
}
}
public static function getRequiredTablesList() {
return array(
"addressbooks",
"calendarobjects",
"calendars",
"cards",
"groupmembers",
"locks",
"principals",
"users",
);
}
public static function isDBStructurallyComplete(\Flake\Core\Database $oDB) {
$aRequiredTables = self::getRequiredTablesList();
$aPresentTables = $oDB->tables();
$aIntersect = array_intersect($aRequiredTables, $aPresentTables);
if(count($aIntersect) !== count($aRequiredTables)) {
return array_diff($aRequiredTables, $aIntersect);
}
return TRUE;
}
public static function bashPrompt($prompt) {
print $prompt;
@flush();
@ob_flush();
$confirmation = @trim(fgets(STDIN));
return $confirmation;
}
public static function bashPromptSilent($prompt = "Enter Password:") {
$command = "/usr/bin/env bash -c 'echo OK'";
if(rtrim(shell_exec($command)) !== 'OK') {
trigger_error("Can't invoke bash");
return;
}
$command = "/usr/bin/env bash -c 'read -s -p \""
. addslashes($prompt)
. "\" mypassword && echo \$mypassword'";
$password = rtrim(shell_exec($command));
echo "\n";
return $password;
}
public static function getCopyrightNotice($sLinePrefixChar = "#", $sLineSuffixChar = "", $sOpening = FALSE, $sClosing = FALSE) {
if($sOpening === FALSE) {
$sOpening = str_repeat("#", 78);
}
if($sClosing === FALSE) {
$sClosing = str_repeat("#", 78);
}
$iYear = date("Y");
$sCode =<<<CODE
Copyright notice
(c) {$iYear} Jérôme Schneider <mail@jeromeschneider.fr>
All rights reserved
http://baikal-server.com
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!
CODE;
$sCode = "\n" . trim($sCode) . "\n";
$aCode = explode("\n", $sCode);
foreach(array_keys($aCode) as $iLineNum) {
$aCode[$iLineNum] = trim($sLinePrefixChar . "\t" . $aCode[$iLineNum]);
}
if(trim($sOpening) !== "") {
array_unshift($aCode, $sOpening);
}
if(trim($sClosing) !== "") {
$aCode[] = $sClosing;
}
return implode("\n", $aCode);
}
public static function timezones() {
$aZones = array(
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"Africa/Algiers",
"Africa/Asmara",
"Africa/Bamako",
"Africa/Bangui",
"Africa/Banjul",
"Africa/Bissau",
"Africa/Blantyre",
"Africa/Brazzaville",
"Africa/Bujumbura",
"Africa/Cairo",
"Africa/Casablanca",
"Africa/Ceuta",
"Africa/Conakry",
"Africa/Dakar",
"Africa/Dar_es_Salaam",
"Africa/Djibouti",
"Africa/Douala",
"Africa/El_Aaiun",
"Africa/Freetown",
"Africa/Gaborone",
"Africa/Harare",
"Africa/Johannesburg",
"Africa/Juba",
"Africa/Kampala",
"Africa/Khartoum",
"Africa/Kigali",
"Africa/Kinshasa",
"Africa/Lagos",
"Africa/Libreville",
"Africa/Lome",
"Africa/Luanda",
"Africa/Lubumbashi",
"Africa/Lusaka",
"Africa/Malabo",
"Africa/Maputo",
"Africa/Maseru",
"Africa/Mbabane",
"Africa/Mogadishu",
"Africa/Monrovia",
"Africa/Nairobi",
"Africa/Ndjamena",
"Africa/Niamey",
"Africa/Nouakchott",
"Africa/Ouagadougou",
"Africa/Porto-Novo",
"Africa/Sao_Tome",
"Africa/Tripoli",
"Africa/Tunis",
"Africa/Windhoek",
"America/Adak",
"America/Anchorage",
"America/Anguilla",
"America/Antigua",
"America/Araguaina",
"America/Argentina/Buenos_Aires",
"America/Argentina/Catamarca",
"America/Argentina/Cordoba",
"America/Argentina/Jujuy",
"America/Argentina/La_Rioja",
"America/Argentina/Mendoza",
"America/Argentina/Rio_Gallegos",
"America/Argentina/Salta",
"America/Argentina/San_Juan",
"America/Argentina/San_Luis",
"America/Argentina/Tucuman",
"America/Argentina/Ushuaia",
"America/Aruba",
"America/Asuncion",
"America/Atikokan",
"America/Bahia",
"America/Barbados",
"America/Belem",
"America/Belize",
"America/Blanc-Sablon",
"America/Boa_Vista",
"America/Bogota",
"America/Boise",
"America/Cambridge_Bay",
"America/Campo_Grande",
"America/Cancun",
"America/Caracas",
"America/Cayenne",
"America/Cayman",
"America/Chicago",
"America/Chihuahua",
"America/Costa_Rica",
"America/Cuiaba",
"America/Curacao",
"America/Danmarkshavn",
"America/Dawson",
"America/Dawson_Creek",
"America/Denver",
"America/Detroit",
"America/Dominica",
"America/Edmonton",
"America/Eirunepe",
"America/El_Salvador",
"America/Felipe_Carrillo",
"America/Fortaleza",
"America/Glace_Bay",
"America/Godthab",
"America/Goose_Bay",
"America/Grand_Turk",
"America/Grenada",
"America/Guadeloupe",
"America/Guatemala",
"America/Guayaquil",
"America/Guyana",
"America/Halifax",
"America/Havana",
"America/Hermosillo",
"America/Indiana/Indianapolis",
"America/Indiana/Knox",
"America/Indiana/Marengo",
"America/Indiana/Petersburg",
"America/Indiana/Tell_City",
"America/Indiana/Vevay",
"America/Indiana/Vincennes",
"America/Indiana/Winamac",
"America/Inuvik",
"America/Iqaluit",
"America/Jamaica",
"America/Juneau",
"America/Kentucky/Louisville",
"America/Kentucky/Monticello",
"America/La_Paz",
"America/Lima",
"America/Los_Angeles",
"America/Maceio",
"America/Managua",
"America/Manaus",
"America/Marigot",
"America/Martinique",
"America/Matamoros",
"America/Mazatlan",
"America/Menominee",
"America/Merida",
"America/Mexico_City",
"America/Miquelon",
"America/Moncton",
"America/Monterrey",
"America/Montevideo",
"America/Montreal",
"America/Montserrat",
"America/Nassau",
"America/New_York",
"America/Nipigon",
"America/Nome",
"America/Noronha",
"America/North_Dakota/Center",
"America/North_Dakota/New_Salem",
"America/Ojinaga",
"America/Panama",
"America/Pangnirtung",
"America/Paramaribo",
"America/Phoenix",
"America/Port-au-Prince",
"America/Porto_Velho",
"America/Port_of_Spain",
"America/Puerto_Rico",
"America/Rainy_River",
"America/Rankin_Inlet",
"America/Recife",
"America/Regina",
"America/Resolute",
"America/Rio_Branco",
"America/Santarem",
"America/Santa_Isabel",
"America/Santiago",
"America/Santo_Domingo",
"America/Sao_Paulo",
"America/Scoresbysund",
"America/Shiprock",
"America/St_Barthelemy",
"America/St_Johns",
"America/St_Kitts",
"America/St_Lucia",
"America/St_Thomas",
"America/St_Vincent",
"America/Swift_Current",
"America/Tegucigalpa",
"America/Thule",
"America/Thunder_Bay",
"America/Tijuana",
"America/Toronto",
"America/Tortola",
"America/Vancouver",
"America/Whitehorse",
"America/Winnipeg",
"America/Yakutat",
"America/Yellowknife",
"Antarctica/Casey",
"Antarctica/Davis",
"Antarctica/DumontDUrville",
"Antarctica/Mawson",
"Antarctica/McMurdo",
"Antarctica/Palmer",
"Antarctica/Rothera",
"Antarctica/South_Pole",
"Antarctica/Syowa",
"Antarctica/Vostok",
"Arctic/Longyearbyen",
"Asia/Aden",
"Asia/Almaty",
"Asia/Amman",
"Asia/Anadyr",
"Asia/Aqtau",
"Asia/Aqtobe",
"Asia/Ashgabat",
"Asia/Baghdad",
"Asia/Bahrain",
"Asia/Baku",
"Asia/Bangkok",
"Asia/Beirut",
"Asia/Bishkek",
"Asia/Brunei",
"Asia/Choibalsan",
"Asia/Chongqing",
"Asia/Colombo",
"Asia/Damascus",
"Asia/Dhaka",
"Asia/Dili",
"Asia/Dubai",
"Asia/Dushanbe",
"Asia/Gaza",
"Asia/Harbin",
"Asia/Hong_Kong",
"Asia/Hovd",
"Asia/Ho_Chi_Minh",
"Asia/Irkutsk",
"Asia/Jakarta",
"Asia/Jayapura",
"Asia/Jerusalem",
"Asia/Kabul",
"Asia/Kamchatka",
"Asia/Karachi",
"Asia/Kashgar",
"Asia/Kathmandu",
"Asia/Kolkata",
"Asia/Krasnoyarsk",
"Asia/Kuala_Lumpur",
"Asia/Kuching",
"Asia/Kuwait",
"Asia/Macau",
"Asia/Magadan",
"Asia/Makassar",
"Asia/Manila",
"Asia/Muscat",
"Asia/Nicosia",
"Asia/Novokuznetsk",
"Asia/Novosibirsk",
"Asia/Omsk",
"Asia/Oral",
"Asia/Phnom_Penh",
"Asia/Pontianak",
"Asia/Pyongyang",
"Asia/Qatar",
"Asia/Qyzylorda",
"Asia/Rangoon",
"Asia/Riyadh",
"Asia/Sakhalin",
"Asia/Samarkand",
"Asia/Seoul",
"Asia/Shanghai",
"Asia/Singapore",
"Asia/Taipei",
"Asia/Tashkent",
"Asia/Tbilisi",
"Asia/Tehran",
"Asia/Thimphu",
"Asia/Tokyo",
"Asia/Ulaanbaatar",
"Asia/Urumqi",
"Asia/Vientiane",
"Asia/Vladivostok",
"Asia/Yakutsk",
"Asia/Yekaterinburg",
"Asia/Yerevan",
"Atlantic/Azores",
"Atlantic/Bermuda",
"Atlantic/Canary",
"Atlantic/Cape_Verde",
"Atlantic/Faroe",
"Atlantic/Madeira",
"Atlantic/Reykjavik",
"Atlantic/South_Georgia",
"Atlantic/Stanley",
"Atlantic/St_Helena",
"Australia/Adelaide",
"Australia/Brisbane",
"Australia/Broken_Hill",
"Australia/Currie",
"Australia/Darwin",
"Australia/Eucla",
"Australia/Hobart",
"Australia/Lindeman",
"Australia/Lord_Howe",
"Australia/Melbourne",
"Australia/Perth",
"Australia/Sydney",
"Europe/Amsterdam",
"Europe/Andorra",
"Europe/Athens",
"Europe/Belgrade",
"Europe/Berlin",
"Europe/Bratislava",
"Europe/Brussels",
"Europe/Bucharest",
"Europe/Budapest",
"Europe/Chisinau",
"Europe/Copenhagen",
"Europe/Dublin",
"Europe/Gibraltar",
"Europe/Guernsey",
"Europe/Helsinki",
"Europe/Isle_of_Man",
"Europe/Istanbul",
"Europe/Jersey",
"Europe/Kaliningrad",
"Europe/Kiev",
"Europe/Lisbon",
"Europe/Ljubljana",
"Europe/London",
"Europe/Luxembourg",
"Europe/Madrid",
"Europe/Malta",
"Europe/Mariehamn",
"Europe/Minsk",
"Europe/Monaco",
"Europe/Moscow",
"Europe/Oslo",
"Europe/Paris",
"Europe/Podgorica",
"Europe/Prague",
"Europe/Riga",
"Europe/Rome",
"Europe/Samara",
"Europe/San_Marino",
"Europe/Sarajevo",
"Europe/Simferopol",
"Europe/Skopje",
"Europe/Sofia",
"Europe/Stockholm",
"Europe/Tallinn",
"Europe/Tirane",
"Europe/Uzhgorod",
"Europe/Vaduz",
"Europe/Vatican",
"Europe/Vienna",
"Europe/Vilnius",
"Europe/Volgograd",
"Europe/Warsaw",
"Europe/Zagreb",
"Europe/Zaporozhye",
"Europe/Zurich",
"Indian/Antananarivo",
"Indian/Chagos",
"Indian/Christmas",
"Indian/Cocos",
"Indian/Comoro",
"Indian/Kerguelen",
"Indian/Mahe",
"Indian/Maldives",
"Indian/Mauritius",
"Indian/Mayotte",
"Indian/Reunion",
"Pacific/Apia",
"Pacific/Auckland",
"Pacific/Chatham",
"Pacific/Easter",
"Pacific/Efate",
"Pacific/Enderbury",
"Pacific/Fakaofo",
"Pacific/Fiji",
"Pacific/Funafuti",
"Pacific/Galapagos",
"Pacific/Gambier",
"Pacific/Guadalcanal",
"Pacific/Guam",
"Pacific/Honolulu",
"Pacific/Johnston",
"Pacific/Kiritimati",
"Pacific/Kosrae",
"Pacific/Kwajalein",
"Pacific/Majuro",
"Pacific/Marquesas",
"Pacific/Midway",
"Pacific/Nauru",
"Pacific/Niue",
"Pacific/Norfolk",
"Pacific/Noumea",
"Pacific/Pago_Pago",
"Pacific/Palau",
"Pacific/Pitcairn",
"Pacific/Ponape",
"Pacific/Port_Moresby",
"Pacific/Rarotonga",
"Pacific/Saipan",
"Pacific/Tahiti",
"Pacific/Tarawa",
"Pacific/Tongatapu",
"Pacific/Truk",
"Pacific/Wake",
"Pacific/Wallis",
);
reset($aZones);
return $aZones;
}
}

View file

@ -0,0 +1,93 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Framework extends \Flake\Core\Framework {
public static function installTool() {
if(defined("BAIKAL_CONTEXT_INSTALL") && BAIKAL_CONTEXT_INSTALL === TRUE) {
# Install tool has been launched and we're already on the install page
return;
} else {
# Install tool has been launched; redirecting user
$sInstallToolUrl = PROJECT_URI . "admin/install/";
header("Location: " . $sInstallToolUrl);
exit(0);
}
}
public static function bootstrap() {
# Registering Baikal classloader
define("BAIKAL_PATH_FRAMEWORKROOT", dirname(__FILE__) . "/");
\Baikal\Core\Tools::assertEnvironmentIsOk();
\Baikal\Core\Tools::configureEnvironment();
# Check that a config file exists
if(
!file_exists(PROJECT_PATH_SPECIFIC . "config.php") ||
!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")
) {
self::installTool();
} else {
require_once(PROJECT_PATH_SPECIFIC . "config.php");
require_once(PROJECT_PATH_SPECIFIC . "config.system.php");
date_default_timezone_set(PROJECT_TIMEZONE);
# Check that Baïkal is already configured
if(!defined("BAIKAL_CONFIGURED_VERSION")) {
self::installTool();
} else {
# Check that running version matches configured version
if(version_compare(BAIKAL_VERSION, BAIKAL_CONFIGURED_VERSION) > 0) {
self::installTool();
} else {
# Check that admin password is set
if(!defined("BAIKAL_ADMIN_PASSWORDHASH")) {
self::installTool();
}
\Baikal\Core\Tools::assertBaikalIsOk();
set_error_handler("\Baikal\Framework::exception_error_handler");
}
}
}
}
# Mapping PHP errors to exceptions; needed by SabreDAV
public static function exception_error_handler($errno, $errstr, $errfile, $errline) {
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
}
}

View file

@ -0,0 +1,118 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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 AddressBook extends \Flake\Core\Model\Db {
const DATATABLE = "addressbooks";
const PRIMARYKEY = "id";
const LABELFIELD = "displayname";
protected $aData = array(
"principaluri" => "",
"displayname" => "",
"uri" => "",
"description" => "",
"ctag" => 1,
);
public static function humanName() {
return "Address Book";
}
public static function icon() {
return "icon-book";
}
public static function mediumicon() {
return "glyph-adress-book";
}
public static function bigicon() {
return "glyph2x-adress-book";
}
public function getContactsBaseRequester() {
$oBaseRequester = \Baikal\Model\AddressBook\Contact::getBaseRequester();
$oBaseRequester->addClauseEquals(
"addressbookid",
$this->get("id")
);
return $oBaseRequester;
}
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "uri",
"label" => "Address Book token ID",
"validation" => "required,tokenid",
"popover" => array(
"title" => "Address Book token ID",
"content" => "The unique identifier for this address book.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "displayname",
"label" => "Display name",
"validation" => "required",
"popover" => array(
"title" => "Display name",
"content" => "This is the name that will be displayed in your CardDAV client.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "description",
"label" => "Description",
"validation" => "required"
)));
if($this->floating()) {
$oMorpho->element("uri")->setOption(
"help",
"Allowed characters are digits, lowercase letters and the dash symbol '-'."
);
} else {
$oMorpho->element("uri")->setOption("readonly", TRUE);
}
return $oMorpho;
}
public function destroy() {
$oContacts = $this->getContactsBaseRequester()->execute();
foreach($oContacts as $contact) {
$contact->destroy();
}
parent::destroy();
}
}

View file

@ -0,0 +1,40 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\AddressBook;
class Contact extends \Flake\Core\Model\Db {
const DATATABLE = "cards";
const PRIMARYKEY = "id";
const LABELFIELD = "uri";
protected $aData = array(
"carddata" => "",
"uri" => "",
"addressbookid" => "",
"lastmodified" => "",
);
}

View file

@ -0,0 +1,207 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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" => 0,
"description" => "",
"calendarorder" => 0,
"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 getEventsBaseRequester() {
$oBaseRequester = \Baikal\Model\Calendar\Event::getBaseRequester();
$oBaseRequester->addClauseEquals(
"calendarid",
$this->get("id")
);
return $oBaseRequester;
}
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);
}
if($sPropName === "notes") {
# TRUE if components contains VJOURNAL, FALSE otherwise
if(($sComponents = $this->get("components")) !== "") {
$aComponents = explode(",", $sComponents);
} else {
$aComponents = array();
}
return in_array("VJOURNAL", $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));
}
if($sPropName === "notes") {
if(($sComponents = $this->get("components")) !== "") {
$aComponents = explode(",", $sComponents);
} else {
$aComponents = array();
}
if($sValue === TRUE) {
if(!in_array("VJOURNAL", $aComponents)) {
$aComponents[] = "VJOURNAL";
}
} else {
if(in_array("VJOURNAL", $aComponents)) {
unset($aComponents[array_search("VJOURNAL", $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",
"popover" => array(
"title" => "Calendar token ID",
"content" => "The unique identifier for this calendar.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "displayname",
"label" => "Display name",
"validation" => "required",
"popover" => array(
"title" => "Display name",
"content" => "This is the name that will be displayed in your CalDAV client.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "description",
"label" => "Description"
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "todos",
"label" => "Todos",
"help" => "If checked, todos will be enabled on this calendar.",
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "notes",
"label" => "Notes",
"help" => "If checked, notes will be enabled on this calendar.",
)));
if($this->floating()) {
$oMorpho->element("uri")->setOption(
"help",
"Allowed characters are digits, lowercase letters and the dash symbol '-'."
);
} else {
$oMorpho->element("uri")->setOption("readonly", TRUE);
}
return $oMorpho;
}
public function isDefault() {
return $this->get("uri") === "default";
}
public function destroy() {
$oEvents = $this->getEventsBaseRequester()->execute();
foreach($oEvents as $event) {
$event->destroy();
}
parent::destroy();
}
}

View file

@ -0,0 +1,40 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Calendar;
class Event extends \Flake\Core\Model\Db {
const DATATABLE = "calendarobjects";
const PRIMARYKEY = "id";
const LABELFIELD = "uri";
protected $aData = array(
"calendardata" => "",
"uri" => "",
"calendarid" => "",
"lastmodified" => "",
);
}

View file

@ -0,0 +1,240 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
abstract class Config extends \Flake\Core\Model\NoDb {
protected $sConfigFilePath = "";
protected $aConstants = array();
protected $aData = array();
public function __construct($sConfigFilePath) {
# Note: no call to parent::__construct() to avoid erasing $this->aData
$this->sConfigFilePath = $sConfigFilePath;
$aConfig = $this->parseConfig(
$this->getConfigAsString()
);
foreach(array_keys($this->aData) as $sProp) {
if(array_key_exists($sProp, $aConfig)) {
$this->aData[$sProp] = $aConfig[$sProp];
}
}
}
protected function getConfigAsString() {
if(file_exists($this->sConfigFilePath)) {
$sContent = file_get_contents($this->sConfigFilePath);
return str_replace(LF . CR, LF, $sContent);
} else {
$sConfig = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
$sConfig .= static::getDefaultConfig();
return $sConfig;
}
}
protected function parseConfig($sString) {
$aRes = array();
foreach(array_keys($this->aConstants) as $sConstant) {
$aConstant = $this->aConstants[$sConstant];
$aMatches = array();
$sPattern = '/\s*define\(\s*["|\']' . $sConstant . '["|\']\s*\,\s*(.*?)\s*\);\s*/ix';
$iNbRes = preg_match_all(
$sPattern,
$sString,
$aMatches
);
if($iNbRes === 1) {
# Exactly one match
# O would be not enough, and > 1, to much to handle properly
$sValue = $aMatches[1][0]; # first capture (.*?), first occurence (anyway, we asserted that there's only one)
switch($aConstant["type"]) {
case "string": {
$sValue = substr($sValue, 1, -1); # Strip quotes
break;
}
case "integer": {
$sValue = intval($sValue); # Integer
break;
}
case "boolean": {
if(in_array(strtoupper(trim($sValue)), array("1", "TRUE"))) {
$sValue = TRUE;
} else {
$sValue = FALSE;
}
break;
}
case "litteral": {
$sValue = trim($sValue);
break;
}
default: {
# nothing
break;
}
}
$aRes[$sConstant] = $sValue;
} elseif($iNbRes > 1) {
throw new \Exception("Baikal\Model\Config->parseConfig(): constant '" . $sConstant . "' has been found multiple times in the config file; stopping execution");
} else {
# $iNbRes === 0
# We do nothing, to keep the default value (the one already set in $aData)
}
}
reset($aRes);
return $aRes;
}
public function writable() {
return (
@file_exists($this->sConfigFilePath) &&
@is_file($this->sConfigFilePath) &&
@is_writable($this->sConfigFilePath)
);
}
public static function icon() {
return "icon-cog";
}
public static function mediumicon() {
return "glyph-cogwheel";
}
public static function bigicon() {
return "glyph2x-cogwheel";
}
public function floating() {
return FALSE;
}
public function persist() {
$aLines = explode(LF, $this->getConfigAsString());
$iLines = count($aLines);
foreach(array_keys($this->aData) as $prop) {
$sPattern = '/\s*define\(\s*["|\']' . $prop . '["|\']\s*\,\s*(.*?)\s*\);\s*/ix';
$sValue = $this->aData[$prop];
# We replace value by it's native PHP notation
switch($this->aConstants[$prop]["type"]) {
case "string": {
$sValue = var_export($sValue, TRUE); # Add quotes, and escape " and all string-termination chars
break;
}
case "integer": {
$sValue = intval($sValue); # Cast as integer
break;
}
case "boolean": {
if(intval($sValue) === 1) { # Note as a BOOLEAN PHP constant
$sValue = "TRUE";
} else {
$sValue = "FALSE";
}
break;
}
case "litteral": {
$sValue = trim($sValue);
break;
}
default: {
$sValue = "''";
break;
}
}
$mFound = FALSE;
for($k = ($iLines - 1); $k >= 0; $k--) {
if(preg_match($sPattern, $aLines[$k])) {
# Found the last matching line
$mFound = $k;
break;
}
}
if($mFound === FALSE) {
# Adding line at the end of the file
$aLines[] = "\n" . "# " . $this->aConstants[$prop]["comment"] . "\ndefine(\"" . $prop . "\", " . $sValue . ");";
} else {
$aLines[$mFound] = "define(\"" . $prop . "\", " . $sValue . ");";
}
}
$sLines = implode("\n", $aLines);
$sSandboxedCode = str_replace(array("<?php", "<?", "?>"), "", $sLines);
$sRand = (string)rand();
$sCode = "if(0) {" . $sSandboxedCode . "}; echo '" . $sRand . "';";
ob_start();
eval($sCode);
$sRes = ob_get_contents();
ob_end_clean();
if($sRes !== $sRand) {
echo "<pre>" . htmlspecialchars($sLines) . "</pre>";
throw new \Exception("Parse error in new config file. Aborting, nothing has been changed.");
}
# We asserted that the syntax is OK;
# We now check that all the constants are present, and with the right value
$aNewConfig = $this->parseConfig($sLines);
$aWrittenConfig = $this->aData;
asort($aNewConfig);
asort($aWrittenConfig);
if($aNewConfig != $aWrittenConfig) {
throw new \Exception("New config does not correspond to expected config. Aborting, nothing has been changed.");
}
file_put_contents($this->sConfigFilePath, $sLines);
}
public function destroy() {
}
protected static function getDefaultConfig() {
}
}

View file

@ -0,0 +1,117 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Config;
class Database extends \Baikal\Model\Config {
protected $aConstants = array(
"PROJECT_SQLITE_FILE" => array(
"type" => "litteral",
"comment" => "Define path to Baïkal Database SQLite file",
),
"PROJECT_DB_MYSQL" => array(
"type" => "boolean",
"comment" => "MySQL > Use MySQL instead of SQLite ?",
),
"PROJECT_DB_MYSQL_HOST" => array(
"type" => "string",
"comment" => "MySQL > Host, including ':portnumber' if port is not the default one (3306)",
),
"PROJECT_DB_MYSQL_DBNAME" => array(
"type" => "string",
"comment" => "MySQL > Database name",
),
"PROJECT_DB_MYSQL_USERNAME" => array(
"type" => "string",
"comment" => "MySQL > Username",
),
"PROJECT_DB_MYSQL_PASSWORD" => array(
"type" => "string",
"comment" => "MySQL > Password",
),
);
# Default values
protected $aData = array(
"PROJECT_SQLITE_FILE" => 'PROJECT_PATH_SPECIFIC . "db/db.sqlite"',
"PROJECT_DB_MYSQL" => FALSE,
"PROJECT_DB_MYSQL_HOST" => "",
"PROJECT_DB_MYSQL_DBNAME" => "",
"PROJECT_DB_MYSQL_USERNAME" => "",
"PROJECT_DB_MYSQL_PASSWORD" => "",
);
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_SQLITE_FILE",
"label" => "SQLite file path",
"validation" => "required",
"inputclass" => "input-xxlarge",
"help" => "The absolute server path to the SQLite file",
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "PROJECT_DB_MYSQL",
"label" => "Use MySQL",
"help" => "If checked, Baïkal will use MySQL instead of SQLite.",
"refreshonchange" => TRUE,
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_HOST",
"label" => "MySQL host",
"help" => "Host ip or name, including <strong>':portnumber'</strong> if port is not the default one (3306)"
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_DBNAME",
"label" => "MySQL database name",
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_USERNAME",
"label" => "MySQL username",
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "PROJECT_DB_MYSQL_PASSWORD",
"label" => "MySQL password",
)));
return $oMorpho;
}
public function label() {
return "Baïkal Database Settings";
}
protected static function getDefaultConfig() {
throw new \Exception("Should never reach getDefaultConfig() on \Baikal\Model\Config\Database");
}
}

View file

@ -0,0 +1,61 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Config;
class Distrib extends \Baikal\Model\Config {
protected $aConstants = array(
"BAIKAL_VERSION" => array(
"type" => "string",
"comment" => "The version of the packaged system"
),
"BAIKAL_HOMEPAGE" => array(
"type" => "string",
"comment" => "The URL to the project homepage",
),
"PROJECT_PACKAGE" => array(
"type" => "string",
"comment" => "The type of the current package (one of 'flat', 'regular')"
),
);
# Default values
protected $aData = array(
"BAIKAL_VERSION" => "",
"BAIKAL_HOMEPAGE" => "",
"PROJECT_PACKAGE" => "",
);
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
return $oMorpho;
}
public function label() {
return "Baïkal distribution info";
}
}

View file

@ -0,0 +1,222 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Config;
class Standard extends \Baikal\Model\Config {
protected $aConstants = array(
"PROJECT_TIMEZONE" => array(
"type" => "string",
"comment" => "Timezone of the server; if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones",
),
"BAIKAL_CARD_ENABLED" => array(
"type" => "boolean",
"comment" => "CardDAV ON/OFF switch; default TRUE",
),
"BAIKAL_CAL_ENABLED" => array(
"type" => "boolean",
"comment" => "CalDAV ON/OFF switch; default TRUE",
),
"BAIKAL_DAV_AUTH_TYPE" => array(
"type" => "string",
"comment" => "HTTP authentication type for WebDAV; default Digest"
),
"BAIKAL_ADMIN_ENABLED" => array(
"type" => "boolean",
"comment" => "Baïkal Web Admin ON/OFF switch; default TRUE",
),
"BAIKAL_ADMIN_AUTOLOCKENABLED" => array(
"type" => "boolean",
"comment" => "Baïkal Web Admin autolock ON/OFF switch; default FALSE",
),
"BAIKAL_ADMIN_PASSWORDHASH" => array(
"type" => "string",
"comment" => "Baïkal Web admin password hash; Set via Baïkal Web Admin",
)
);
# Default values
protected $aData = array(
"PROJECT_TIMEZONE" => "Europe/Paris",
"BAIKAL_CARD_ENABLED" => TRUE,
"BAIKAL_CAL_ENABLED" => TRUE,
"BAIKAL_DAV_AUTH_TYPE" => "Digest",
"BAIKAL_ADMIN_ENABLED" => TRUE,
"BAIKAL_ADMIN_AUTOLOCKENABLED" => FALSE,
"BAIKAL_ADMIN_PASSWORDHASH" => ""
);
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Listbox(array(
"prop" => "PROJECT_TIMEZONE",
"label" => "Server Time zone",
"validation" => "required",
"options" => \Baikal\Core\Tools::timezones(),
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "BAIKAL_CAL_ENABLED",
"label" => "Enable CalDAV"
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "BAIKAL_CARD_ENABLED",
"label" => "Enable CardDAV"
)));
$oMorpho->add(new \Formal\Element\Listbox(array(
"prop" => "BAIKAL_DAV_AUTH_TYPE",
"label" => "WebDAV authentication type",
"options" => array( "Digest", "Basic" )
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "BAIKAL_ADMIN_PASSWORDHASH",
"label" => "Admin password",
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM",
"label" => "Admin password, confirmation",
"validation" => "sameas:BAIKAL_ADMIN_PASSWORDHASH",
)));
if(!defined("BAIKAL_ADMIN_PASSWORDHASH") || trim(BAIKAL_ADMIN_PASSWORDHASH) === "") {
# No password set (Form is used in install tool), so password is required as it has to be defined
$oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH")->setOption("validation", "required");
} else {
$sNotice = "-- Leave empty to keep current password --";
$oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH")->setOption("placeholder", $sNotice);
$oMorpho->element("BAIKAL_ADMIN_PASSWORDHASH_CONFIRM")->setOption("placeholder", $sNotice);
}
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "BAIKAL_ADMIN_ENABLED",
"label" => "Enable Web interface (recommended)",
"popover" => array(
"title" => "Warning !",
"content" => "If disabled, you'll lose access to this very admin interface !",
),
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "BAIKAL_ADMIN_AUTOLOCKENABLED",
"label" => "Web interface autolock",
"popover" => array(
"title" => "Web admin autolock",
"content" => "If enabled, you'll have to create a file named <strong>ENABLE_ADMIN</strong> in the folder <strong>Specific/</strong> prior to every admin use.<br /><br />This enforces security, but might be uncomfortable if you use the admin frequently."
)
)));
return $oMorpho;
}
public function label() {
return "Baïkal Settings";
}
public function set($sProp, $sValue) {
if($sProp === "BAIKAL_ADMIN_PASSWORDHASH" || $sProp === "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM") {
# Special handling for password and passwordconfirm
if($sProp === "BAIKAL_ADMIN_PASSWORDHASH" && $sValue !== "") {
parent::set(
"BAIKAL_ADMIN_PASSWORDHASH",
\BaikalAdmin\Core\Auth::hashAdminPassword($sValue)
);
}
return $this;
}
parent::set($sProp, $sValue);
}
public function get($sProp) {
if($sProp === "BAIKAL_ADMIN_PASSWORDHASH" || $sProp === "BAIKAL_ADMIN_PASSWORDHASH_CONFIRM") {
return "";
}
return parent::get($sProp);
}
protected function createDefaultConfigFilesIfNeeded() {
# Create empty config.php if needed
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.php")) {
@touch(PROJECT_PATH_SPECIFIC . "config.php");
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
$sContent .= $this->getDefaultConfig();
file_put_contents(PROJECT_PATH_SPECIFIC . "config.php", $sContent);
}
# Create empty config.system.php if needed
if(!file_exists(PROJECT_PATH_SPECIFIC . "config.system.php")) {
@touch(PROJECT_PATH_SPECIFIC . "config.system.php");
$sContent = "<?php\n" . \Baikal\Core\Tools::getCopyrightNotice() . "\n\n";
$sContent .= $this->getDefaultSystemConfig();
file_put_contents(PROJECT_PATH_SPECIFIC . "config.system.php", $sContent);
}
}
protected static function getDefaultConfig() {
$sCode =<<<CODE
##############################################################################
# Required configuration
# You *have* to review these settings for Baïkal to run properly
#
# Timezone of your users, if unsure, check http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
define("PROJECT_TIMEZONE", "Europe/Paris");
# CardDAV ON/OFF switch; default TRUE
define("BAIKAL_CARD_ENABLED", TRUE);
# CalDAV ON/OFF switch; default TRUE
define("BAIKAL_CAL_ENABLED", TRUE);
# WebDAV authentication type; default Digest
define("BAIKAL_DAV_AUTH_TYPE", "Digest");
# Baïkal Web Admin ON/OFF switch; default TRUE
define("BAIKAL_ADMIN_ENABLED", TRUE);
# Baïkal Web Admin autolock ON/OFF switch; default FALSE
define("BAIKAL_ADMIN_AUTOLOCKENABLED", FALSE);
# Baïkal Web admin password hash; Set via Baïkal Web Admin
define("BAIKAL_ADMIN_PASSWORDHASH", "");
CODE;
$sCode = trim($sCode);
return $sCode;
}
}

View file

@ -0,0 +1,244 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Config;
class System extends \Baikal\Model\Config {
protected $aConstants = array(
"BAIKAL_PATH_SABREDAV" => array(
"type" => "litteral",
"comment" => "PATH to SabreDAV",
),
"BAIKAL_AUTH_REALM" => array(
"type" => "string",
"comment" => "If you change this value, you'll have to re-generate passwords for all your users",
),
"BAIKAL_CARD_BASEURI" => array(
"type" => "litteral",
"comment" => 'Should begin and end with a "/"',
),
"BAIKAL_CAL_BASEURI" => array(
"type" => "litteral",
"comment" => 'Should begin and end with a "/"',
),
"PROJECT_SQLITE_FILE" => array(
"type" => "litteral",
"comment" => "Define path to Baïkal Database SQLite file",
),
"PROJECT_DB_MYSQL" => array(
"type" => "boolean",
"comment" => "MySQL > Use MySQL instead of SQLite ?",
),
"PROJECT_DB_MYSQL_HOST" => array(
"type" => "string",
"comment" => "MySQL > Host, including ':portnumber' if port is not the default one (3306)",
),
"PROJECT_DB_MYSQL_DBNAME" => array(
"type" => "string",
"comment" => "MySQL > Database name",
),
"PROJECT_DB_MYSQL_USERNAME" => array(
"type" => "string",
"comment" => "MySQL > Username",
),
"PROJECT_DB_MYSQL_PASSWORD" => array(
"type" => "string",
"comment" => "MySQL > Password",
),
"BAIKAL_ENCRYPTION_KEY" => array(
"type" => "string",
"comment" => "A random 32 bytes key that will be used to encrypt data",
),
"BAIKAL_CONFIGURED_VERSION" => array(
"type" => "string",
"comment" => "The currently configured Baïkal version",
),
);
# Default values
protected $aData = array(
"BAIKAL_PATH_SABREDAV" => 'PROJECT_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/"',
"BAIKAL_AUTH_REALM" => "BaikalDAV",
"BAIKAL_CARD_BASEURI" => 'PROJECT_BASEURI . "card.php/"',
"BAIKAL_CAL_BASEURI" => 'PROJECT_BASEURI . "cal.php/"',
"PROJECT_SQLITE_FILE" => 'PROJECT_PATH_SPECIFIC . "db/db.sqlite"',
"PROJECT_DB_MYSQL" => FALSE,
"PROJECT_DB_MYSQL_HOST" => "",
"PROJECT_DB_MYSQL_DBNAME" => "",
"PROJECT_DB_MYSQL_USERNAME" => "",
"PROJECT_DB_MYSQL_PASSWORD" => "",
"BAIKAL_ENCRYPTION_KEY" => "",
"BAIKAL_CONFIGURED_VERSION" => "",
);
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "BAIKAL_CAL_BASEURI",
"label" => "CalDAV base URI",
"validation" => "required",
"help" => "The absolute web path to cal.php",
"popover" => array(
"title" => "CalDAV base URI",
"content" => "If Baïkal is hosted in a subfolder, this path should reflect it.<br /><strong>Whatever happens, it should begin and end with a slash.</strong>",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "BAIKAL_CARD_BASEURI",
"label" => "CardDAV base URI",
"validation" => "required",
"help" => "The absolute web path to card.php",
"popover" => array(
"title" => "CardDAV base URI",
"content" => "If Baïkal is hosted in a subfolder, this path should reflect it.<br /><strong>Whatever happens, it should begin and end with a slash.</strong>"
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "BAIKAL_AUTH_REALM",
"label" => "Auth realm",
"validation" => "required",
"help" => "Token used in authentication process.<br />If you change this, you'll have to reset all your users passwords.<br />You'll also loose access to this admin interface.",
"popover" => array(
"title" => "Auth realm",
"content" => "If you change this, you'll loose your access to this interface.<br />In other words: <strong>you should not change this, unless YKWYD.</strong>"
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "BAIKAL_PATH_SABREDAV",
"label" => "Path to SabreDAV",
"validation" => "required",
"inputclass" => "input-xxlarge",
"help" => "The absolute server path to SabreDAV API",
"popover" => array(
"title" => "Path to SabreDAV",
"content" => "If Baïkal is hosted in a subfolder, this path should reflect it.<br /><strong>Whatever happens, it should begin and end with a slash.</strong>",
"position" => "top"
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_SQLITE_FILE",
"label" => "SQLite file path",
"validation" => "required",
"inputclass" => "input-xxlarge",
"help" => "The absolute server path to the SQLite file",
)));
$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "PROJECT_DB_MYSQL",
"label" => "Use MySQL",
"help" => "If checked, Baïkal will use MySQL instead of SQLite.",
"refreshonchange" => TRUE,
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_HOST",
"label" => "MySQL host",
"help" => "Host ip or name, including ':portnumber' if port is not the default one (3306)"
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_DBNAME",
"label" => "MySQL database name",
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "PROJECT_DB_MYSQL_USERNAME",
"label" => "MySQL username",
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "PROJECT_DB_MYSQL_PASSWORD",
"label" => "MySQL password",
)));
return $oMorpho;
}
public function label() {
return "Baïkal Settings";
}
protected static function getDefaultConfig() {
$sBaikalVersion = BAIKAL_VERSION;
$sCode =<<<CODE
##############################################################################
# System configuration
# Should not be changed, unless YNWYD
#
# RULES
# 0. All folder pathes *must* be suffixed by "/"
# 1. All URIs *must* be suffixed by "/" if pointing to a folder
#
# PATH to SabreDAV
define("BAIKAL_PATH_SABREDAV", PROJECT_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/");
# If you change this value, you'll have to re-generate passwords for all your users
define("BAIKAL_AUTH_REALM", "BaikalDAV");
# Should begin and end with a "/"
define("BAIKAL_CARD_BASEURI", PROJECT_BASEURI . "card.php/");
# Should begin and end with a "/"
define("BAIKAL_CAL_BASEURI", PROJECT_BASEURI . "cal.php/");
# Define path to Baïkal Database SQLite file
define("PROJECT_SQLITE_FILE", PROJECT_PATH_SPECIFIC . "db/db.sqlite");
# MySQL > Use MySQL instead of SQLite ?
define("PROJECT_DB_MYSQL", FALSE);
# MySQL > Host, including ':portnumber' if port is not the default one (3306)
define("PROJECT_DB_MYSQL_HOST", "");
# MySQL > Database name
define("PROJECT_DB_MYSQL_DBNAME", "");
# MySQL > Username
define("PROJECT_DB_MYSQL_USERNAME", "");
# MySQL > Password
define("PROJECT_DB_MYSQL_PASSWORD", "");
# A random 32 bytes key that will be used to encrypt data
define("BAIKAL_ENCRYPTION_KEY", "");
# The currently configured Baïkal version
define("BAIKAL_CONFIGURED_VERSION", "{$sBaikalVersion}");
CODE;
$sCode = trim($sCode);
return $sCode;
}
}

View file

@ -0,0 +1,37 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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 Principal extends \Flake\Core\Model\Db {
const DATATABLE = "principals";
const PRIMARYKEY = "id";
protected $aData = array(
"uri" => "",
"displayname" => "",
"email" => "",
);
}

View file

@ -0,0 +1,280 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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 User extends \Flake\Core\Model\Db {
const DATATABLE = "users";
const PRIMARYKEY = "id";
const LABELFIELD = "username";
protected $aData = array(
"username" => "",
"digesta1" => "",
);
protected $oIdentityPrincipal = null;
public function initByPrimary($sPrimary) {
parent::initByPrimary($sPrimary);
# Initializing principals
$this->oIdentityPrincipal = \Baikal\Model\Principal::getBaseRequester()
->addClauseEquals("uri", "principals/" . $this->get("username"))
->execute()
->first();
}
public function getAddressBooksBaseRequester() {
$oBaseRequester = \Baikal\Model\AddressBook::getBaseRequester();
$oBaseRequester->addClauseEquals(
"principaluri",
"principals/" . $this->get("username")
);
return $oBaseRequester;
}
public function getCalendarsBaseRequester() {
$oBaseRequester = \Baikal\Model\Calendar::getBaseRequester();
$oBaseRequester->addClauseEquals(
"principaluri",
"principals/" . $this->get("username")
);
return $oBaseRequester;
}
public function initFloating() {
parent::initFloating();
# Initializing principals
$this->oIdentityPrincipal = new \Baikal\Model\Principal();
}
public function get($sPropName) {
if($sPropName === "password" || $sPropName === "passwordconfirm") {
# Special handling for password and passwordconfirm
return "";
}
try {
# does the property exist on the model object ?
$sRes = parent::get($sPropName);
} catch(\Exception $e) {
# no, it may belong to the oIdentityPrincipal model object
$sRes = $this->oIdentityPrincipal->get($sPropName);
}
return $sRes;
}
public function set($sPropName, $sPropValue) {
if($sPropName === "password" || $sPropName === "passwordconfirm") {
# Special handling for password and passwordconfirm
if($sPropName === "password" && $sPropValue !== "") {
parent::set(
"digesta1",
$this->getPasswordHashForPassword($sPropValue)
);
}
return $this;
}
try {
# does the property exist on the model object ?
parent::set($sPropName, $sPropValue);
} catch(\Exception $e) {
# no, it may belong to the oIdentityPrincipal model object
$this->oIdentityPrincipal->set($sPropName, $sPropValue);
}
return $this;
}
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();
# Creating default address book for user
$oDefaultAddressBook = new \Baikal\Model\AddressBook();
$oDefaultAddressBook->set(
"principaluri",
"principals/" . $this->get("username")
)->set(
"displayname",
"Default Address Book"
)->set(
"uri",
"default"
)->set(
"description",
"Default Address Book for " . $this->get("displayname")
);
$oDefaultAddressBook->persist();
}
}
public function destroy() {
# TODO: delete all related resources (principals, calendars, calendar events, contact books and contacts)
# Destroying identity principal
$this->oIdentityPrincipal->destroy();
$oCalendars = $this->getCalendarsBaseRequester()->execute();
foreach($oCalendars as $calendar) {
$calendar->destroy();
}
$oAddressBooks = $this->getAddressBooksBaseRequester()->execute();
foreach($oAddressBooks as $addressbook) {
$addressbook->destroy();
}
parent::destroy();
}
public function getMailtoURI() {
return "mailto:" . rawurlencode($this->get("displayname") . " <" . $this->get("email") . ">");
}
public function formMorphologyForThisModelInstance() {
$oMorpho = new \Formal\Form\Morphology();
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "username",
"label" => "Username",
"validation" => "required,unique",
"popover" => array(
"title" => "Username",
"content" => "The login for this user account.<br />It has to be unique.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "displayname",
"label" => "Display name",
"validation" => "required",
"popover" => array(
"title" => "Display name",
"content" => "This is the name that will be displayed in your CalDAV/CardDAV clients.",
)
)));
$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "email",
"label" => "Email",
"validation" => "required,email"
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "password",
"label" => "Password",
)));
$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "passwordconfirm",
"label" => "Confirm password",
"validation" => "sameas:password",
)));
if($this->floating()) {
$oMorpho->element("username")->setOption("help", "May be an email, but not forcibly.");
$oMorpho->element("password")->setOption("validation", "required");
} else {
$sNotice = "-- Leave empty to keep current password --";
$oMorpho->element("username")->setOption("readonly", true);
$oMorpho->element("password")->setOption("popover", array(
"title" => "Password",
"content" => "Write something here only if you want to change the user password."
));
$oMorpho->element("passwordconfirm")->setOption("popover", array(
"title" => "Confirm password",
"content" => "Write something here only if you want to change the user password."
));
$oMorpho->element("password")->setOption("placeholder", $sNotice);
$oMorpho->element("passwordconfirm")->setOption("placeholder", $sNotice);
}
return $oMorpho;
}
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

@ -0,0 +1,63 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Dashboard extends \Flake\Core\Controller {
public function execute() {
}
public function render() {
$oView = new \BaikalAdmin\View\Dashboard();
$oView->setData("BAIKAL_VERSION", BAIKAL_VERSION);
$oView->setData("PROJECT_PACKAGE", PROJECT_PACKAGE);
# Services status
$oView->setData("BAIKAL_CAL_ENABLED", BAIKAL_CAL_ENABLED);
$oView->setData("BAIKAL_CARD_ENABLED", BAIKAL_CARD_ENABLED);
# Statistics: Users
$iNbUsers = \Baikal\Model\User::getBaseRequester()->count();
$oView->setData("nbusers", $iNbUsers);
# Statistics: CalDAV
$iNbCalendars = \Baikal\Model\Calendar::getBaseRequester()->count();
$oView->setData("nbcalendars", $iNbCalendars);
$iNbEvents = \Baikal\Model\Calendar\Event::getBaseRequester()->count();
$oView->setData("nbevents", $iNbEvents);
# Statistics: CardDAV
$iNbBooks = \Baikal\Model\AddressBook::getBaseRequester()->count();
$oView->setData("nbbooks", $iNbBooks);
$iNbContacts = \Baikal\Model\AddressBook\Contact::getBaseRequester()->count();
$oView->setData("nbcontacts", $iNbContacts);
return $oView->render();
}
}

View file

@ -0,0 +1,165 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Install;
class Database extends \Flake\Core\Controller {
protected $aMessages = array();
protected $oModel;
protected $oForm; # \Formal\Form
public function execute() {
$this->oModel = new \Baikal\Model\Config\Database(PROJECT_PATH_SPECIFIC . "config.system.php");
$this->oForm = $this->oModel->formForThisModelInstance(array(
"close" => FALSE,
"hook.validation" => array($this, "validateMySQLConnection"),
"hook.morphology" => array($this, "hideMySQLFieldWhenNeeded"),
));
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
# nothing here
}
}
}
public function render() {
$sBigIcon = "glyph2x-magic";
$sBaikalVersion = BAIKAL_VERSION;
$oView = new \BaikalAdmin\View\Install\Database();
$oView->setData("baikalversion", BAIKAL_VERSION);
if($this->oForm->persisted()) {
\BaikalAdmin\Core\Auth::lockInstall();
$sMessage = "<p>Baïkal is now installed, and it's database properly configured. <strong>For security reasons, this installation wizard is now disabled.</strong></p>";
$sMessage . "<p>&nbsp;</p>";
$sMessage .= "<p><a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Start using Baïkal</a></p>";
$sForm = "";
} else {
$sMessage = "";
$sForm = $this->oForm->render();
}
$oView->setData("message", $sMessage);
$oView->setData("form", $sForm);
return $oView->render();
}
public function validateMySQLConnection($oForm, $oMorpho) {
$bMySQLEnabled = $oMorpho->element("PROJECT_DB_MYSQL")->value();
if($bMySQLEnabled) {
$sHost = $oMorpho->element("PROJECT_DB_MYSQL_HOST")->value();
$sDbname = $oMorpho->element("PROJECT_DB_MYSQL_DBNAME")->value();
$sUsername = $oMorpho->element("PROJECT_DB_MYSQL_USERNAME")->value();
$sPassword = $oMorpho->element("PROJECT_DB_MYSQL_PASSWORD")->value();
try {
$oDb = new \Flake\Core\Database\Mysql(
$sHost,
$sDbname,
$sUsername,
$sPassword
);
if(($aMissingTables = \Baikal\Core\Tools::isDBStructurallyComplete($oDb)) !== TRUE) {
# Checking if all tables are missing
$aRequiredTables = \Baikal\Core\Tools::getRequiredTablesList();
if(count($aRequiredTables) !== count($aMissingTables)) {
$sMessage = "<br /><p><strong>Database is not structurally complete.</strong></p>";
$sMessage .= "<p>Missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong></p>";
$sMessage .= "<p>You will find the SQL definition of Baïkal tables in this file: <strong>Core/Resources/Db/MySQL/db.sql</strong></p>";
$sMessage .= "<br /><p>Nothing has been saved. <strong>Please, add these tables to the database before pursuing Baïkal initialization.</strong></p>";
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL"),
$sMessage
);
} else {
# All tables are missing
# We add these tables ourselves to the database, to initialize Baïkal
$sSqlDefinition = file_get_contents(PROJECT_PATH_CORERESOURCES . "Db/MySQL/db.sql");
$oDb->query($sSqlDefinition);
}
}
return TRUE;
} catch(\Exception $e) {
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL"),
"Baïkal was not able to establish a connexion to the MySQL database as configured.<br />MySQL says: " . $e->getMessage()
);
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL_HOST")
);
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL_DBNAME")
);
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL_USERNAME")
);
$oForm->declareError(
$oMorpho->element("PROJECT_DB_MYSQL_PASSWORD")
);
}
}
}
public function hideMySQLFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if($oForm->submitted()) {
$bMySQL = (intval($oForm->postValue("PROJECT_DB_MYSQL")) === 1);
} else {
$bMySQL = PROJECT_DB_MYSQL;
}
if($bMySQL === TRUE) {
$oMorpho->remove("PROJECT_SQLITE_FILE");
} else {
$oMorpho->remove("PROJECT_DB_MYSQL_HOST");
$oMorpho->remove("PROJECT_DB_MYSQL_DBNAME");
$oMorpho->remove("PROJECT_DB_MYSQL_USERNAME");
$oMorpho->remove("PROJECT_DB_MYSQL_PASSWORD");
}
}
}

View file

@ -0,0 +1,124 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Install;
class Initialize extends \Flake\Core\Controller {
protected $aMessages = array();
protected $oModel;
protected $oForm; # \Formal\Form
public function execute() {
# Assert that /Specific is writable
if(!file_exists(PROJECT_PATH_SPECIFIC) || !is_dir(PROJECT_PATH_SPECIFIC) || !is_writable(PROJECT_PATH_SPECIFIC)) {
$message = "<h1>Error - Insufficient permissions on the <span style='background-color: yellow;'>Specific/</span> folder</h1><p>";
$message .= "<p>In order to work properly, Baïkal needs to have write permissions in the <strong>Specific/</strong> folder.</p>";
die($message);
}
$this->createHtaccessFilesIfNeeded();
$this->oModel = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
$this->oForm = $this->oModel->formForThisModelInstance(array(
"close" => FALSE
));
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
# Creating system config, and initializing BAIKAL_ENCRYPTION_KEY
$oSystemConfig = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
$oSystemConfig->set("BAIKAL_ENCRYPTION_KEY", md5(microtime() . rand()));
# Default: PDO::SQLite or PDO::MySQL ?
$aPDODrivers = \PDO::getAvailableDrivers();
if(!in_array('sqlite', $aPDODrivers)) { # PDO::MySQL is already asserted in \Baikal\Core\Tools::assertEnvironmentIsOk()
$oSystemConfig->set("PROJECT_DB_MYSQL", TRUE);
}
$oSystemConfig->persist();
# Using default PROJECT_SQLITE_FILE
$PROJECT_SQLITE_FILE = PROJECT_PATH_SPECIFIC . "db/db.sqlite";
if(!file_exists($PROJECT_SQLITE_FILE)) {
# Installing default sqlite database
@copy(PROJECT_PATH_CORERESOURCES . "Db/SQLite/db.sqlite", $PROJECT_SQLITE_FILE);
}
}
}
}
public function render() {
$sBigIcon = "glyph2x-magic";
$sBaikalVersion = BAIKAL_VERSION;
$oView = new \BaikalAdmin\View\Install\Initialize();
$oView->setData("baikalversion", BAIKAL_VERSION);
if($this->oForm->persisted()) {
$sLink = PROJECT_URI . "admin/install/?/database";
\Flake\Util\Tools::redirect($sLink);
exit(0);
#$sMessage = "<p>Baïkal is now configured. You may <a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Access the Baïkal admin</a></p>";
#$sForm = "";
} else {
$sMessage = "";
$sForm = $this->oForm->render();
}
$oView->setData("message", $sMessage);
$oView->setData("form", $sForm);
return $oView->render();
}
protected function createHtaccessFilesIfNeeded() {
if(!file_exists(PROJECT_PATH_DOCUMENTROOT . ".htaccess")) {
@copy(PROJECT_PATH_CORERESOURCES . "System/htaccess-documentroot", PROJECT_PATH_DOCUMENTROOT . ".htaccess");
}
if(!file_exists(PROJECT_PATH_DOCUMENTROOT . ".htaccess")) {
throw new \Exception("Unable to create " . PROJECT_PATH_DOCUMENTROOT . ".htaccess; you may try to create it manually by copying " . PROJECT_PATH_CORERESOURCES . "System/htaccess-documentroot");
}
if(!file_exists(PROJECT_PATH_SPECIFIC . ".htaccess")) {
@copy(PROJECT_PATH_CORERESOURCES . "System/htaccess-specific", PROJECT_PATH_SPECIFIC . ".htaccess");
}
if(!file_exists(PROJECT_PATH_SPECIFIC . ".htaccess")) {
throw new \Exception("Unable to create " . PROJECT_PATH_SPECIFIC . ".htaccess; you may try to create it manually by copying " . PROJECT_PATH_CORERESOURCES . "System/htaccess-specific");
}
}
}

View file

@ -0,0 +1,168 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Install;
class VersionUpgrade extends \Flake\Core\Controller {
protected $aMessages = array();
protected $oModel;
protected $oForm; # \Formal\Form
protected $aErrors = array();
protected $aSuccess = array();
public function execute() {
}
public function render() {
$sBigIcon = "glyph2x-magic";
$sBaikalVersion = BAIKAL_VERSION;
$sBaikalConfiguredVersion = BAIKAL_CONFIGURED_VERSION;
if(BAIKAL_CONFIGURED_VERSION === BAIKAL_VERSION) {
$sMessage = "Your system is configured to use version <strong>" . $sBaikalConfiguredVersion . "</strong>.<br />There's no upgrade to be done.";
} else {
$sMessage = "Upgrading Baïkal from version <strong>" . $sBaikalConfiguredVersion . "</strong> to version <strong>" . $sBaikalVersion . "</strong>";
}
$sHtml = <<<HTML
<header class="jumbotron subhead" id="overview">
<h1><i class="{$sBigIcon}"></i>Baïkal upgrade wizard</h1>
<p class="lead">{$sMessage}</p>
</header>
HTML;
$bSuccess = $this->upgrade(BAIKAL_CONFIGURED_VERSION, BAIKAL_VERSION);
if(!empty($this->aErrors)) {
$sHtml .= "<h3>Errors</h3>" . implode("<br />\n", $this->aErrors);
}
if(!empty($this->aSuccess)) {
$sHtml .= "<h3>Successful operations</h3>" . implode("<br />\n", $this->aSuccess);
}
if($bSuccess === FALSE) {
$sHtml .= "<p>&nbsp;</p><p><span class='label label-important'>Error</span> Baïkal has not been upgraded. See the section 'Errors' for details.</p>";
} else {
$sHtml .= "<p>&nbsp;</p><p>Baïkal has been successfully upgraded. You may now <a class='btn btn-success' href='" . PROJECT_URI . "admin/'>Access the Baïkal admin</a></p>";
}
return $sHtml;
}
protected function upgrade($sVersionFrom, $sVersionTo) {
if($sVersionFrom === "0.2.0") {
$sOldDbFilePath = PROJECT_PATH_SPECIFIC . "Db/.ht.db.sqlite";
if(PROJECT_SQLITE_FILE === $sOldDbFilePath) {
$sNewDbFilePath = PROJECT_PATH_SPECIFIC . "Db/db.sqlite";
# Move old db from Specific/Db/.ht.db.sqlite to Specific/Db/db.sqlite
if(!file_exists($sNewDbFilePath)) {
if(!is_writable(dirname($sNewDbFilePath))) {
$this->aErrors[] = "DB file path '" . dirname($sNewDbFilePath) . "' is not writable";
return FALSE;
}
if(!@copy($sOldDbFilePath, $sNewDbFilePath)) {
$this->aErrors[] = "DB could not be copied from '" . $sOldDbFilePath . "' to '" . $sNewDbFilePath . "'.";
return FALSE;
}
$this->aSuccess[] = "SQLite database has been renamed from '" . $sOldDbFilePath . "' to '" . $sNewDbFilePath . "'";
}
}
}
if(version_compare($sVersionFrom, '0.2.3', '<=')) {
# Upgrading DB
# etag VARCHAR(32),
# size INT(11) UNSIGNED NOT NULL,
# componenttype VARCHAR(8),
# firstoccurence INT(11) UNSIGNED,
# lastoccurence INT(11) UNSIGNED,
if(defined("PROJECT_DB_MYSQL") && PROJECT_DB_MYSQL === TRUE) {
$aSql = array(
"ALTER TABLE calendarobjects ADD COLUMN etag VARCHAR(32)",
"ALTER TABLE calendarobjects ADD COLUMN size INT(11) UNSIGNED NOT NULL",
"ALTER TABLE calendarobjects ADD COLUMN componenttype VARCHAR(8)",
"ALTER TABLE calendarobjects ADD COLUMN firstoccurence INT(11) UNSIGNED",
"ALTER TABLE calendarobjects ADD COLUMN lastoccurence INT(11) UNSIGNED",
"ALTER TABLE calendars ADD COLUMN transparent TINYINT(1) NOT NULL DEFAULT '0'",
);
$this->aSuccess[] = "MySQL database has been successfuly upgraded.";
} else {
$aSql = array(
"ALTER TABLE calendarobjects ADD COLUMN etag text",
"ALTER TABLE calendarobjects ADD COLUMN size integer",
"ALTER TABLE calendarobjects ADD COLUMN componenttype text",
"ALTER TABLE calendarobjects ADD COLUMN firstoccurence integer",
"ALTER TABLE calendarobjects ADD COLUMN lastoccurence integer",
"ALTER TABLE calendars ADD COLUMN transparent bool",
"ALTER TABLE principals ADD COLUMN vcardurl text", # This one is added in SQLite but not MySQL, because it is already there since the beginning in MySQL
);
$this->aSuccess[] = "SQLite database has been successfuly upgraded.'";
}
try{
foreach($aSql as $sAlterTableSql) {
$GLOBALS["DB"]->query($sAlterTableSql);
}
} catch(\Exception $e) {
$this->aSuccess = array();
$this->aErrors[] = "<p>Database cannot be upgraded.<br />Caught exception: " . $e->getMessage() . "</p>";
return FALSE;
}
}
if(version_compare($sVersionFrom, '0.2.4', '<=')) {
# Nothing to do :)
}
$this->updateConfiguredVersion($sVersionTo);
return TRUE;
}
protected function updateConfiguredVersion($sVersionTo) {
# Create new settings
$oConfig = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
$oConfig->persist();
# Update BAIKAL_CONFIGURED_VERSION
$oConfig = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
$oConfig->set("BAIKAL_CONFIGURED_VERSION", $sVersionTo);
$oConfig->persist();
}
}

View file

@ -0,0 +1,77 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Login extends \Flake\Core\Controller {
public function execute() {
}
public function render() {
$sActionUrl = \Flake\Util\Tools::getCurrentUrl();
$sSubmittedFlagName = "auth";
$sMessage = "";
if(self::isSubmitted() && !\BaikalAdmin\Core\Auth::isAuthenticated()) {
$sMessage = \Formal\Core\Message::error(
"The login/password you provided is invalid. Please retry.",
"Authentication error"
);
} elseif(self::justLoggedOut()) {
$sMessage = \Formal\Core\Message::notice(
"You have been disconnected from your session.",
"Session ended",
FALSE
);
}
$sLogin = htmlspecialchars(\Flake\Util\Tools::POST("login"));
$sPassword = htmlspecialchars(\Flake\Util\Tools::POST("password"));
if(trim($sLogin) === "") {
$sLogin = "admin";
}
$oView = new \BaikalAdmin\View\Login();
$oView->setData("message", $sMessage);
$oView->setData("actionurl", $sActionUrl);
$oView->setData("submittedflagname", $sSubmittedFlagName);
$oView->setData("login", $sLogin);
$oView->setData("password", $sPassword);
return $oView->render();
}
protected static function isSubmitted() {
return (intval(\Flake\Util\Tools::POST("auth")) === 1);
}
protected static function justLoggedOut() {
$aParams = $GLOBALS["ROUTER"]::getURLParams();
return (!empty($aParams) && $aParams[0] === "loggedout");
}
}

View file

@ -0,0 +1,41 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Logout extends \Flake\Core\Controller {
public function execute() {
\BaikalAdmin\Core\Auth::unAuthenticate();
$sControllerForDefaultRoute = $GLOBALS["ROUTER"]::getControllerForRoute("default");
$sLink = $GLOBALS["ROUTER"]::buildRouteForController($sControllerForDefaultRoute, "loggedout");
\Flake\Util\Tools::redirect($sLink);
}
public function render() {
}
}

View file

@ -0,0 +1,79 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation;
class Topbar extends \Flake\Core\Controller {
public function execute() {
}
public function render() {
$oView = new \BaikalAdmin\View\Navigation\Topbar();
$sCurrentRoute = $GLOBALS["ROUTER"]::getCurrentRoute();
$sActiveHome = $sActiveUsers = $sActiveSettingsStandard = $sActiveSettingsSystem = "";
$sControllerForDefaultRoute = $GLOBALS["ROUTER"]::getControllerForRoute("default");
$sHomeLink = $sControllerForDefaultRoute::link();
$sUsersLink = \BaikalAdmin\Controller\Users::link();
$sSettingsStandardLink = \BaikalAdmin\Controller\Settings\Standard::link();
$sSettingsSystemLink = \BaikalAdmin\Controller\Settings\System::link();
$sLogoutLink = \BaikalAdmin\Controller\Logout::link();
if($sCurrentRoute === "default") {
$sActiveHome = "active";
}
if(
$sCurrentRoute === $GLOBALS["ROUTER"]::getRouteForController("\BaikalAdmin\Controller\Users") ||
$sCurrentRoute === $GLOBALS["ROUTER"]::getRouteForController("\BaikalAdmin\Controller\User\Calendars") ||
$sCurrentRoute === $GLOBALS["ROUTER"]::getRouteForController("\BaikalAdmin\Controller\User\AddressBooks")
) {
$sActiveUsers = "active";
}
if($sCurrentRoute === $GLOBALS["ROUTER"]::getRouteForController("\BaikalAdmin\Controller\Settings\Standard")) {
$sActiveSettingsStandard = "active";
}
if($sCurrentRoute === $GLOBALS["ROUTER"]::getRouteForController("\BaikalAdmin\Controller\Settings\System")) {
$sActiveSettingsSystem = "active";
}
$oView->setData("activehome", $sActiveHome);
$oView->setData("activeusers", $sActiveUsers);
$oView->setData("activesettingsstandard", $sActiveSettingsStandard);
$oView->setData("activesettingssystem", $sActiveSettingsSystem);
$oView->setData("homelink", $sHomeLink);
$oView->setData("userslink", $sUsersLink);
$oView->setData("settingsstandardlink", $sSettingsStandardLink);
$oView->setData("settingssystemlink", $sSettingsSystemLink);
$oView->setData("logoutlink", $sLogoutLink);
return $oView->render();
}
}

View file

@ -0,0 +1,38 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation\Topbar;
class Anonymous extends \Flake\Core\Controller {
public function execute() {
}
public function render() {
$oView = new \BaikalAdmin\View\Navigation\Topbar\Anonymous();
return $oView->render();
}
}

View file

@ -0,0 +1,38 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation\Topbar;
class Install extends \Flake\Core\Controller {
public function execute() {
}
public function render() {
$oView = new \BaikalAdmin\View\Navigation\Topbar\Install();
return $oView->render();
}
}

View file

@ -0,0 +1,55 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Settings;
class Standard extends \Flake\Core\Controller {
public function execute() {
$this->oModel = new \Baikal\Model\Config\Standard(PROJECT_PATH_SPECIFIC . "config.php");
# Assert that config file is writable
if(!$this->oModel->writable()) {
throw new \Exception("Config file is not writable;" . __FILE__ . " > " . __LINE__);
}
$this->oForm = $this->oModel->formForThisModelInstance(array(
"close" => FALSE
));
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
public function render() {
$oView = new \BaikalAdmin\View\Settings\Standard();
$oView->setData("form", $this->oForm->render());
return $oView->render();
}
}

View file

@ -0,0 +1,118 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Settings;
class System extends \Flake\Core\Controller {
public function execute() {
$this->oModel = new \Baikal\Model\Config\System(PROJECT_PATH_SPECIFIC . "config.system.php");
# Assert that config file is writable
if(!$this->oModel->writable()) {
throw new \Exception("System config file is not writable;" . __FILE__ . " > " . __LINE__);
}
$this->oForm = $this->oModel->formForThisModelInstance(array(
"close" => FALSE,
"hook.morphology" => array($this, "morphologyHook"),
"hook.validation" => array($this, "validationHook"),
));
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
public function render() {
$oView = new \BaikalAdmin\View\Settings\System();
$oView->setData("message", \Formal\Core\Message::notice(
"Do not change anything on this page unless you really know what you are doing.<br />You might break Baïkal if you misconfigure something here.",
"Warning !",
FALSE
));
$oView->setData("form", $this->oForm->render());
return $oView->render();
}
public function morphologyHook(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if($oForm->submitted()) {
$bMySQL = (intval($oForm->postValue("PROJECT_DB_MYSQL")) === 1);
} else {
$bMySQL = PROJECT_DB_MYSQL;
}
if($bMySQL === TRUE) {
$oMorpho->remove("PROJECT_SQLITE_FILE");
} else {
$oMorpho->remove("PROJECT_DB_MYSQL_HOST");
$oMorpho->remove("PROJECT_DB_MYSQL_DBNAME");
$oMorpho->remove("PROJECT_DB_MYSQL_USERNAME");
$oMorpho->remove("PROJECT_DB_MYSQL_PASSWORD");
}
}
public function validationHook(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if(intval($oForm->modelInstance()->get("PROJECT_DB_MYSQL")) === 1) {
# We have to check the MySQL connection
$sHost = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_HOST");
$sDbName = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_DBNAME");
$sUsername = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_USERNAME");
$sPassword = $oForm->modelInstance()->get("PROJECT_DB_MYSQL_PASSWORD");
try {
$oDB = new \Flake\Core\Database\Mysql(
$sHost,
$sDbName,
$sUsername,
$sPassword
);
} catch(\Exception $e) {
$sMessage = "<strong>MySQL error:</strong> " . $e->getMessage();
$sMessage .= "<br /><strong>Nothing has been saved</strong>";
$oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_HOST"), $sMessage);
$oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_DBNAME"));
$oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_USERNAME"));
$oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL_PASSWORD"));
return;
}
if(($aMissingTables = \Baikal\Core\Tools::isDBStructurallyComplete($oDB)) !== TRUE) {
$sMessage = "<strong>MySQL error:</strong> These tables, required by Baïkal, are missing: <strong>" . implode(", ", $aMissingTables) . "</strong><br />";
$sMessage .= "You may want create these tables using the file <strong>Core/Resources/Db/MySQL/db.sql</strong>";
$sMessage .= "<br /><br /><strong>Nothing has been saved</strong>";
$oForm->declareError($oMorpho->element("PROJECT_DB_MYSQL"), $sMessage);
return;
}
}
}
}

View file

@ -0,0 +1,278 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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 AddressBooks extends \Flake\Core\Controller {
protected $aMessages = array();
protected $oModel; # \Baikal\Model\Contact
protected $oUser; # \Baikal\Model\User
protected $oForm; # \Formal\Form
public function execute() {
if(($iUser = $this->currentUserId()) === FALSE) {
throw new \Exception("BaikalAdmin\Controller\User\Contacts::render(): User get-parameter not found.");
}
$this->oUser = new \Baikal\Model\User($iUser);
if($this->actionNewRequested()) {
$this->actionNew();
}
if($this->actionEditRequested()) {
$this->actionEdit();
}
if($this->actionDeleteRequested()) {
$this->actionDelete();
}
}
public function render() {
$oView = new \BaikalAdmin\View\User\AddressBooks();
# User
$oView->setData("user", $this->oUser);
# Render list of address books
$aAddressBooks = array();
$oAddressBooks = $this->oUser->getAddressBooksBaseRequester()->execute();
reset($oAddressBooks);
foreach($oAddressBooks as $addressbook) {
$aAddressBooks[] = array(
"linkedit" => $this->linkEdit($addressbook),
"linkdelete" => $this->linkDelete($addressbook),
"icon" => $addressbook->icon(),
"label" => $addressbook->label(),
"description" => $addressbook->get("description"),
);
}
$oView->setData("addressbooks", $aAddressBooks);
# Messages
$sMessages = implode("\n", $this->aMessages);
$oView->setData("messages", $sMessages);
if($this->actionNewRequested() || $this->actionEditRequested()) {
$sForm = $this->oForm->render();
} else {
$sForm = "";
}
$oView->setData("form", $sForm);
$oView->setData("titleicon", \Baikal\Model\AddressBook::bigicon());
$oView->setData("modelicon", $this->oUser->mediumIcon());
$oView->setData("modellabel", $this->oUser->label());
$oView->setData("linkback", \BaikalAdmin\Controller\Users::link());
$oView->setData("linknew", $this->linkNew());
$oView->setData("addressbookicon", \Baikal\Model\AddressBook::icon());
return $oView->render();
}
protected function initForm() {
if($this->actionEditRequested() || $this->actionNewRequested()) {
$aOptions = array(
"closeurl" => $this->linkHome()
);
$this->oForm = $this->oModel->formForThisModelInstance($aOptions);
}
}
protected function currentUserId() {
$aParams = $this->getParams();
if(($iUser = intval($aParams["user"])) === 0) {
return FALSE;
}
return $iUser;
}
# Action new
public function linkNew() {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"new" => 1
)) . "#form";
}
protected function actionNewRequested() {
$aParams = $this->getParams();
if(array_key_exists("new", $aParams) && intval($aParams["new"]) === 1) {
return TRUE;
}
return FALSE;
}
protected function actionNew() {
# Building floating model object
$this->oModel = new \Baikal\Model\AddressBook();
$this->oModel->set(
"principaluri",
$this->oUser->get("uri")
);
$this->oModel->set(
"ctag",
"1"
);
$this->initForm();
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
$this->oForm->setOption(
"action",
$this->linkEdit(
$this->oForm->modelInstance()
)
);
}
}
}
# Action edit
public function linkEdit(\Baikal\Model\AddressBook $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"edit" => $oModel->get("id")
)) . "#form";
}
protected function actionEditRequested() {
$aParams = $this->getParams();
if(array_key_exists("edit", $aParams) && intval($aParams["edit"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionEdit() {
# Building anchored model object
$aParams = $this->getParams();
$this->oModel = new \Baikal\Model\AddressBook(intval($aParams["edit"]));
# Initialize corresponding form
$this->initForm();
# Process form
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
# Action delete + confirm
public function linkDelete(\Baikal\Model\AddressBook $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"delete" => $oModel->get("id")
)) . "#message";
}
public function linkDeleteConfirm(\Baikal\Model\AddressBook $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"delete" => $oModel->get("id"),
"confirm" => 1
)) . "#message";
}
protected function actionDeleteRequested() {
$aParams = $this->getParams();
if(array_key_exists("delete", $aParams) && intval($aParams["delete"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionDeleteConfirmed() {
if(($iPrimary = $this->actionDeleteRequested()) === FALSE) {
return FALSE;
}
$aParams = $this->getParams();
if(array_key_exists("confirm", $aParams) && intval($aParams["confirm"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionDelete() {
$aParams = $this->getParams();
$iModel = intval($aParams["delete"]);
if($this->actionDeleteConfirmed() !== FALSE) {
# catching Exception thrown when model already destroyed
# happens when user refreshes page on delete-URL, for instance
try {
$oModel = new \Baikal\Model\AddressBook($iModel);
$oModel->destroy();
} catch(\Exception $e) {
# already deleted; silently discarding
}
# Redirecting to admin home
\Flake\Util\Tools::redirectUsingMeta($this->linkHome());
} else {
$oModel = new \Baikal\Model\AddressBook($iModel);
$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 contact book and all it's visiting cards. This operation cannot be undone.</p><p>So, now that you know all that, what shall we do ?</p>",
$this->linkDeleteConfirm($oModel),
"Delete <strong><i class='" . $oModel->icon() . " icon-white'></i> " . $oModel->label() . "</strong>",
$this->linkHome()
);
}
}
# Link to home
public function linkHome() {
return self::buildRoute(array(
"user" => $this->currentUserId(),
));
}
}

View file

@ -0,0 +1,281 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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 execute() {
if(($iUser = $this->currentUserId()) === FALSE) {
throw new \Exception("BaikalAdmin\Controller\User\Calendars::render(): User get-parameter not found.");
}
$this->oUser = new \Baikal\Model\User($iUser);
if($this->actionNewRequested()) {
$this->actionNew();
} elseif($this->actionEditRequested()) {
$this->actionEdit();
} elseif($this->actionDeleteRequested()) {
$this->actionDelete();
}
}
public function render() {
$oView = new \BaikalAdmin\View\User\Calendars();
# User
$oView->setData("user", $this->oUser);
# List of calendars
$oCalendars = $this->oUser->getCalendarsBaseRequester()->execute();
$aCalendars = array();
foreach($oCalendars as $calendar) {
$aCalendars[] = array(
"linkedit" => $this->linkEdit($calendar),
"linkdelete" => $this->linkDelete($calendar),
"icon" => $calendar->icon(),
"label" => $calendar->label(),
"description" => $calendar->get("description"),
);
}
$oView->setData("calendars", $aCalendars);
# Messages
$sMessages = implode("\n", $this->aMessages);
$oView->setData("messages", $sMessages);
if($this->actionNewRequested() || $this->actionEditRequested()) {
$sForm = $this->oForm->render();
} else {
$sForm = "";
}
$oView->setData("form", $sForm);
$oView->setData("titleicon", \Baikal\Model\Calendar::bigicon());
$oView->setData("modelicon", $this->oUser->mediumicon());
$oView->setData("modellabel", $this->oUser->label());
$oView->setData("linkback", \BaikalAdmin\Controller\Users::link());
$oView->setData("linknew", $this->linkNew());
$oView->setData("calendaricon", \Baikal\Model\Calendar::icon());
return $oView->render();
}
protected function initForm() {
if($this->actionEditRequested() || $this->actionNewRequested()) {
$aOptions = array(
"closeurl" => $this->linkHome()
);
$this->oForm = $this->oModel->formForThisModelInstance($aOptions);
}
}
protected function currentUserId() {
$aParams = $this->getParams();
if(($iUser = intval($aParams["user"])) === 0) {
return FALSE;
}
return $iUser;
}
# Action new
public function linkNew() {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"new" => 1
)) . "#form";
}
protected function actionNewRequested() {
$aParams = $this->getParams();
if(array_key_exists("new", $aParams) && intval($aParams["new"]) === 1) {
return TRUE;
}
return FALSE;
}
protected function actionNew() {
# Building floating model 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"
);
# Initialize corresponding form
$this->initForm();
# Process form
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
$this->oForm->setOption(
"action",
$this->linkEdit(
$this->oForm->modelInstance()
)
);
}
}
}
# Action edit
public function linkEdit(\Baikal\Model\Calendar $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"edit" => $oModel->get("id")
)) . "#form";
}
protected function actionEditRequested() {
$aParams = $this->getParams();
if(array_key_exists("edit", $aParams) && intval($aParams["edit"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionEdit() {
# Building anchored model object
$aParams = $this->getParams();
$this->oModel = new \Baikal\Model\Calendar(intval($aParams["edit"]));
# Initialize corresponding form
$this->initForm();
# Process form
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
# Action delete + confirm
public function linkDelete(\Baikal\Model\Calendar $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"delete" => $oModel->get("id")
)) . "#message";
}
public function linkDeleteConfirm(\Baikal\Model\Calendar $oModel) {
return self::buildRoute(array(
"user" => $this->currentUserId(),
"delete" => $oModel->get("id"),
"confirm" => 1
)) . "#message";
}
protected function actionDeleteRequested() {
$aParams = $this->getParams();
if(array_key_exists("delete", $aParams) && intval($aParams["delete"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionDeleteConfirmed() {
if($this->actionDeleteRequested() === FALSE) {
return FALSE;
}
$aParams = $this->getParams();
if(array_key_exists("confirm", $aParams) && intval($aParams["confirm"]) === 1) {
return TRUE;
}
return FALSE;
}
protected function actionDelete() {
$aParams = $this->getParams();
$iCalendar = intval($aParams["delete"]);
if($this->actionDeleteConfirmed() !== 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($this->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>",
$this->linkDeleteConfirm($oModel),
"Delete <strong><i class='" . $oModel->icon() . " icon-white'></i> " . $oModel->label() . "</strong>",
$this->linkHome()
);
}
}
# Link to home
public function linkHome() {
return self::buildRoute(array(
"user" => $this->currentUserId(),
));
}
}

View file

@ -0,0 +1,241 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Users extends \Flake\Core\Controller {
protected $aMessages = array();
public function execute() {
if($this->actionEditRequested()) {
$this->actionEdit();
}
if($this->actionNewRequested()) {
$this->actionNew();
}
if($this->actionDeleteRequested()) {
$this->actionDelete();
}
}
public function render() {
$oView = new \BaikalAdmin\View\Users();
# List of users
$aUsers = array();
$oUsers = \Baikal\Model\User::getBaseRequester()->execute();
reset($oUsers);
foreach($oUsers as $user) {
$aUsers[] = array(
"linkcalendars" => \BaikalAdmin\Controller\Users::linkCalendars($user),
"linkaddressbooks" => \BaikalAdmin\Controller\Users::linkAddressBooks($user),
"linkedit" => \BaikalAdmin\Controller\Users::linkEdit($user),
"linkdelete" => \BaikalAdmin\Controller\Users::linkDelete($user),
"mailtouri" => $user->getMailtoURI(),
"username" => $user->get("username"),
"displayname" => $user->get("displayname"),
"email" => $user->get("email"),
);
}
$oView->setData("users", $aUsers);
$oView->setData("calendaricon", \Baikal\Model\Calendar::icon());
$oView->setData("usericon", \Baikal\Model\User::icon());
# Messages
$sMessages = implode("\n", $this->aMessages);
$oView->setData("messages", $sMessages);
# Form
if($this->actionNewRequested() || $this->actionEditRequested()) {
$sForm = $this->oForm->render();
} else {
$sForm = "";
}
$oView->setData("form", $sForm);
$oView->setData("usericon", \Baikal\Model\User::icon());
$oView->setData("controller", $this);
return $oView->render();
}
protected function initForm() {
if($this->actionEditRequested() || $this->actionNewRequested()) {
$aOptions = array(
"closeurl" => self::link()
);
$this->oForm = $this->oModel->formForThisModelInstance($aOptions);
}
}
# Action edit
protected function actionEditRequested() {
$aParams = $this->getParams();
if(array_key_exists("edit", $aParams) && intval($aParams["edit"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionEdit() {
$aParams = $this->getParams();
$this->oModel = new \Baikal\Model\User(intval($aParams["edit"]));
$this->initForm();
if($this->oForm->submitted()) {
$this->oForm->execute();
}
}
# Action delete
protected function actionDeleteRequested() {
$aParams = $this->getParams();
if(array_key_exists("delete", $aParams) && intval($aParams["delete"]) > 0) {
return TRUE;
}
return FALSE;
}
protected function actionDeleteConfirmed() {
if($this->actionDeleteRequested() === FALSE) {
return FALSE;
}
$aParams = $this->getParams();
if(array_key_exists("confirm", $aParams) && intval($aParams["confirm"]) === 1) {
return TRUE;
}
return FALSE;
}
protected function actionDelete() {
$aParams = $this->getParams();
$iUser = intval($aParams["delete"]);
if($this->actionDeleteConfirmed() !== FALSE) {
# catching Exception thrown when model already destroyed
# happens when user refreshes delete-page, for instance
try {
$oUser = new \Baikal\Model\User($iUser);
$oUser->destroy();
} catch(\Exception $e) {
# user is already deleted; silently discarding
}
# Redirecting to admin home
\Flake\Util\Tools::redirectUsingMeta($this->link());
} else {
$oUser = new \Baikal\Model\User($iUser);
$this->aMessages[] = \Formal\Core\Message::warningConfirmMessage(
"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>",
$this->linkDeleteConfirm($oUser),
"Delete <strong><i class='" . $oUser->icon() . " icon-white'></i> " . $oUser->label() . "</strong>",
$this->link()
);
}
}
# Action new
protected function actionNewRequested() {
$aParams = $this->getParams();
if(array_key_exists("new", $aParams) && intval($aParams["new"]) === 1) {
return TRUE;
}
return FALSE;
}
protected function actionNew() {
$this->oModel = new \Baikal\Model\User();
$this->initForm();
if($this->oForm->submitted()) {
$this->oForm->execute();
if($this->oForm->persisted()) {
$this->oForm->setOption(
"action",
$this->linkEdit(
$this->oForm->modelInstance()
)
);
}
}
}
public function linkNew() {
return self::buildRoute(array(
"new" => 1
)) . "#form";
}
public static function linkEdit(\Baikal\Model\User $user) {
return self::buildRoute(array(
"edit" => $user->get("id")
)) . "#form";
}
public static function linkDelete(\Baikal\Model\User $user) {
return self::buildRoute(array(
"delete" => $user->get("id")
)) . "#message";
}
public static function linkDeleteConfirm(\Baikal\Model\User $user) {
return self::buildRoute(array(
"delete" => $user->get("id"),
"confirm" => 1
)) . "#message";
}
public static function linkCalendars(\Baikal\Model\User $user) {
return \BaikalAdmin\Controller\User\Calendars::buildRoute(array(
"user" => $user->get("id"),
));
}
public static function linkAddressBooks(\Baikal\Model\User $user) {
return \BaikalAdmin\Controller\User\AddressBooks::buildRoute(array(
"user" => $user->get("id"),
));
}
}

View file

@ -0,0 +1,128 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Core;
class Auth {
public static function assertEnabled() {
if(!defined("BAIKAL_ADMIN_ENABLED") || BAIKAL_ADMIN_ENABLED !== TRUE) {
die("<h1>Ba&iuml;kal Admin is disabled.</h1>To enable it, set BAIKAL_ADMIN_ENABLED to TRUE in <b>Specific/config.php</b>");
}
self::assertUnlocked();
}
public static function assertUnlocked() {
if(defined("BAIKAL_CONTEXT_INSTALL") && BAIKAL_CONTEXT_INSTALL === TRUE) {
$sToolName = "Ba&iuml;kal Install Tool";
$sFileName = "ENABLE_INSTALL";
} else {
if(!defined("BAIKAL_ADMIN_AUTOLOCKENABLED") || BAIKAL_ADMIN_AUTOLOCKENABLED === FALSE) {
return TRUE;
}
$sToolName = "Ba&iuml;kal Admin";
$sFileName = "ENABLE_ADMIN";
}
$sEnableFile = PROJECT_PATH_SPECIFIC . $sFileName;
$bLocked = TRUE;
if(file_exists($sEnableFile)) {
clearstatcache();
$iTime = intval(filemtime($sEnableFile));
if((time() - $iTime) < 3600) {
# file has been created/updated less than an hour ago; update it's mtime
if(is_writable($sEnableFile)) {
@file_put_contents($sEnableFile, '');
}
$bLocked = FALSE;
} else {
// file has been created more than an hour ago
// delete and declare locked
if(!@unlink($sEnableFile)) {
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, create (or re-create if it exists already) an empty file named <strong>" . $sFileName . "</strong> (uppercase, no file extension) in the <b>Specific/</b> folder of Ba&iuml;kal.");
}
}
}
if($bLocked) {
die("<h1>" . $sToolName . " is locked.</h1>To unlock it, create (or re-create if it exists already) an empty file named <strong>" . $sFileName . "</strong> (uppercase, no file extension) in the <b>Specific/</b> folder of Ba&iuml;kal.");
}
}
public static function isAuthenticated() {
if(isset($_SESSION["baikaladminauth"]) && $_SESSION["baikaladminauth"] === md5(BAIKAL_ADMIN_PASSWORDHASH)) {
return TRUE;
}
return FALSE;
}
public static function authenticate() {
if(intval(\Flake\Util\Tools::POST("auth")) !== 1) {
return FALSE;
}
$sUser = \Flake\Util\Tools::POST("login");
$sPass = \Flake\Util\Tools::POST("password");
$sPassHash = self::hashAdminPassword($sPass);
if($sUser === "admin" && $sPassHash === BAIKAL_ADMIN_PASSWORDHASH) {
$_SESSION["baikaladminauth"] = md5(BAIKAL_ADMIN_PASSWORDHASH);
return TRUE;
}
return FALSE;
}
public static function unAuthenticate() {
unset($_SESSION["baikaladminauth"]);
}
public static function hashAdminPassword($sPassword) {
if(defined("BAIKAL_AUTH_REALM")) {
$sAuthRealm = BAIKAL_AUTH_REALM;
} else {
$sAuthRealm = "BaikalDAV"; # Fallback to default value; useful when initializing App, as all constants are not set yet
}
return md5('admin:' . $sAuthRealm . ':' . $sPassword);
}
public static function lockAdmin() {
@unlink(PROJECT_PATH_SPECIFIC . "ENABLE_ADMIN");
}
public static function lockInstall() {
@unlink(PROJECT_PATH_SPECIFIC . "ENABLE_INSTALL");
}
}

View file

@ -0,0 +1,35 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Core;
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,42 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Framework extends \Flake\Core\Framework {
public static function bootstrap() {
define("BAIKALADMIN_PATH_ROOT", PROJECT_PATH_ROOT . "Core/Frameworks/BaikalAdmin/"); # ./
\Baikal\Framework::bootstrap();
\Formal\Framework::bootstrap();
$GLOBALS["ROUTER"]::setURIPath("admin/");
# Include BaikalAdmin Framework config
require_once(BAIKALADMIN_PATH_ROOT . "config.php");
}
}

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,114 @@
{% autoescape false %}
{% set url = 'http://baikal-server.com' %}
<style>
.label-intext { vertical-align: top;}
</style>
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-circle-info"></i>Dashboard</h1>
</header>
<section id="about">
<div class="page-header">
<h1>About this system</h1>
</div>
<div class="row">
<div class="span3">
<h2>Version</h2>
<p>This systems runs<br />
Baïkal <span class="label label-info label-intext">{{ BAIKAL_VERSION }}</span>, <em>{{ PROJECT_PACKAGE }}</em> package<br />
<small><a href="{{ url }}">{{ url }}</a></small>
</p>
</div>
<div class="span3">
<h2>Services</h2>
{% if BAIKAL_CAL_ENABLED %}
{% set caldavclass = 'label-success' %}
{% set caldavtext = 'On' %}
{% else %}
{% set caldavclass = 'label-important' %}
{% set caldavtext = 'Off' %}
{% endif %}
{% if BAIKAL_CARD_ENABLED %}
{% set carddavclass = 'label-success' %}
{% set carddavtext = 'On' %}
{% else %}
{% set carddavclass = 'label-important' %}
{% set carddavtext = 'Off' %}
{% endif %}
<table class="table">
<tbody>
<tr>
<td>Web admin</td>
<td><span class="label label-success label-intext">On</span></p></td>
</tr>
<tr>
<td>CalDAV</td>
<td><span class="label {{ caldavclass }} label-intext">{{ caldavtext }}</span></td>
</tr>
<tr>
<td>CardDAV</td>
<td><span class="label {{ carddavclass }} label-intext">{{ carddavtext }}</span></td>
</tr>
</tbody>
</table>
</div>
<div class="span6">
<h2>License and credits</h2>
<p>Baïkal is open source software licensed under the terms of the GNU GPL v3.</p>
<p>Baïkal is based upon other open source projects.<br />Read the <a href="https://github.com/jeromeschneider/Baikal/blob/master/README.md" target="_blank">README.md</a> file to learn about that.</p>
<p>Baïkal is developed by <a href="https://github.com/jeromeschneider" target="_blank">Jérôme Schneider</a>.
</div>
</div>
</section>
<section id="statistics">
<div class="page-header">
<h1>Statistics</h1>
</div>
<div class="row">
<div class="span4">
<h2>Users</h2>
<table class="table">
<tbody>
<tr>
<td>Registered users</td>
<td><span class="badge">{{ nbusers }}</span></td>
</tr>
</tbody>
</table>
</div>
<div class="span4">
<h2>CalDAV</h2>
<table class="table">
<tbody>
<tr>
<td>Number of calendars</td>
<td><span class="badge">{{ nbcalendars }}</span></td>
</tr>
<tr>
<td>Number of events</td>
<td><span class="badge">{{ nbevents }}</span></td>
</tr>
</tbody>
</table>
</div>
<div class="span4">
<h2>CardDAV</h2>
<table class="table">
<tbody>
<tr>
<td>Number of address books</td>
<td><span class="badge">{{ nbbooks }}</span></td>
</tr>
<tr>
<td>Number of contacts</td>
<td><span class="badge">{{ nbcontacts }}</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
{% endautoescape %}

View file

@ -0,0 +1,11 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-magic"></i>Baïkal Database setup</h1>
<p class="lead">Configure Baïkal Database.</p>
</header>
<a id="formid"></a>
{{ message }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,11 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-magic"></i>Baïkal initialization wizard</h1>
<p class="lead">Configure your new Baïkal <strong>{{ baikalversion }}</strong> installation.</p>
</header>
<a id="formid"></a>
{{ message }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,27 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-lock"></i>Authentication</h1>
<p class="lead">Please authenticate to access Baïkal Web Admin.</p>
</header>
{{ message }}
<form class="form-horizontal" action="{{ actionurl }}" method="post" enctype="multipart/formdata">
<input type="hidden" name="{{ submittedflagname }}" value="1" />
<fieldset>
<p>
<label for="login">Login</label>
<input type="text" name="login" value="{{ login }}" />
</p>
<p>
<label for="password">Password</label>
<input type="password" name="password" value="{{ password }}" />
</p>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Authenticate</button>
</div>
</fieldset>
</form>
{% endautoescape %}

View file

@ -0,0 +1,23 @@
{% autoescape false %}
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{ homelink }}"><img style="vertical-align: text-top; line-height: 20px;" src="res/core/BaikalAdmin/Templates/Page/baikal-text-20.png" /> Web Admin</a>
<div class="nav-collapse">
<ul class="nav">
<li class="{{ activehome }}"> <a href="{{ homelink }}">Dashboard</a></li>
<li class="{{ activeusers }}"> <a href="{{ userslink }}">Users and resources</a></li>
<li class="{{ activesettingsstandard }}"> <a href="{{ settingsstandardlink }}">Settings</a></li>
<li class="{{ activesettingssystem }}"> <a href="{{ settingssystemlink }}">System settings</a></li>
<li> <a href="{{ logoutlink }}"><i class="icon-eject icon-white"></i> Logout</a></li>
</ul>
</div>
</div>
</div>
</div>
{% endautoescape %}

View file

@ -0,0 +1,7 @@
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand"><img style="vertical-align: text-top; line-height: 20px;" src="res/core/BaikalAdmin/Templates/Page/baikal-text-20.png" /> Web Admin</a>
</div>
</div>
</div>

View file

@ -0,0 +1,7 @@
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand"><img style="vertical-align: text-top; line-height: 20px;" src="res/core/BaikalAdmin/Templates/Page/baikal-text-20.png" /> Install Tool</a>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,55 @@
{% autoescape false %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{ pagetitle }}</title>
<base href="{{ baseurl }}" />
<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/GlyphiconsPro/glyphpro.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/GlyphiconsPro/glyphpro-2x.css" rel="stylesheet" />
<link href="res/core/BaikalAdmin/Templates/Page/style.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="res/core/BaikalAdmin/html5.js"></script>
<![endif]-->
{{ head }}
</head>
<body>
{{ navbar }}
<div class="container">
{{ Payload }}
</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>
<script src="res/core/TwitterBootstrap/js/bootstrap-tooltip.js"></script>
<script src="res/core/TwitterBootstrap/js/bootstrap-popover.js"></script>
<script type="text/javascript">
$("[rel=tooltip]").tooltip();
$(".popover-hover").popover();
$(".popover-focus").popover({
trigger: 'focus'
});
$(".popover-focus-top").popover({
trigger: 'focus',
placement: 'top'
});
$(".popover-focus-bottom").popover({
trigger: 'focus',
placement: 'bottom'
});
</script>
{{ javascript }}
</body>
</html>
{% endautoescape %}

View file

@ -0,0 +1,83 @@
/* generics */
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
.table thead th {
background-color: #777;
color: white;
}
.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th {
background-color: rgb(240, 240, 240);
}
table .no-border-left { border-left: none !important;}
table p {
margin-bottom: 0;
}
p.lead { line-height: 40px;}
/* Jumbotrons
-------------------------------------------------- */
.jumbotron {
position: relative;
}
.jumbotron h1 {
font-size: 40px;
font-weight: bold;
letter-spacing: -1px;
line-height: 90px;
}
.jumbotron p {
margin-bottom: 18px;
font-weight: 300;
}
.jumbotron .btn-large {
font-size: 20px;
font-weight: normal;
padding: 14px 24px;
margin-right: 10px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
.jumbotron .btn-large small {
font-size: 14px;
}
@media (max-width: 550px) {
.jumbotron h1 {
font-size: 20px;
font-weight: bold;
letter-spacing: -1px;
line-height: 20px;
}
p.lead {
font-size: 14px;
line-height: 14px;
}
[class^="glyph2x-"],
[class*=" glyph2x-"] {
display: none;
}
}
/* Address books */
table.addressbooks .col-displayname { width: 20%;}
table.addressbooks .col-description { width: 55%;}
table.addressbooks .col-actions { width: 25%;}
/* Calendars */
table.calendars .col-displayname { width: 20%;}
table.calendars .col-description { width: 55%;}
table.calendars .col-actions { width: 25%;}
/* Users */
table.users .col-id { width: 2%;}
table.users .col-username { width: 45%;}

View file

@ -0,0 +1,7 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-adjust"></i>Baïkal settings</h1>
</header>
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,9 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="glyph2x-adjust"></i>Baïkal system settings</h1>
</header>
{{ message }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,36 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="{{ titleicon }}"></i>Address Books</h1>
<p class="lead">Manage Address Books for<i class="{{ modelicon }}"></i><strong>{{ modellabel }}</strong>.</p>
<p class="pull-left"><a href="{{ linkback }}" 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="{{ linknew }}"><i class="icon-white {{ addressbookicon }}"></i> + Add address book</a></p>
</header>
<table class="table table-bordered table-striped addressbooks">
<thead>
<tr>
<th>Display name</th>
<th>Description</th>
<th class="no-border-left"></th>
</tr>
</thead>
<tbody>
{% for addressbook in addressbooks %}
<tr>
<td class="col-displayname"><i class="{{ addressbook.icon }}"></i>{{ addressbook.label|escape }}</td>
<td class="col-description">{{ addressbook.description|escape }}</td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn btn-primary" href="{{ addressbook.linkedit }}"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="{{ addressbook.linkdelete }}"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a id='form'></a>
{{ messages }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,36 @@
{% autoescape false %}
<header class="jumbotron subhead" id="overview">
<h1><i class="{{ titleicon }}"></i>Calendars</h1>
<p class="lead">Manage Calendars for<i class="{{ modelicon }}"></i><strong>{{ modellabel }}</strong>.</p>
<p class="pull-left"><a href="{{ linkback }}" 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="{{ linknew }}"><i class="icon-white {{ calendaricon }}"></i> + Add calendar</a></p>
</header>
<table class="table table-bordered table-striped calendars">
<thead>
<tr>
<th>Display name</th>
<th>Description</th>
<th class="no-border-left"></th>
</tr>
</thead>
<tbody>
{% for calendar in calendars %}
<tr>
<td class="col-displayname"><i class="{{ calendar.icon }}"></i>{{ calendar.label|escape }}</td>
<td class="col-description">{{ calendar.description|escape }}</td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn btn-primary" href="{{ calendar.linkedit }}"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="{{ calendar.linkdelete }}"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a id='form'></a>
{{ messages }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,30 @@
{% autoescape false %}
<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="{{ controller.linkNew() }}"><i class="icon-white {{ usericon }}"></i> + Add user</a></p>
</header>
<table class="table table-bordered table-striped users">
{% for user in users %}
<tr>
<td class="col-username">
<i class="{{ usericon }}"></i> <strong>{{ user.username|escape }}</strong><br />
{{ user.displayname|escape }} <a href="{{ user.mailtouri|escape }}">&lt;{{ user.email|escape }}&gt;</a>
</td>
<td class="col-actions no-border-left">
<p class="pull-right">
<nobr><a class="btn" href="{{ user.linkcalendars }}"><i class="{{ calendaricon }}"></i> Calendars</a></nobr>
<nobr><a class="btn" href="{{ user.linkaddressbooks }}"><i class="icon-book"></i> Address Books</a></nobr>
<nobr><a class="btn btn-primary" href="{{ user.linkedit }}"><i class="icon-edit icon-white"></i> Edit</a></nobr>
<nobr><a class="btn btn-danger" href="{{ user.linkdelete }}"><i class="icon-remove icon-white"></i> Delete</a></nobr>
</p>
</td>
</tr>
{% endfor %}
</table>
<a id='form'></a>
{{ messages }}
{{ form }}
{% endautoescape %}

View file

@ -0,0 +1,8 @@
/*
HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);

View file

@ -0,0 +1,34 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route;
class Dashboard extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Dashboard());
}
}

View file

@ -0,0 +1,34 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route;
class Logout extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Logout());
}
}

View file

@ -0,0 +1,34 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route\Settings;
class Standard extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Settings\Standard());
}
}

View file

@ -0,0 +1,34 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route\Settings;
class System extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Settings\System());
}
}

View file

@ -0,0 +1,56 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route\User;
class AddressBooks extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\User\AddressBooks(
self::getParams()
));
}
public static function parametersMap() {
return array(
"user" => array(
"required" => TRUE,
),
"new" => array(
"required" => FALSE,
),
"edit" => array(
"required" => FALSE,
),
"delete" => array(
"required" => FALSE,
),
"confirm" => array(
"required" => FALSE,
),
);
}
}

View file

@ -0,0 +1,55 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route\User;
class Calendars extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$aParams = self::getParams();
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\User\Calendars($aParams));
}
public static function parametersMap() {
return array(
"user" => array(
"required" => TRUE,
),
"new" => array(
"required" => FALSE,
),
"edit" => array(
"required" => FALSE,
),
"delete" => array(
"required" => FALSE,
),
"confirm" => array(
"required" => FALSE,
),
);
}
}

View file

@ -0,0 +1,52 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Route;
class Users extends \Flake\Core\Route {
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
$aParams = self::getParams();
$oRenderContainer->zone("Payload")->addBlock(new \BaikalAdmin\Controller\Users($aParams));
}
public static function parametersMap() {
return array(
"new" => array(
"required" => FALSE,
),
"edit" => array(
"required" => FALSE,
),
"delete" => array(
"required" => FALSE,
),
"confirm" => array(
"required" => FALSE,
),
);
}
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Dashboard extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Install;
class Database extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Install;
class Initialize extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Login extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation;
class Topbar extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation\Topbar;
class Anonymous extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Navigation\Topbar;
class Install extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Settings;
class Standard extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,31 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\Settings;
class System extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\User;
class AddressBooks extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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\User;
class Calendars extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,30 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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;
class Users extends \BaikalAdmin\Core\View {
}

View file

@ -0,0 +1,37 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://baikal-server.com
#
# 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!
#################################################################
define("BAIKALADMIN_PATH_TEMPLATES", BAIKALADMIN_PATH_ROOT . "Resources/Templates/");
$GLOBALS["ROUTES"] = array(
"default" => "\BaikalAdmin\Route\Dashboard",
"users" => "\BaikalAdmin\Route\Users",
"users/calendars" => "\BaikalAdmin\Route\User\Calendars",
"users/addressbooks" => "\BaikalAdmin\Route\User\AddressBooks",
"settings/standard" => "\BaikalAdmin\Route\Settings\Standard",
"settings/system" => "\BaikalAdmin\Route\Settings\System",
"logout" => "\BaikalAdmin\Route\Logout"
);

View file

@ -0,0 +1,154 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Controller;
class Cli extends \Flake\Core\Render\Container {
function render() {
$this->sys_init();
$this->init();
$this->echoFlush($this->notice("process started @" . strftime("%d/%m/%Y %H:%M:%S")));
$this->execute();
$this->echoFlush($this->notice("process ended @" . strftime("%d/%m/%Y %H:%M:%S")) . "\n\n");
}
function execute() {
reset($this->aSequence);
while(list($sKey,) = each($this->aSequence)) {
$this->aSequence[$sKey]["block"]->execute();
}
}
/**************************************************************************/
var $sLog = "";
function sys_init() {
$this->rawLine("Command line: " . (implode(" ", $_SERVER["argv"])));
$this->initArgs();
}
function init() {
}
function initArgs() {
$sShortOpts = "";
$sShortOpts .= "h"; // help; pas de valeur
$sShortOpts .= "w:"; // author; valeur obligatoire
$aLongOpts = array(
"help", // help; pas de valeur
"helloworld", // author; pas de valeur
);
$this->aArgs = getopt($sShortOpts, $aLongOpts);
}
function getScriptPath() {
return realpath($_SERVER['argv'][0]);
}
function getSyntax() {
return $this->getScriptPath();
}
function syntaxError() {
$sStr = $this->rawLine("Syntax error.\nUsage: " . $this->getSyntax());
die("\n\n" . $sStr . "\n\n");
}
function log($sStr) {
$this->sLog .= $sStr;
}
function header($sMsg) {
$sStr = "\n" . str_repeat("#", 80);
$sStr .= "\n" . "#" . str_repeat(" ", 78) . "#";
$sStr .= "\n" . "#" . str_pad(strtoupper($sMsg), 78, " ", STR_PAD_BOTH) . "#";
$sStr .= "\n" . "#" . str_repeat(" ", 78) . "#";
$sStr .= "\n" . str_repeat("#", 80);
$sStr .= "\n";
$this->log($sStr);
return $sStr;
}
function subHeader($sMsg) {
$sStr = "\n\n# " . str_pad(strtoupper($sMsg) . " ", 78, "-", STR_PAD_RIGHT) . "\n";
$this->log($sStr);
return $sStr;
}
function subHeader2($sMsg) {
$sStr = "\n# # " . str_pad($sMsg . " ", 76, "-", STR_PAD_RIGHT) . "\n";
$this->log($sStr);
return $sStr;
}
function textLine($sMsg) {
$sStr = ". " . $sMsg . "\n";
$this->log($sStr);
return $sStr;
}
function rawLine($sMsg) {
$sStr = $sMsg . "\n";
$this->log($sStr);
return $sStr;
}
function notice($sMsg) {
$sStr = "\n" . str_pad($sMsg, 80, ".", STR_PAD_BOTH) . "\n";
$this->log($sStr);
return $sStr;
}
function getLog() {
return $this->sLog;
}
function file_writeBin($sPath, $sData, $bUTF8 = TRUE) {
$rFile = fopen($sPath, "wb");
if($bUTF8 === TRUE) {
fputs($rFile, "\xEF\xBB\xBF" . $sData);
} else {
fputs($rFile, $sData);
}
fclose($rFile);
}
function echoFlush($sString = "") {
echo $sString;
ob_flush();
flush();
}
}

View file

@ -0,0 +1,42 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Controller;
class HtmlBlock extends \Flake\Core\Controller {
function __construct($sHtml) {
$this->sHtml = $sHtml;
}
function execute() {
}
function render() {
return $this->sHtml;
}
}

View file

@ -0,0 +1,44 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Controller;
class HtmlBlockTemplated extends \Flake\Core\Controller {
function __construct($sTemplatePath, $aMarkers = array()) {
$this->sTemplatePath = $sTemplatePath;
$this->aMarkers = $aMarkers;
}
function render() {
$oTemplate = new \Flake\Core\Template($this->sTemplatePath);
$sHtml = $oTemplate->parse(
$this->aMarkers
);
return $sHtml;
}
}

View file

@ -0,0 +1,126 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Controller;
class Page extends \Flake\Core\Render\Container {
protected $sTitle = "";
protected $sMetaKeywords = "";
protected $sMetaDescription = "";
protected $sTemplatePath = "";
public function __construct($sTemplatePath) {
$this->sTemplatePath = $sTemplatePath;
}
public function setTitle($sTitle) {
$this->sTitle = $sTitle;
}
public function setMetaKeywords($sKeywords) {
$this->sMetaKeywords = $sKeywords;
}
public function setMetaDescription($sDescription) {
$this->sMetaDescription = $sDescription;
}
public function getTitle() {
return $this->sTitle;
}
public function getMetaKeywords() {
$sString = str_replace(array("le", "la", "les", "de", "des", "un", "une"), " ", $this->sMetaKeywords);
$sString = \Flake\Util\Tools::stringToUrlToken($sString);
return implode(", ", explode("-", $sString));
}
public function getMetaDescription() {
return $this->sMetaDescription;
}
public function setBaseUrl($sBaseUrl) {
$this->sBaseUrl = $sBaseUrl;
}
public function getBaseUrl() {
return $this->sBaseUrl;
}
public function injectHTTPHeaders() {
header("Content-Type: text/html; charset=UTF-8");
header("X-Frame-Options: DENY"); # Prevent Clickjacking attacks
header("X-Content-Type-Options: nosniff"); # Prevent code injection via mime type sniffing
}
public function render() {
$this->execute();
$aRenderedBlocks = $this->renderBlocks();
$aRenderedBlocks["pagetitle"] = $this->getTitle();
$aRenderedBlocks["pagemetakeywords"] = $this->getMetaKeywords();
$aRenderedBlocks["pagemetadescription"] = $this->getMetaDescription();
$aRenderedBlocks["baseurl"] = $this->getBaseUrl();
$oTemplate = new \Flake\Core\Template($this->sTemplatePath);
$sHtml = $oTemplate->parse(
$aRenderedBlocks
);
return $sHtml;
}
public function addCss($sCssAbsPath) {
if(\Flake\Util\Frameworks::enabled("LessPHP")) {
$sCompiledPath = PATH_buildcss;
$sFileName = basename($sCssAbsPath);
$sCompiledFilePath = $sCompiledPath . \Flake\Util\Tools::shortMD5($sFileName) . "_" . $sFileName;
if(substr(strtolower($sCompiledFilePath), -4) !== ".css") {
$sCompiledFilePath .= ".css";
}
if(!file_exists($sCompiledPath)) {
@mkdir($sCompiledPath);
if(!file_exists($sCompiledPath)) {
die("Page: Cannot create " . $sCompiledPath);
}
}
\Frameworks\LessPHP\Delegate::compileCss($sCssAbsPath, $sCompiledFilePath);
$sCssUrl = \Flake\Util\Tools::serverToRelativeWebPath($sCompiledFilePath);
} else {
$sCssUrl = \Flake\Util\Tools::serverToRelativeWebPath($sCssAbsPath);
}
$sHtml = "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $sCssUrl . "\" media=\"all\"/>";
$this->zone("head")->addBlock(new \Flake\Controller\HtmlBlock($sHtml));
}
}

View file

@ -0,0 +1,68 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Controller;
class Rpc extends \Flake\Core\Render\Container {
public function initializeContext() {
$this->injectHTTPHeaders();
$GLOBALS["POSTCONNECTIONSERVICES"] = array();
}
public function injectHTTPHeaders() {
ob_start();
header("Access-Control-Allow-Origin: *"); # To allow cross domain AJAX response
header("Access-Control-Allow-Credentials: true"); # To allow cross domain cookies
header("Content-Type: application/json; charset=UTF-8");
# Needed to cut client off when needed
header("Connection: close\r\n");
ignore_user_abort(TRUE);
}
public function P3PAllowCrossDomainCookies() {
# This tells IE6+ to accept passing cookies allong when establishing a XHR connection to read.codr.fr
header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
}
public function sendResponseCutClientAndRunPostConnectionTasks() {
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
reset($GLOBALS["POSTCONNECTIONSERVICES"]);
# If post-connection services are registered, process
foreach($GLOBALS["POSTCONNECTIONSERVICES"] as $service) {
$service->execute();
}
session_write_close();
}
}

View file

@ -0,0 +1,214 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core;
class Collection extends \Flake\Core\FLObject implements \Iterator {
protected $aCollection = array();
protected $aMeta = array();
public function current() {
return current($this->aCollection);
}
public function key() {
return key($this->aCollection);
}
public function next() {
return next($this->aCollection);
}
public function rewind() {
$this->reset();
}
public function valid() {
$key = key($this->aCollection);
return ($key !== NULL && $key !== FALSE);
}
public function &getForKey($sKey) {
$aKeys = $this->keys();
if(!in_array($sKey, $aKeys)) {
throw new \Exception("\Flake\Core\Collection->getForKey(): key '" . $sKey . "' not found in Collection");
}
$oRes = $this->aCollection[$sKey];
return $oRes;
}
public function &each() {
list($key, $val) = each($this->aCollection);
return $val;
}
public function reset() {
reset($this->aCollection);
}
public function prev() {
return prev($this->aCollection);
}
public function count() {
return count($this->aCollection);
}
public function keys() {
return array_keys($this->aCollection);
}
public function isEmpty() {
return $this->count() === 0;
}
public function isAtFirst() {
return $this->key() === array_shift($this->keys());
}
public function isAtLast() {
return $this->key() === array_pop($this->keys());
}
public function push(&$mMixed) {
array_push($this->aCollection, $mMixed);
}
public function flush() {
unset($this->aCollection);
$this->aCollection = array();
}
public function &first() {
if(!$this->isEmpty()) {
$aKeys = $this->keys();
return $this->aCollection[array_shift($aKeys)];
}
$var = null; # two lines instead of one
return $var; # as PHP needs a variable to return by ref
}
public function &last() {
if(!$this->isEmpty()) {
$aKeys = $this->keys();
return $this->aCollection[array_pop($aKeys)];
}
$var = null;
return $var;
}
public function toArray() {
return $this->aCollection;
}
public static function fromArray($aData) {
$oColl = new \Flake\Core\Collection();
reset($aData);
foreach($aData as $mData) {
$oColl->push($mData);
}
return $oColl;
}
# Create a new collection like this one
# This abstraction is useful because of CollectionTyped
protected function newCollectionLikeThisOne() {
$oCollection = new \Flake\Core\Collection(); # two lines instead of one
return $oCollection; # as PHP needs a variable to return by ref
}
public function map($sFunc) {
$aData = $this->toArray();
$oNewColl = $this->fromArray(array_map($sFunc, $aData));
return $oNewColl;
}
public function walk($sFunc, $aParams=array()) {
$aData = $this->toArray();
$oNewColl = $this->fromArray(array_walk($aData, $sFunc, $aParams));
return $oNewColl;
}
public function remove($sKey) {
$aKeys = $this->keys();
if(!in_array($sKey, $aKeys)) {
throw new \Exception("\Flake\Core\Collection->remove(): key '" . $sKey . "' not found in Collection");
}
unset($this->aCollection[$sKey]);
$this->aCollection = array_values($this->aCollection);
}
public function &__call($sName, $aArguments) {
if(
strlen($sName) > 7 &&
$sName{0} === "s" &&
$sName{1} === "e" &&
$sName{2} === "t" &&
$sName{3} === "M" &&
$sName{4} === "e" &&
$sName{5} === "t" &&
$sName{6} === "a"
) {
$sKey = strtolower(substr($sName, 7, 1)) . substr($sName, 8);
$mValue =& $aArguments[0];
if(is_null($mValue)) {
if(array_key_exists($sKey, $this->aMeta)) {
unset($this->aMeta[$sKey]);
}
} else {
$this->aMeta[$sKey] =& $mValue;
}
$res = NULL;
return $res; # To avoid 'Notice: Only variable references should be returned by reference'
} elseif(
strlen($sName) > 7 &&
$sName{0} === "g" &&
$sName{1} === "e" &&
$sName{2} === "t" &&
$sName{3} === "M" &&
$sName{4} === "e" &&
$sName{5} === "t" &&
$sName{6} === "a"
) {
$sKey = strtolower(substr($sName, 7, 1)) . substr($sName, 8);
if(array_key_exists($sKey, $this->aMeta)) {
return $this->aMeta[$sKey];
} else {
return null;
}
} else {
throw new \Exception("Method " . $sName . "() not found on " . get_class($this));
}
}
}

View file

@ -0,0 +1,51 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core;
class CollectionTyped extends \Flake\Core\Collection {
protected $sTypeClassOrProtocol;
public function __construct($sTypeClassOrProtocol) {
$this->sTypeClassOrProtocol = $sTypeClassOrProtocol;
$this->setMetaType($this->sTypeClassOrProtocol);
}
public function push(&$mMixed) {
if(!\Flake\Util\Tools::is_a($mMixed, $this->sTypeClassOrProtocol)) {
throw new \Exception("\Flake\Core\CollectionTyped<" . $this->sTypeClassOrProtocol . ">: Given object is not correctly typed.");
}
parent::push($mMixed);
}
# Create a new collection like this one
public function newCollectionLikeThisOne() {
$oCollection = new \Flake\Core\CollectionTyped($this->sTypeClassOrProtocol);
return $oCollection;
}
}

View file

@ -0,0 +1,56 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core;
abstract class Controller extends \Flake\Core\FLObject {
protected $aParams = array();
public function __construct($aParams = array()) {
$this->aParams = $aParams;
}
public function getParams() {
return $this->aParams;
}
public static function link(/*[$sParam, $sParam2, ...]*/) {
return static::buildRoute();
}
public static function buildRoute($aParams = array()) {
# TODO: il faut remplacer le mécanisme basé sur un nombre variable de paramètres en un mécanisme basé sur un seul paramètre "tableau"
#$aParams = func_get_args();
$sController = "\\" . get_called_class();
#array_unshift($aParams, $sController); # Injecting current controller as first param
#return call_user_func_array($GLOBALS["ROUTER"] . "::buildRouteForController", $aParams);
return $GLOBALS["ROUTER"]::buildRouteForController($sController, $aParams);
}
public abstract function execute();
public abstract function render();
}

View file

@ -0,0 +1,130 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://bootstrap.codr.fr
#
# This script is part of the CodrBootstrap project. The CodrBootstrap 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 Flake\Core\DOM;
class HTMLElement extends \DOMElement {
public function getInnerText() {
return $this->nodeValue;
}
public function getOuterHTML() {
return $this->ownerDocument->saveHTML($this);
}
public function getNormalizedInnerText() {
return $this->normalizeWhiteSpace($this->getInnerText());
}
public function getNormalizedOuterHTML() {
return $this->normalizeWhitespace($this->getOuterHTML());
}
protected function normalizeWhitespace($sText) {
$sText = str_replace(array("\t", "\r\n", "\n"), ' ', $sText);
# using multiple str_replace has proven to be twice as fast that regexp on big strings
$iCount = 0;
do {
$sText = str_replace(' ', ' ', $sText, $iCount);
} while($iCount > 0);
return trim($sText);
}
public function setInnerHTML($sHtml) {
// first, empty the element
for ($x=$this->childNodes->length-1; $x>=0; $x--) {
$this->removeChild($this->childNodes->item($x));
}
// $value holds our new inner HTML
if ($sHtml != '') {
$f = $this->ownerDocument->createDocumentFragment();
// appendXML() expects well-formed markup (XHTML)
$result = @$f->appendXML($sHtml); // @ to suppress PHP warnings
if ($result) {
if ($f->hasChildNodes()) $this->appendChild($f);
} else {
// $value is probably ill-formed
$f = new \DOMDocument();
$sHtml = mb_convert_encoding($sHtml, 'HTML-ENTITIES', 'UTF-8');
// Using <htmlfragment> will generate a warning, but so will bad HTML
// (and by this point, bad HTML is what we've got).
// We use it (and suppress the warning) because an HTML fragment will
// be wrapped around <html><body> tags which we don't really want to keep.
// Note: despite the warning, if loadHTML succeeds it will return true.
$result = @$f->loadHTML('<htmlfragment>'.$sHtml.'</htmlfragment>');
if ($result) {
$import = $f->getElementsByTagName('htmlfragment')->item(0);
foreach ($import->childNodes as $child) {
$importedNode = $this->ownerDocument->importNode($child, true);
$this->appendChild($importedNode);
}
} else {
// oh well, we tried, we really did. :(
// this element is now empty
}
}
}
}
public function getInnerHTML() {
$sHtml = '';
$iNodes = $this->childNodes->length;
for($i = 0; $i < $iNodes; $i++) {
$oItem = $this->childNodes->item($i);
$sHtml .= $oItem->ownerDocument->saveHTML($oItem);
}
return $sHtml;
}
public function isDOMText() {
return $this->nodeType === XML_TEXT_NODE;
}
public function getSiblingPosition() {
$iPos = 0;
$oNode = $this;
while(!is_null($oNode->previousSibling)) {
$oNode = $oNode->previousSibling;
$iPos++;
}
return $iPos;
}
public function getTreePosition() {
# Tree position is number 100^level + sibling offset
$iLevel = substr_count($this->getNodePath(), "/") - 2; # -1 to align on 0, and -1 to compensate for /document
if($iLevel === 0) {
return $this->getSiblingPosition();
} else {
return pow(10, $iLevel) + $this->getSiblingPosition();
}
}
}

View file

@ -0,0 +1,208 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core;
abstract class Database extends \Flake\Core\FLObject {
/* common stuff */
protected function messageAndDie($sMessage) {
$sError = "<h2>" . get_class($this) . ": " . $sMessage . "</h2>";
die($sError);
}
public function exec_INSERTquery($table,$fields_values,$no_quote_fields=FALSE) {
return $this->query($this->INSERTquery($table,$fields_values,$no_quote_fields));
}
public function INSERTquery($table,$fields_values,$no_quote_fields=FALSE) {
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
if (is_array($fields_values) && count($fields_values)) {
// quote and escape values
$fields_values = $this->fullQuoteArray($fields_values,$table,$no_quote_fields);
// Build query:
$query = 'INSERT INTO '.$table.'
(
'.implode(',
',array_keys($fields_values)).'
) VALUES (
'.implode(',
',$fields_values).'
)';
// Return query:
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
return $query;
}
}
public function exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields=FALSE) {
return $this->query($this->UPDATEquery($table,$where,$fields_values,$no_quote_fields));
}
public function UPDATEquery($table,$where,$fields_values,$no_quote_fields=FALSE) {
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
if (is_string($where)) {
if (is_array($fields_values) && count($fields_values)) {
// quote and escape values
$nArr = $this->fullQuoteArray($fields_values,$table,$no_quote_fields);
$fields = array();
foreach ($nArr as $k => $v) {
$fields[] = $k.'='.$v;
}
// Build query:
$query = 'UPDATE '.$table.'
SET
'.implode(',
',$fields).
(strlen($where)>0 ? '
WHERE
'.$where : '');
// Return query:
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
return $query;
}
} else {
die('<strong>Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !');
}
}
public function exec_DELETEquery($table,$where) {
return $this->query($this->DELETEquery($table,$where));
}
public function DELETEquery($table,$where) {
if (is_string($where)) {
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function
$query = 'DELETE FROM '.$table.
(strlen($where)>0 ? '
WHERE
'.$where : '');
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
return $query;
} else {
die('<strong>Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !');
}
}
public function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') {
return $this->query($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit));
}
public function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') {
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function
// Build basic query:
$query = 'SELECT '.$select_fields.'
FROM '.$from_table.
(strlen($where_clause)>0 ? '
WHERE
'.$where_clause : '');
// Group by:
if (strlen($groupBy)>0) {
$query.= '
GROUP BY '.$groupBy;
}
// Order by:
if (strlen($orderBy)>0) {
$query.= '
ORDER BY '.$orderBy;
}
// Group by:
if (strlen($limit)>0) {
$query.= '
LIMIT '.$limit;
}
// Return query:
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
return $query;
}
public function fullQuote($str, $table) {
return '\''.$this->quote($str, $table).'\'';
}
public function fullQuoteArray($arr, $table, $noQuote=FALSE) {
if (is_string($noQuote)) {
$noQuote = explode(',',$noQuote);
} elseif (!is_array($noQuote)) { // sanity check
$noQuote = FALSE;
}
foreach($arr as $k => $v) {
if ($noQuote===FALSE || !in_array($k,$noQuote)) {
$arr[$k] = $this->fullQuote($v, $table);
}
}
return $arr;
}
/* Should be abstract, but we provide a body anyway as PDO abstracts these methods for us */
public function query($sSql) {
if(($stmt = $this->oDb->query($sSql)) === FALSE) {
$sMessage = print_r($this->oDb->errorInfo(), TRUE);
throw new \Exception("SQL ERROR in: '" . $sSql . "'; Message: " . $sMessage);
}
return new \Flake\Core\Database\Statement($stmt);
}
public function lastInsertId() {
return $this->oDb->lastInsertId();
}
public function quote($str) {
return substr($this->oDb->quote($str), 1, -1); # stripping first and last quote
}
public function getPDO() {
return $this->oDb;
}
public function close() {
$this->oDb = null;
}
public function __destruct() {
$this->close();
}
public abstract function tables();
}

View file

@ -0,0 +1,67 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Database;
class Mysql extends \Flake\Core\Database {
protected $oDb = FALSE; // current DB link
protected $debugOutput = FALSE;
protected $store_lastBuiltQuery = TRUE;
protected $debug_lastBuiltQuery = "";
protected $sHost = "";
protected $sDbName = "";
protected $sUsername = "";
protected $sPassword = "";
public function __construct($sHost, $sDbName, $sUsername, $sPassword) {
$this->sHost = $sHost;
$this->sDbName = $sDbName;
$this->sUsername = $sUsername;
$this->sPassword = $sPassword;
$this->oDb = new \PDO(
'mysql:host=' . $this->sHost . ';dbname=' . $this->sDbName,
$this->sUsername,
$this->sPassword
);
}
public function tables() {
$aTables = array();
$sSql = "SHOW TABLES FROM " . $this->sDbName;
$oStmt = $this->query($sSql);
while(($aRs = $oStmt->fetch()) !== FALSE) {
$aTables[] = array_shift($aRs);
}
asort($aTables);
reset($aTables);
return $aTables;
}
}

View file

@ -0,0 +1,60 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Database;
class Sqlite extends \Flake\Core\Database {
protected $oDb = FALSE; // current DB link
protected $debugOutput = FALSE;
protected $store_lastBuiltQuery = TRUE;
protected $debug_lastBuiltQuery = "";
protected $sDbPath = "";
public function __construct($sDbPath) {
$this->sDbPath = $sDbPath;
$this->oDb = new \PDO('sqlite:' . $this->sDbPath);
}
# Taken from http://dev.kohanaframework.org/issues/2985
public function tables() {
$aTables = array();
# Find all user level table names
$oStmt = $this->query('SELECT name '
.'FROM sqlite_master '
.'WHERE type=\'table\' AND name NOT LIKE \'sqlite_%\' '
.'ORDER BY name');
while(($aRs = $oStmt->fetch()) !== FALSE) {
// Get the table name from the results
$aTables[] = array_shift($aRs);
}
reset($aTables);
return $aTables;
}
}

View file

@ -0,0 +1,43 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Database;
class Statement extends \Flake\Core\FLObject {
protected $stmt = null;
public function __construct($stmt) {
$this->stmt = $stmt;
}
public function fetch() {
if($this->stmt !== FALSE) {
return $this->stmt->fetch(\PDO::FETCH_ASSOC, \PDO::FETCH_ORI_FIRST);
}
return FALSE;
}
}

View file

@ -0,0 +1,62 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Datastructure;
class Chain extends \SplDoublyLinkedList {
public function push(\Flake\Core\Datastructure\Chainable $value) {
$value->chain($this, $this->count());
parent::push($value);
}
public function offsetUnset($offset) {
throw new \Exception("Cannot delete Chainable in Chain");
}
public function &first() {
$oRes = $this->bottom();
return $oRes;
}
public function &last() {
$oRes = $this->top();
return $oRes;
}
public function reset() {
reset($this);
}
public function __toString() {
ob_start();
var_dump($this);
$sDump = ob_get_contents();
ob_end_clean();
return "<pre>" . htmlspecialchars($sDump) . "</pre>";
}
}

View file

@ -0,0 +1,110 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Datastructure;
abstract class ChainLink implements \Flake\Core\Datastructure\Chainable {
protected $__container = null;
protected $__key = null;
public function chain(Chain $container, $key) {
$this->__container = $container;
$this->__key = $key;
}
public function offsetSet($offset,$value) {
if(is_null($this->__container)) {
return;
}
$this->__container->offsetSet($offset, $value);
}
public function offsetExists($offset) {
if(is_null($this->__container)) {
return FALSE;
}
return $this->__container->offsetExists($offset);
}
public function offsetUnset($offset) {
if(is_null($this->__container)) {
return;
}
$this->__container->offsetUnset($offset);
}
public function &offsetGet($offset) {
if(is_null($this->__container)) {
return null;
}
$oRes = $this->__container->offsetGet($offset);
return $oRes;
}
public function rewind() {
$this->__container->rewind();
}
public function current() {
return $this->__container->current();
}
public function key() {
return $this->__container->key();
}
public function &next() {
$oRes = $this->__container->next();
return $oRes;
}
public function &prev() {
$oPrev = $this->__container->prev();
return $oPrev;
}
public function valid() {
return $this->__container->valid();
}
public function count() {
return $this->__container->count();
}
public function &first() {
$oRes = $this->__container->first();
return $oRes;
}
public function &last() {
$oRes = $this->__container->last();
return $oRes;
}
}

View file

@ -0,0 +1,38 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core\Datastructure;
interface Chainable extends \ArrayAccess, \Iterator, \Countable {
# public function &next(); # This is already specified by interface Iterator
public function &prev();
public function &first();
public function &last();
public function chain(\Flake\Core\Datastructure\Chain $chain, $key);
}

View file

@ -0,0 +1,42 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# 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 Flake\Core;
class FLObject {
public function __toString() {
ob_start();
var_dump($this);
$sDump = ob_get_contents();
ob_end_clean();
return "<pre>" . htmlspecialchars($sDump) . "</pre>";
}
public function isA($sClassOrProtocolName) {
return \Flake\Util\Tools::is_a($this, $sClassOrProtocolName);
}
}

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