/tags/0.9.2/process.php |
---|
Новый файл |
0,0 → 1,454 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
require_once dirname(__FILE__)."/init.php"; |
$mode = $_POST["mode"]; |
switch ($mode) { |
case 'authorize': |
$r = $core->checkSign($_POST["word"]); |
header("Location: ".$r["Location"]."\n\n"); |
break; |
case 'distributive-add': |
// Добавление нового дистрибутива |
$DName = $secure->checkStr($_POST["dname"],1); |
$DUA = $secure->checkStr($_POST["dua"],1); |
$DType = $secure->checkInt($_POST["dtype"]); |
$DLogo = 0; |
if ($_FILES["distlogo"]["type"]!="") { |
$DLogo = $core->uploadPicture($picture, $DUA, $_FILES); |
} |
$r = $core->addDistribution($DName, $DType, $DUA, $DLogo); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'distributive-edit': |
// Редактирование информации о дистрибутиве |
$ID = $secure->checkInt($_POST["distID"]); |
$DName = $secure->checkStr($_POST["dname"],1); |
$DUA = $secure->checkStr($_POST["dua"],1); |
$DType = $secure->checkInt($_POST["dtype"]); |
if ($_FILES["distlogo"]["type"]!="") { |
$DLogo = $core->uploadPicture($picture, $DUA, $_FILES); |
$r = $core->updateDistribution($ID, $DName, $DType, $DUA, $DLogo); |
} |
$r = $core->updateDistribution($ID, $DName, $DType, $DUA); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'distributive-delete': |
// Удаление информации о дистрибутиве |
$ID = $secure->checkInt($_POST["distID"]); |
$r = $core->dropDistribution($ID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'version-add': |
// Добавление новой версии дистрибутива |
$DistID = $secure->checkInt($_POST["distname"]); |
$VName = $secure->checkStr($_POST["vname"],1); |
$VNmbr = $secure->checkStr($_POST["version"],1); |
$VCNme = $secure->checkStr($_POST["vcodename"],1); |
$r = $core->addDistVersion($DistID, $VNmbr, $VName, $VCNme); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'version-edit': |
// Редактирование версии дистрибутива |
$versID = $secure->checkInt($_POST["versionID"]); |
$VName = $secure->checkStr($_POST["vname"],1); |
$VNmbr = $secure->checkStr($_POST["version"],1); |
$VCNme = $secure->checkStr($_POST["vcodename"],1); |
$r = $core->updateDistVersion($versID, $VNmbr, $VName, $VCNme); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'version-delete': |
// Удаление версии дистрибутива |
$versID = $secure->checkInt($_POST["versionID"]); |
$r = $core->dropDistVersion($versID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'section-add': |
// Добавление новой секции |
$SName = $secure->checkStr($_POST["sname"],1); |
$SInfo = $secure->checkStr($_POST["sinfo"],1); |
$r = $core->addSection($SName, $SInfo); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'section-edit': |
// Редактирование информации о секции |
$sectID = $secure->checkInt($_POST["sectionID"]); |
$SName = $secure->checkStr($_POST["sname"],1); |
$SInfo = $secure->checkStr($_POST["sinfo"],1); |
$r = $core->updateSection($sectID, $SName, $SInfo); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'section-delete': |
// Удаление информации о секции |
$sectID = $secure->checkInt($_POST["sectionID"]); |
$r = $core->dropSection($sectID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'sign-add': |
// Добавление новой подписи |
$SName = $secure->checkStr($_POST["sname"],1); |
$SInfo = $secure->checkStr($_POST["sinfo"],1); |
$r = $core->addSign($SName, $SInfo); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'sign-edit': |
// Редактирование информации о подписи |
$signID = $secure->checkInt($_POST["signID"]); |
$SName = $secure->checkStr($_POST["sname"],1); |
$SInfo = $secure->checkStr($_POST["sinfo"],1); |
$r = $core->updateSign($signID, $SName, $SInfo); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'sign-delete': |
// Удаление информации о подписи |
$signID = $secure->checkInt($_POST["signID"]); |
$r = $core->dropSign($signID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'arch-add': |
// Добавление новой архитектуры |
$arch = $secure->checkStr($_POST["arch"],1); |
$r = $core->addArch($arch); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'arch-edit': |
// Редактирование архитектуры |
$archID = $secure->checkInt($_POST["archID"]); |
$arch = $secure->checkStr($_POST["arch"],1); |
$r = $core->updateArch($archID, $arch); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'arch-delete': |
// Удаление архитектуры |
$archID = $secure->checkInt($_POST["archID"]); |
$r = $core->dropArch($archID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'scheme-add': |
// Добавление новой схемы репозитория |
$scheme = $secure->checkStr($_POST["scheme"],1); |
$r = $core->addScheme($scheme); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'scheme-edit': |
// Редактирование схемы репозитория |
$schemeID = $secure->checkInt($_POST["schemeID"]); |
$scheme = $secure->checkStr($_POST["scheme"],1); |
$r = $core->updateScheme($schemeID, $scheme); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'scheme-delete': |
// Удаление схемы репозитория |
$schemeID = $secure->checkInt($_POST["schemeID"]); |
$r = $core->dropScheme($schemeID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'proto-add': |
// Добавление протокола доступа |
$proto = $secure->checkStr($_POST["proto"],1); |
$r = $core->addProto($proto); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'proto-edit': |
// Редактирование протокола доступа |
$protoID = $secure->checkInt($_POST["protoID"]); |
$proto = $secure->checkStr($_POST["proto"],1); |
$r = $core->updateProto($protoID, $proto); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'proto-delete': |
// Удаление протокола доступа |
$protoID = $secure->checkInt($_POST["protoID"]); |
$r = $core->dropProto($protoID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'host-add': |
// Добавление хоста репозитория |
$host = $secure->checkStr($_POST["rhost"],1); |
$r = $core->addHost($host); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'host-edit': |
// Редактирование хоста репозитория |
$hostID = $secure->checkInt($_POST["hostID"]); |
$host = $secure->checkStr($_POST["rhost"],1); |
$r = $core->updateHost($hostID, $host); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'host-delete': |
// Удаление хоста репозитория |
$hostID = $secure->checkInt($_POST["hostID"]); |
$r = $core->dropHost($hostID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'folder-add': |
// Добавление корневой папки репозитория |
$folder = $secure->checkStr($_POST["rfolder"],1); |
$r = $core->addFolder($folder); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'folder-edit': |
// Редактирование корневой папки репозитория |
$folderID = $secure->checkInt($_POST["folderID"]); |
$folder = $secure->checkStr($_POST["rfolder"],1); |
$r = $core->updateFolder($folderID, $folder); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'folder-delete': |
// Удаление корневой папки репозитория |
$folderID = $secure->checkInt($_POST["folderID"]); |
$r = $core->dropFolder($folderID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'repository-master': |
// Добавляем новый репозиторий |
$rdist = $_POST["rdist"]; // Версия дистрибутива |
$rname = $_POST["rname"]; // Название репозитория |
$rinfo = $_POST["rinfo"]; // Описание репозитория |
$rkey = $_POST["rkey"]; // Ключ подписи репозитория |
$rproto = $_POST["rproto"]; // Протокол доступа |
$rhost = $_POST["rhost"]; // Хост репозитория |
$rfolder = $_POST["rfolder"]; // Корневая папка |
$rtype = $_POST["rtype"]; // Тип репозитория |
$rscheme = $_POST["rscheme"]; // Схема репозитория |
$rsign = $_POST["rsign"]; // Подпись репозитория (для rpm/ALTLinux) |
$r = $core->addRepository($rdist, $rname, $rinfo, $rkey, $rproto, $rhost, $rfolder, $rtype, $rscheme, $rsign, $_POST["rsects"], $_POST["rarchs"]); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'repository-edit': |
// Редактируем репозиторий |
$rID = $_POST["repositoryID"]; |
$rdist = $_POST["rdist"]; |
$rname = $_POST["rname"]; |
$rinfo = $_POST["rinfo"]; |
$rkey = $_POST["rkey"]; |
$rproto = $_POST["rproto"]; |
$rhost = $_POST["rhost"]; |
$rfolder = $_POST["rfolder"]; |
$rtype = $_POST["rtype"]; |
$rscheme = $_POST["rscheme"]; |
$rsign = $_POST["rsign"]; |
$r = $core->updateRepository($rID, $rdist, $rname, $rinfo, $rkey, $rproto, $rhost, $rfolder, $rtype, $rscheme, $rsign, $_POST["rsects"], $_POST["rarchs"]); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'repository-delete': |
// Удаляем репозиторий |
$rID = $secure->checkInt($_POST["repositoryID"]); // Версия дистрибутива |
$r = $core->dropRepository($rID); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
break; |
case 'update-password': |
// Обновление пароля |
$oword = $_POST["oword"]; |
$nword = $_POST["nword"]; |
$again = $_POST["again"]; |
$sHash = $secure->encryptStr($oword); |
$pwd = $core->getOption("passwd"); |
if ($sHash == $pwd["OptValue"]) { |
$r = $core->updatePassword($nword, $again); |
if ($r["ERR"]==0) { |
header("Location: ".$manager."\n\n"); |
} else { |
echo $r["ERRINFO"]; |
} |
} |
break; |
} |
?> |
/tags/0.9.2/TODO |
---|
Новый файл |
0,0 → 1,2 |
* Сделать нормальный интерфейс администратора |
* Сделать нормальную поддержку apt-rpm |
/tags/0.9.2/get.php |
---|
Новый файл |
0,0 → 1,34 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
require_once dirname(__FILE__)."/init.php"; |
$reqID = $_GET["uuid"]; |
$distID = $secure->checkInt($_POST["d"]); |
$versID = $secure->checkInt($_POST["v"]); |
$request = array(); |
$request["dist_id"] = $distID; |
$request["version_id"] = $versID; |
for ($i=0;$i<count($_POST["section"]);$i++) { |
$request["section"][$i] = $_POST["section"][$i]; |
} |
for ($i=0;$i<count($_POST["repository"]);$i++) { |
$request["repository"][$i] = $_POST["repository"][$i]; |
} |
header("content-type: text/plain\n\n"); |
$r = $core->showSourcesList($request); |
echo $r; |
?> |
/tags/0.9.2/lib/DB.php |
---|
Новый файл |
0,0 → 1,1489 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Database independent query interface |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: DB.php,v 1.88 2007/08/12 05:27:25 aharvey Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once dirname(__FILE__).'/PEAR.php'; |
// {{{ constants |
// {{{ error codes |
/**#@+ |
* One of PEAR DB's portable error codes. |
* @see DB_common::errorCode(), DB::errorMessage() |
* |
* {@internal If you add an error code here, make sure you also add a textual |
* version of it in DB::errorMessage().}} |
*/ |
/** |
* The code returned by many methods upon success |
*/ |
define('DB_OK', 1); |
/** |
* Unkown error |
*/ |
define('DB_ERROR', -1); |
/** |
* Syntax error |
*/ |
define('DB_ERROR_SYNTAX', -2); |
/** |
* Tried to insert a duplicate value into a primary or unique index |
*/ |
define('DB_ERROR_CONSTRAINT', -3); |
/** |
* An identifier in the query refers to a non-existant object |
*/ |
define('DB_ERROR_NOT_FOUND', -4); |
/** |
* Tried to create a duplicate object |
*/ |
define('DB_ERROR_ALREADY_EXISTS', -5); |
/** |
* The current driver does not support the action you attempted |
*/ |
define('DB_ERROR_UNSUPPORTED', -6); |
/** |
* The number of parameters does not match the number of placeholders |
*/ |
define('DB_ERROR_MISMATCH', -7); |
/** |
* A literal submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID', -8); |
/** |
* The current DBMS does not support the action you attempted |
*/ |
define('DB_ERROR_NOT_CAPABLE', -9); |
/** |
* A literal submitted was too long so the end of it was removed |
*/ |
define('DB_ERROR_TRUNCATED', -10); |
/** |
* A literal number submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_NUMBER', -11); |
/** |
* A literal date submitted did not match the data type expected |
*/ |
define('DB_ERROR_INVALID_DATE', -12); |
/** |
* Attempt to divide something by zero |
*/ |
define('DB_ERROR_DIVZERO', -13); |
/** |
* A database needs to be selected |
*/ |
define('DB_ERROR_NODBSELECTED', -14); |
/** |
* Could not create the object requested |
*/ |
define('DB_ERROR_CANNOT_CREATE', -15); |
/** |
* Could not drop the database requested because it does not exist |
*/ |
define('DB_ERROR_CANNOT_DROP', -17); |
/** |
* An identifier in the query refers to a non-existant table |
*/ |
define('DB_ERROR_NOSUCHTABLE', -18); |
/** |
* An identifier in the query refers to a non-existant column |
*/ |
define('DB_ERROR_NOSUCHFIELD', -19); |
/** |
* The data submitted to the method was inappropriate |
*/ |
define('DB_ERROR_NEED_MORE_DATA', -20); |
/** |
* The attempt to lock the table failed |
*/ |
define('DB_ERROR_NOT_LOCKED', -21); |
/** |
* The number of columns doesn't match the number of values |
*/ |
define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); |
/** |
* The DSN submitted has problems |
*/ |
define('DB_ERROR_INVALID_DSN', -23); |
/** |
* Could not connect to the database |
*/ |
define('DB_ERROR_CONNECT_FAILED', -24); |
/** |
* The PHP extension needed for this DBMS could not be found |
*/ |
define('DB_ERROR_EXTENSION_NOT_FOUND',-25); |
/** |
* The present user has inadequate permissions to perform the task requestd |
*/ |
define('DB_ERROR_ACCESS_VIOLATION', -26); |
/** |
* The database requested does not exist |
*/ |
define('DB_ERROR_NOSUCHDB', -27); |
/** |
* Tried to insert a null value into a column that doesn't allow nulls |
*/ |
define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); |
/**#@-*/ |
// }}} |
// {{{ prepared statement-related |
/**#@+ |
* Identifiers for the placeholders used in prepared statements. |
* @see DB_common::prepare() |
*/ |
/** |
* Indicates a scalar (<kbd>?</kbd>) placeholder was used |
* |
* Quote and escape the value as necessary. |
*/ |
define('DB_PARAM_SCALAR', 1); |
/** |
* Indicates an opaque (<kbd>&</kbd>) placeholder was used |
* |
* The value presented is a file name. Extract the contents of that file |
* and place them in this column. |
*/ |
define('DB_PARAM_OPAQUE', 2); |
/** |
* Indicates a misc (<kbd>!</kbd>) placeholder was used |
* |
* The value should not be quoted or escaped. |
*/ |
define('DB_PARAM_MISC', 3); |
/**#@-*/ |
// }}} |
// {{{ binary data-related |
/**#@+ |
* The different ways of returning binary data from queries. |
*/ |
/** |
* Sends the fetched data straight through to output |
*/ |
define('DB_BINMODE_PASSTHRU', 1); |
/** |
* Lets you return data as usual |
*/ |
define('DB_BINMODE_RETURN', 2); |
/** |
* Converts the data to hex format before returning it |
* |
* For example the string "123" would become "313233". |
*/ |
define('DB_BINMODE_CONVERT', 3); |
/**#@-*/ |
// }}} |
// {{{ fetch modes |
/**#@+ |
* Fetch Modes. |
* @see DB_common::setFetchMode() |
*/ |
/** |
* Indicates the current default fetch mode should be used |
* @see DB_common::$fetchmode |
*/ |
define('DB_FETCHMODE_DEFAULT', 0); |
/** |
* Column data indexed by numbers, ordered from 0 and up |
*/ |
define('DB_FETCHMODE_ORDERED', 1); |
/** |
* Column data indexed by column names |
*/ |
define('DB_FETCHMODE_ASSOC', 2); |
/** |
* Column data as object properties |
*/ |
define('DB_FETCHMODE_OBJECT', 3); |
/** |
* For multi-dimensional results, make the column name the first level |
* of the array and put the row number in the second level of the array |
* |
* This is flipped from the normal behavior, which puts the row numbers |
* in the first level of the array and the column names in the second level. |
*/ |
define('DB_FETCHMODE_FLIPPED', 4); |
/**#@-*/ |
/**#@+ |
* Old fetch modes. Left here for compatibility. |
*/ |
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); |
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); |
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); |
/**#@-*/ |
// }}} |
// {{{ tableInfo() && autoPrepare()-related |
/**#@+ |
* The type of information to return from the tableInfo() method. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::tableInfo() |
* |
* {@internal Since the TABLEINFO constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}} |
*/ |
define('DB_TABLEINFO_ORDER', 1); |
define('DB_TABLEINFO_ORDERTABLE', 2); |
define('DB_TABLEINFO_FULL', 3); |
/**#@-*/ |
/**#@+ |
* The type of query to create with the automatic query building methods. |
* @see DB_common::autoPrepare(), DB_common::autoExecute() |
*/ |
define('DB_AUTOQUERY_INSERT', 1); |
define('DB_AUTOQUERY_UPDATE', 2); |
/**#@-*/ |
// }}} |
// {{{ portability modes |
/**#@+ |
* Portability Modes. |
* |
* Bitwised constants, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. |
* |
* @see DB_common::setOption() |
* |
* {@internal Since the PORTABILITY constants are bitwised, if more of them are |
* added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}} |
*/ |
/** |
* Turn off all portability features |
*/ |
define('DB_PORTABILITY_NONE', 0); |
/** |
* Convert names of tables and fields to lower case |
* when using the get*(), fetch*() and tableInfo() methods |
*/ |
define('DB_PORTABILITY_LOWERCASE', 1); |
/** |
* Right trim the data output by get*() and fetch*() |
*/ |
define('DB_PORTABILITY_RTRIM', 2); |
/** |
* Force reporting the number of rows deleted |
*/ |
define('DB_PORTABILITY_DELETE_COUNT', 4); |
/** |
* Enable hack that makes numRows() work in Oracle |
*/ |
define('DB_PORTABILITY_NUMROWS', 8); |
/** |
* Makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
*/ |
define('DB_PORTABILITY_ERRORS', 16); |
/** |
* Convert null values to empty strings in data output by |
* get*() and fetch*() |
*/ |
define('DB_PORTABILITY_NULL_TO_EMPTY', 32); |
/** |
* Turn on all portability features |
*/ |
define('DB_PORTABILITY_ALL', 63); |
/**#@-*/ |
// }}} |
// }}} |
// {{{ class DB |
/** |
* Database independent query interface |
* |
* The main "DB" class is simply a container class with some static |
* methods for creating DB objects as well as some utility functions |
* common to all parts of DB. |
* |
* The object model of DB is as follows (indentation means inheritance): |
* <pre> |
* DB The main DB class. This is simply a utility class |
* with some "static" methods for creating DB objects as |
* well as common utility functions for other DB classes. |
* |
* DB_common The base for each DB implementation. Provides default |
* | implementations (in OO lingo virtual methods) for |
* | the actual DB implementations as well as a bunch of |
* | query utility functions. |
* | |
* +-DB_mysql The DB implementation for MySQL. Inherits DB_common. |
* When calling DB::factory or DB::connect for MySQL |
* connections, the object returned is an instance of this |
* class. |
* </pre> |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB |
{ |
// {{{ &factory() |
/** |
* Create a new DB object for the specified database type but don't |
* connect to the database |
* |
* @param string $type the database type (eg "mysql") |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function &factory($type, $options = false) |
{ |
if (!is_array($options)) { |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/{$type}.php"; |
} else { |
@include_once "DB/{$type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj = new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
return $obj; |
} |
// }}} |
// {{{ &connect() |
/** |
* Create a new DB object including a connection to the specified database |
* |
* Example 1. |
* <code> |
* require_once 'DB.php'; |
* |
* $dsn = 'pgsql://user:password@host/database'; |
* $options = array( |
* 'debug' => 2, |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $db =& DB::connect($dsn, $options); |
* if (PEAR::isError($db)) { |
* die($db->getMessage()); |
* } |
* </code> |
* |
* @param mixed $dsn the string "data source name" or array in the |
* format returned by DB::parseDSN() |
* @param array $options an associative array of option names and values |
* |
* @return object a new DB object. A DB_Error object on failure. |
* |
* @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(), |
* DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(), |
* DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(), |
* DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(), |
* DB_sybase::connect() |
* |
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError() |
*/ |
function &connect($dsn, $options = array()) |
{ |
$dsninfo = DB::parseDSN($dsn); |
$type = $dsninfo['phptype']; |
if (!is_array($options)) { |
/* |
* For backwards compatibility. $options used to be boolean, |
* indicating whether the connection should be persistent. |
*/ |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/${type}.php"; |
} else { |
@include_once "DB/${type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php" |
. " file for '$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj = new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
$err = $obj->connect($dsninfo, $obj->getOption('persistent')); |
if (DB::isError($err)) { |
if (is_array($dsn)) { |
$err->addUserInfo(DB::getDSNString($dsn, true)); |
} else { |
$err->addUserInfo($dsn); |
} |
return $err; |
} |
return $obj; |
} |
// }}} |
// {{{ apiVersion() |
/** |
* Return the DB API version |
* |
* @return string the DB API version number |
*/ |
function apiVersion() |
{ |
return '1.7.13'; |
} |
// }}} |
// {{{ isError() |
/** |
* Determines if a variable is a DB_Error object |
* |
* @param mixed $value the variable to check |
* |
* @return bool whether $value is DB_Error object |
*/ |
function isError($value) |
{ |
return is_a($value, 'DB_Error'); |
} |
// }}} |
// {{{ isConnection() |
/** |
* Determines if a value is a DB_<driver> object |
* |
* @param mixed $value the value to test |
* |
* @return bool whether $value is a DB_<driver> object |
*/ |
function isConnection($value) |
{ |
return (is_object($value) && |
is_subclass_of($value, 'db_common') && |
method_exists($value, 'simpleQuery')); |
} |
// }}} |
// {{{ isManip() |
/** |
* Tell whether a query is a data manipulation or data definition query |
* |
* Examples of data manipulation queries are INSERT, UPDATE and DELETE. |
* Examples of data definition queries are CREATE, DROP, ALTER, GRANT, |
* REVOKE. |
* |
* @param string $query the query |
* |
* @return boolean whether $query is a data manipulation query |
*/ |
function isManip($query) |
{ |
$manips = 'INSERT|UPDATE|DELETE|REPLACE|' |
. 'CREATE|DROP|' |
. 'LOAD DATA|SELECT .* INTO .* FROM|COPY|' |
. 'ALTER|GRANT|REVOKE|' |
. 'LOCK|UNLOCK'; |
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { |
return true; |
} |
return false; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Return a textual error message for a DB error code |
* |
* @param integer $value the DB error code |
* |
* @return string the error message or false if the error code was |
* not recognized |
*/ |
function errorMessage($value) |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
DB_ERROR => 'unknown error', |
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', |
DB_ERROR_ALREADY_EXISTS => 'already exists', |
DB_ERROR_CANNOT_CREATE => 'can not create', |
DB_ERROR_CANNOT_DROP => 'can not drop', |
DB_ERROR_CONNECT_FAILED => 'connect failed', |
DB_ERROR_CONSTRAINT => 'constraint violation', |
DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', |
DB_ERROR_DIVZERO => 'division by zero', |
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', |
DB_ERROR_INVALID => 'invalid', |
DB_ERROR_INVALID_DATE => 'invalid date or time', |
DB_ERROR_INVALID_DSN => 'invalid DSN', |
DB_ERROR_INVALID_NUMBER => 'invalid number', |
DB_ERROR_MISMATCH => 'mismatch', |
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', |
DB_ERROR_NODBSELECTED => 'no database selected', |
DB_ERROR_NOSUCHDB => 'no such database', |
DB_ERROR_NOSUCHFIELD => 'no such field', |
DB_ERROR_NOSUCHTABLE => 'no such table', |
DB_ERROR_NOT_CAPABLE => 'DB backend not capable', |
DB_ERROR_NOT_FOUND => 'not found', |
DB_ERROR_NOT_LOCKED => 'not locked', |
DB_ERROR_SYNTAX => 'syntax error', |
DB_ERROR_UNSUPPORTED => 'not supported', |
DB_ERROR_TRUNCATED => 'truncated', |
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', |
DB_OK => 'no error', |
); |
} |
if (DB::isError($value)) { |
$value = $value->getCode(); |
} |
return isset($errorMessages[$value]) ? $errorMessages[$value] |
: $errorMessages[DB_ERROR]; |
} |
// }}} |
// {{{ parseDSN() |
/** |
* Parse a data source name |
* |
* Additional keys can be added by appending a URI query string to the |
* end of the DSN. |
* |
* The format of the supplied DSN is in its fullest form: |
* <code> |
* phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true |
* </code> |
* |
* Most variations are allowed: |
* <code> |
* phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 |
* phptype://username:password@hostspec/database_name |
* phptype://username:password@hostspec |
* phptype://username@hostspec |
* phptype://hostspec/database |
* phptype://hostspec |
* phptype(dbsyntax) |
* phptype |
* </code> |
* |
* @param string $dsn Data Source Name to be parsed |
* |
* @return array an associative array with the following keys: |
* + phptype: Database backend used in PHP (mysql, odbc etc.) |
* + dbsyntax: Database used with regards to SQL syntax etc. |
* + protocol: Communication protocol to use (tcp, unix etc.) |
* + hostspec: Host specification (hostname[:port]) |
* + database: Database to use on the DBMS server |
* + username: User name for login |
* + password: Password for login |
*/ |
function parseDSN($dsn) |
{ |
$parsed = array( |
'phptype' => false, |
'dbsyntax' => false, |
'username' => false, |
'password' => false, |
'protocol' => false, |
'hostspec' => false, |
'port' => false, |
'socket' => false, |
'database' => false, |
); |
if (is_array($dsn)) { |
$dsn = array_merge($parsed, $dsn); |
if (!$dsn['dbsyntax']) { |
$dsn['dbsyntax'] = $dsn['phptype']; |
} |
return $dsn; |
} |
// Find phptype and dbsyntax |
if (($pos = strpos($dsn, '://')) !== false) { |
$str = substr($dsn, 0, $pos); |
$dsn = substr($dsn, $pos + 3); |
} else { |
$str = $dsn; |
$dsn = null; |
} |
// Get phptype and dbsyntax |
// $str => phptype(dbsyntax) |
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { |
$parsed['phptype'] = $arr[1]; |
$parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; |
} else { |
$parsed['phptype'] = $str; |
$parsed['dbsyntax'] = $str; |
} |
if (!count($dsn)) { |
return $parsed; |
} |
// Get (if found): username and password |
// $dsn => username:password@protocol+hostspec/database |
if (($at = strrpos($dsn,'@')) !== false) { |
$str = substr($dsn, 0, $at); |
$dsn = substr($dsn, $at + 1); |
if (($pos = strpos($str, ':')) !== false) { |
$parsed['username'] = rawurldecode(substr($str, 0, $pos)); |
$parsed['password'] = rawurldecode(substr($str, $pos + 1)); |
} else { |
$parsed['username'] = rawurldecode($str); |
} |
} |
// Find protocol and hostspec |
if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { |
// $dsn => proto(proto_opts)/database |
$proto = $match[1]; |
$proto_opts = $match[2] ? $match[2] : false; |
$dsn = $match[3]; |
} else { |
// $dsn => protocol+hostspec/database (old format) |
if (strpos($dsn, '+') !== false) { |
list($proto, $dsn) = explode('+', $dsn, 2); |
} |
if (strpos($dsn, '/') !== false) { |
list($proto_opts, $dsn) = explode('/', $dsn, 2); |
} else { |
$proto_opts = $dsn; |
$dsn = null; |
} |
} |
// process the different protocol options |
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; |
$proto_opts = rawurldecode($proto_opts); |
if (strpos($proto_opts, ':') !== false) { |
list($proto_opts, $parsed['port']) = explode(':', $proto_opts); |
} |
if ($parsed['protocol'] == 'tcp') { |
$parsed['hostspec'] = $proto_opts; |
} elseif ($parsed['protocol'] == 'unix') { |
$parsed['socket'] = $proto_opts; |
} |
// Get dabase if any |
// $dsn => database |
if ($dsn) { |
if (($pos = strpos($dsn, '?')) === false) { |
// /database |
$parsed['database'] = rawurldecode($dsn); |
} else { |
// /database?param1=value1¶m2=value2 |
$parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); |
$dsn = substr($dsn, $pos + 1); |
if (strpos($dsn, '&') !== false) { |
$opts = explode('&', $dsn); |
} else { // database?param1=value1 |
$opts = array($dsn); |
} |
foreach ($opts as $opt) { |
list($key, $value) = explode('=', $opt); |
if (!isset($parsed[$key])) { |
// don't allow params overwrite |
$parsed[$key] = rawurldecode($value); |
} |
} |
} |
} |
return $parsed; |
} |
// }}} |
// {{{ getDSNString() |
/** |
* Returns the given DSN in a string format suitable for output. |
* |
* @param array|string the DSN to parse and format |
* @param boolean true to hide the password, false to include it |
* @return string |
*/ |
function getDSNString($dsn, $hidePassword) { |
/* Calling parseDSN will ensure that we have all the array elements |
* defined, and means that we deal with strings and array in the same |
* manner. */ |
$dsnArray = DB::parseDSN($dsn); |
if ($hidePassword) { |
$dsnArray['password'] = 'PASSWORD'; |
} |
/* Protocol is special-cased, as using the default "tcp" along with an |
* Oracle TNS connection string fails. */ |
if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') { |
$dsnArray['protocol'] = false; |
} |
// Now we just have to construct the actual string. This is ugly. |
$dsnString = $dsnArray['phptype']; |
if ($dsnArray['dbsyntax']) { |
$dsnString .= '('.$dsnArray['dbsyntax'].')'; |
} |
$dsnString .= '://' |
.$dsnArray['username'] |
.':' |
.$dsnArray['password'] |
.'@' |
.$dsnArray['protocol']; |
if ($dsnArray['socket']) { |
$dsnString .= '('.$dsnArray['socket'].')'; |
} |
if ($dsnArray['protocol'] && $dsnArray['hostspec']) { |
$dsnString .= '+'; |
} |
$dsnString .= $dsnArray['hostspec']; |
if ($dsnArray['port']) { |
$dsnString .= ':'.$dsnArray['port']; |
} |
$dsnString .= '/'.$dsnArray['database']; |
/* Option handling. Unfortunately, parseDSN simply places options into |
* the top-level array, so we'll first get rid of the fields defined by |
* DB and see what's left. */ |
unset($dsnArray['phptype'], |
$dsnArray['dbsyntax'], |
$dsnArray['username'], |
$dsnArray['password'], |
$dsnArray['protocol'], |
$dsnArray['socket'], |
$dsnArray['hostspec'], |
$dsnArray['port'], |
$dsnArray['database'] |
); |
if (count($dsnArray) > 0) { |
$dsnString .= '?'; |
$i = 0; |
foreach ($dsnArray as $key => $value) { |
if (++$i > 1) { |
$dsnString .= '&'; |
} |
$dsnString .= $key.'='.$value; |
} |
} |
return $dsnString; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_Error |
/** |
* DB_Error implements a class for reporting portable database error |
* messages |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_Error extends PEAR_Error |
{ |
// {{{ constructor |
/** |
* DB_Error constructor |
* |
* @param mixed $code DB error code, or string with error message |
* @param int $mode what "error mode" to operate in |
* @param int $level what error level to use for $mode & |
* PEAR_ERROR_TRIGGER |
* @param mixed $debuginfo additional debug info, such as the last query |
* |
* @see PEAR_Error |
*/ |
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, |
$level = E_USER_NOTICE, $debuginfo = null) |
{ |
if (is_int($code)) { |
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, |
$mode, $level, $debuginfo); |
} else { |
$this->PEAR_Error("DB Error: $code", DB_ERROR, |
$mode, $level, $debuginfo); |
} |
} |
// }}} |
} |
// }}} |
// {{{ class DB_result |
/** |
* This class implements a wrapper for a DB result set |
* |
* A new instance of this class will be returned by the DB implementation |
* after processing a query that returns data. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_result |
{ |
// {{{ properties |
/** |
* Should results be freed automatically when there are no more rows? |
* @var boolean |
* @see DB_common::$options |
*/ |
var $autofree; |
/** |
* A reference to the DB_<driver> object |
* @var object |
*/ |
var $dbh; |
/** |
* The current default fetch mode |
* @var integer |
* @see DB_common::$fetchmode |
*/ |
var $fetchmode; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
* @see DB_common::$fetchmode_object_class |
*/ |
var $fetchmode_object_class; |
/** |
* The number of rows to fetch from a limit query |
* @var integer |
*/ |
var $limit_count = null; |
/** |
* The row to start fetching from in limit queries |
* @var integer |
*/ |
var $limit_from = null; |
/** |
* The execute parameters that created this result |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $parameters; |
/** |
* The query string that created this result |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* @var string |
* @since Property available since Release 1.7.0 |
*/ |
var $query; |
/** |
* The query result resource id created by PHP |
* @var resource |
*/ |
var $result; |
/** |
* The present row being dealt with |
* @var integer |
*/ |
var $row_counter = null; |
/** |
* The prepared statement resource id created by PHP in $dbh |
* |
* This resource is only available when the result set was created using |
* a driver's native execute() method, not PEAR DB's emulated one. |
* |
* Copied here incase it changes in $dbh, which is referenced |
* |
* {@internal Mainly here because the InterBase/Firebird API is only |
* able to retrieve data from result sets if the statemnt handle is |
* still in scope.}} |
* |
* @var resource |
* @since Property available since Release 1.7.0 |
*/ |
var $statement; |
// }}} |
// {{{ constructor |
/** |
* This constructor sets the object's properties |
* |
* @param object &$dbh the DB object reference |
* @param resource $result the result resource id |
* @param array $options an associative array with result options |
* |
* @return void |
*/ |
function DB_result(&$dbh, $result, $options = array()) |
{ |
$this->autofree = $dbh->options['autofree']; |
$this->dbh = &$dbh; |
$this->fetchmode = $dbh->fetchmode; |
$this->fetchmode_object_class = $dbh->fetchmode_object_class; |
$this->parameters = $dbh->last_parameters; |
$this->query = $dbh->last_query; |
$this->result = $result; |
$this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; |
foreach ($options as $key => $value) { |
$this->setOption($key, $value); |
} |
} |
/** |
* Set options for the DB_result object |
* |
* @param string $key the option to set |
* @param mixed $value the value to set the option to |
* |
* @return void |
*/ |
function setOption($key, $value = null) |
{ |
switch ($key) { |
case 'limit_from': |
$this->limit_from = $value; |
break; |
case 'limit_count': |
$this->limit_count = $value; |
} |
} |
// }}} |
// {{{ fetchRow() |
/** |
* Fetch a row of data and return it by reference into an array |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed an array or object containing the row's data, |
* NULL when the end of the result set is reached |
* or a DB_Error object on failure. |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if (is_null($rownum) && $this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ($this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
$tmp = null; |
return $tmp; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// The default mode is specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = new $object_class($arr); |
} |
} |
return $arr; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Fetch a row of data into an array which is passed by reference |
* |
* The type of array returned can be controlled either by setting this |
* method's <var>$fetchmode</var> parameter or by changing the default |
* fetch mode setFetchMode() before calling this method. |
* |
* There are two options for standardizing the information returned |
* from databases, ensuring their values are consistent when changing |
* DBMS's. These portability options can be turned on when creating a |
* new DB object or by using setOption(). |
* |
* + <var>DB_PORTABILITY_LOWERCASE</var> |
* convert names of fields to lower case |
* |
* + <var>DB_PORTABILITY_RTRIM</var> |
* right trim the data |
* |
* @param array &$arr the variable where the data should be placed |
* @param int $fetchmode the constant indicating how to format the data |
* @param int $rownum the row number to fetch (index starts at 0) |
* |
* @return mixed DB_OK if a row is processed, NULL when the end of the |
* result set is reached or a DB_Error object on failure |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
*/ |
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if (is_null($rownum) && $this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->dbh->features['limit'] === false) { |
$i = 0; |
while ($i++ < $this->limit_from) { |
$this->dbh->fetchInto($this->result, $arr, $fetchmode); |
} |
} |
} |
if ($this->row_counter >= ( |
$this->limit_from + $this->limit_count)) |
{ |
if ($this->autofree) { |
$this->free(); |
} |
return null; |
} |
if ($this->dbh->features['limit'] === 'emulate') { |
$rownum = $this->row_counter; |
} |
$this->row_counter++; |
} |
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); |
if ($res === DB_OK) { |
if (isset($object_class)) { |
// default mode specified in the |
// DB_common::fetchmode_object_class property |
if ($object_class == 'stdClass') { |
$arr = (object) $arr; |
} else { |
$arr = new $object_class($arr); |
} |
} |
return DB_OK; |
} |
if ($res == null && $this->autofree) { |
$this->free(); |
} |
return $res; |
} |
// }}} |
// {{{ numCols() |
/** |
* Get the the number of columns in a result set |
* |
* @return int the number of columns. A DB_Error object on failure. |
*/ |
function numCols() |
{ |
return $this->dbh->numCols($this->result); |
} |
// }}} |
// {{{ numRows() |
/** |
* Get the number of rows in a result set |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows() |
{ |
if ($this->dbh->features['numrows'] === 'emulate' |
&& $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) |
{ |
if ($this->dbh->features['prepare']) { |
$res = $this->dbh->query($this->query, $this->parameters); |
} else { |
$res = $this->dbh->query($this->query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$i = 0; |
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) { |
$i++; |
} |
$count = $i; |
} else { |
$count = $this->dbh->numRows($this->result); |
} |
/* fbsql is checked for here because limit queries are implemented |
* using a TOP() function, which results in fbsql_num_rows still |
* returning the total number of rows that would have been returned, |
* rather than the real number. As a result, we'll just do the limit |
* calculations for fbsql in the same way as a database with emulated |
* limits. Unfortunately, we can't just do this in DB_fbsql::numRows() |
* because that only gets the result resource, rather than the full |
* DB_Result object. */ |
if (($this->dbh->features['limit'] === 'emulate' |
&& $this->limit_from !== null) |
|| $this->dbh->phptype == 'fbsql') { |
$limit_count = is_null($this->limit_count) ? $count : $this->limit_count; |
if ($count < $this->limit_from) { |
$count = 0; |
} elseif ($count < ($this->limit_from + $limit_count)) { |
$count -= $this->limit_from; |
} else { |
$count = $limit_count; |
} |
} |
return $count; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Get the next result if a batch of queries was executed |
* |
* @return bool true if a new result is available or false if not |
*/ |
function nextResult() |
{ |
return $this->dbh->nextResult($this->result); |
} |
// }}} |
// {{{ free() |
/** |
* Frees the resources allocated for this result set |
* |
* @return bool true on success. A DB_Error object on failure. |
*/ |
function free() |
{ |
$err = $this->dbh->freeResult($this->result); |
if (DB::isError($err)) { |
return $err; |
} |
$this->result = false; |
$this->statement = false; |
return true; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* @see DB_common::tableInfo() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function tableInfo($mode = null) |
{ |
if (is_string($mode)) { |
return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
return $this->dbh->tableInfo($this, $mode); |
} |
// }}} |
// {{{ getQuery() |
/** |
* Determine the query string that created this result |
* |
* @return string the query string |
* |
* @since Method available since Release 1.7.0 |
*/ |
function getQuery() |
{ |
return $this->query; |
} |
// }}} |
// {{{ getRowCounter() |
/** |
* Tells which row number is currently being processed |
* |
* @return integer the current row being looked at. Starts at 1. |
*/ |
function getRowCounter() |
{ |
return $this->row_counter; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_row |
/** |
* PEAR DB Row Object |
* |
* The object contains a row of data from a result set. Each column's data |
* is placed in a property named for the column. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
* @see DB_common::setFetchMode() |
*/ |
class DB_row |
{ |
// {{{ constructor |
/** |
* The constructor places a row's data into properties of this object |
* |
* @param array the array containing the row's data |
* |
* @return void |
*/ |
function DB_row(&$arr) |
{ |
foreach ($arr as $key => $value) { |
$this->$key = &$arr[$key]; |
} |
} |
// }}} |
} |
// }}} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/tags/0.9.2/lib/config.php |
---|
Новый файл |
0,0 → 1,21 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
# Define options for MySQL connection |
define('DBNAME', "generator"); // Database name |
define('DBUSER', "sqluser"); // Database user |
define('DBPASS', "sqlpass"); // Password |
define('DBHOST', "localhost"); // Database host |
define('PREFIX', "g_"); // Database tables prefix |
?> |
/tags/0.9.2/lib/PEAR.php |
---|
Новый файл |
0,0 → 1,1118 |
<?php |
/** |
* PEAR, the PHP Extension and Application Repository |
* |
* PEAR class and PEAR_Error class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Sterling Hughes <sterling@php.net> |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2008 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: PEAR.php,v 1.104 2008/01/03 20:26:34 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 0.1 |
*/ |
/**#@+ |
* ERROR constants |
*/ |
define('PEAR_ERROR_RETURN', 1); |
define('PEAR_ERROR_PRINT', 2); |
define('PEAR_ERROR_TRIGGER', 4); |
define('PEAR_ERROR_DIE', 8); |
define('PEAR_ERROR_CALLBACK', 16); |
/** |
* WARNING: obsolete |
* @deprecated |
*/ |
define('PEAR_ERROR_EXCEPTION', 32); |
/**#@-*/ |
define('PEAR_ZE2', (function_exists('version_compare') && |
version_compare(zend_version(), "2-dev", "ge"))); |
if (substr(PHP_OS, 0, 3) == 'WIN') { |
define('OS_WINDOWS', true); |
define('OS_UNIX', false); |
define('PEAR_OS', 'Windows'); |
} else { |
define('OS_WINDOWS', false); |
define('OS_UNIX', true); |
define('PEAR_OS', 'Unix'); // blatant assumption |
} |
// instant backwards compatibility |
if (!defined('PATH_SEPARATOR')) { |
if (OS_WINDOWS) { |
define('PATH_SEPARATOR', ';'); |
} else { |
define('PATH_SEPARATOR', ':'); |
} |
} |
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; |
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; |
$GLOBALS['_PEAR_destructor_object_list'] = array(); |
$GLOBALS['_PEAR_shutdown_funcs'] = array(); |
$GLOBALS['_PEAR_error_handler_stack'] = array(); |
@ini_set('track_errors', true); |
/** |
* Base class for other PEAR classes. Provides rudimentary |
* emulation of destructors. |
* |
* If you want a destructor in your class, inherit PEAR and make a |
* destructor method called _yourclassname (same name as the |
* constructor, but with a "_" prefix). Also, in your constructor you |
* have to call the PEAR constructor: $this->PEAR();. |
* The destructor method will be called without parameters. Note that |
* at in some SAPI implementations (such as Apache), any output during |
* the request shutdown (in which destructors are called) seems to be |
* discarded. If you need to get any debug information from your |
* destructor, use error_log(), syslog() or something similar. |
* |
* IMPORTANT! To use the emulated destructors you need to create the |
* objects by reference: $obj =& new PEAR_child; |
* |
* @category pear |
* @package PEAR |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.2 |
* @link http://pear.php.net/package/PEAR |
* @see PEAR_Error |
* @since Class available since PHP 4.0.2 |
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear |
*/ |
class PEAR |
{ |
// {{{ properties |
/** |
* Whether to enable internal debug messages. |
* |
* @var bool |
* @access private |
*/ |
var $_debug = false; |
/** |
* Default error mode for this object. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_mode = null; |
/** |
* Default error options used for this object when error mode |
* is PEAR_ERROR_TRIGGER. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_options = null; |
/** |
* Default error handler (callback) for this object, if error mode is |
* PEAR_ERROR_CALLBACK. |
* |
* @var string |
* @access private |
*/ |
var $_default_error_handler = ''; |
/** |
* Which class to use for error objects. |
* |
* @var string |
* @access private |
*/ |
var $_error_class = 'PEAR_Error'; |
/** |
* An array of expected errors. |
* |
* @var array |
* @access private |
*/ |
var $_expected_errors = array(); |
// }}} |
// {{{ constructor |
/** |
* Constructor. Registers this object in |
* $_PEAR_destructor_object_list for destructor emulation if a |
* destructor object exists. |
* |
* @param string $error_class (optional) which class to use for |
* error objects, defaults to PEAR_Error. |
* @access public |
* @return void |
*/ |
function PEAR($error_class = null) |
{ |
$classname = strtolower(get_class($this)); |
if ($this->_debug) { |
print "PEAR constructor called, class=$classname\n"; |
} |
if ($error_class !== null) { |
$this->_error_class = $error_class; |
} |
while ($classname && strcasecmp($classname, "pear")) { |
$destructor = "_$classname"; |
if (method_exists($this, $destructor)) { |
global $_PEAR_destructor_object_list; |
$_PEAR_destructor_object_list[] = &$this; |
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { |
register_shutdown_function("_PEAR_call_destructors"); |
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; |
} |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// }}} |
// {{{ destructor |
/** |
* Destructor (the emulated type of...). Does nothing right now, |
* but is included for forward compatibility, so subclass |
* destructors should always call it. |
* |
* See the note in the class desciption about output from |
* destructors. |
* |
* @access public |
* @return void |
*/ |
function _PEAR() { |
if ($this->_debug) { |
printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); |
} |
} |
// }}} |
// {{{ getStaticProperty() |
/** |
* If you have a class that's mostly/entirely static, and you need static |
* properties, you can use this method to simulate them. Eg. in your method(s) |
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); |
* You MUST use a reference, or they will not persist! |
* |
* @access public |
* @param string $class The calling classname, to prevent clashes |
* @param string $var The variable to retrieve. |
* @return mixed A reference to the variable. If not set it will be |
* auto initialised to NULL. |
*/ |
function &getStaticProperty($class, $var) |
{ |
static $properties; |
if (!isset($properties[$class])) { |
$properties[$class] = array(); |
} |
if (!array_key_exists($var, $properties[$class])) { |
$properties[$class][$var] = null; |
} |
return $properties[$class][$var]; |
} |
// }}} |
// {{{ registerShutdownFunc() |
/** |
* Use this function to register a shutdown method for static |
* classes. |
* |
* @access public |
* @param mixed $func The function name (or array of class/method) to call |
* @param mixed $args The arguments to pass to the function |
* @return void |
*/ |
function registerShutdownFunc($func, $args = array()) |
{ |
// if we are called statically, there is a potential |
// that no shutdown func is registered. Bug #6445 |
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { |
register_shutdown_function("_PEAR_call_destructors"); |
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; |
} |
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); |
} |
// }}} |
// {{{ isError() |
/** |
* Tell whether a value is a PEAR error. |
* |
* @param mixed $data the value to test |
* @param int $code if $data is an error object, return true |
* only if $code is a string and |
* $obj->getMessage() == $code or |
* $code is an integer and $obj->getCode() == $code |
* @access public |
* @return bool true if parameter is an error |
*/ |
function isError($data, $code = null) |
{ |
if (is_a($data, 'PEAR_Error')) { |
if (is_null($code)) { |
return true; |
} elseif (is_string($code)) { |
return $data->getMessage() == $code; |
} else { |
return $data->getCode() == $code; |
} |
} |
return false; |
} |
// }}} |
// {{{ setErrorHandling() |
/** |
* Sets how errors generated by this object should be handled. |
* Can be invoked both in objects and statically. If called |
* statically, setErrorHandling sets the default behaviour for all |
* PEAR objects. If called in an object, setErrorHandling sets |
* the default behaviour for that object. |
* |
* @param int $mode |
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options |
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one |
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* |
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected |
* to be the callback function or method. A callback |
* function is a string with the name of the function, a |
* callback method is an array of two elements: the element |
* at index 0 is the object, and the element at index 1 is |
* the name of the method to call in the object. |
* |
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is |
* a printf format string used when printing the error |
* message. |
* |
* @access public |
* @return void |
* @see PEAR_ERROR_RETURN |
* @see PEAR_ERROR_PRINT |
* @see PEAR_ERROR_TRIGGER |
* @see PEAR_ERROR_DIE |
* @see PEAR_ERROR_CALLBACK |
* @see PEAR_ERROR_EXCEPTION |
* |
* @since PHP 4.0.5 |
*/ |
function setErrorHandling($mode = null, $options = null) |
{ |
if (isset($this) && is_a($this, 'PEAR')) { |
$setmode = &$this->_default_error_mode; |
$setoptions = &$this->_default_error_options; |
} else { |
$setmode = &$GLOBALS['_PEAR_default_error_mode']; |
$setoptions = &$GLOBALS['_PEAR_default_error_options']; |
} |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$setmode = $mode; |
$setoptions = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$setmode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$setoptions = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
} |
// }}} |
// {{{ expectError() |
/** |
* This method is used to tell which errors you expect to get. |
* Expected errors are always returned with error mode |
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack, |
* and this method pushes a new element onto it. The list of |
* expected errors are in effect until they are popped off the |
* stack with the popExpect() method. |
* |
* Note that this method can not be called statically |
* |
* @param mixed $code a single error code or an array of error codes to expect |
* |
* @return int the new depth of the "expected errors" stack |
* @access public |
*/ |
function expectError($code = '*') |
{ |
if (is_array($code)) { |
array_push($this->_expected_errors, $code); |
} else { |
array_push($this->_expected_errors, array($code)); |
} |
return sizeof($this->_expected_errors); |
} |
// }}} |
// {{{ popExpect() |
/** |
* This method pops one element off the expected error codes |
* stack. |
* |
* @return array the list of error codes that were popped |
*/ |
function popExpect() |
{ |
return array_pop($this->_expected_errors); |
} |
// }}} |
// {{{ _checkDelExpect() |
/** |
* This method checks unsets an error code if available |
* |
* @param mixed error code |
* @return bool true if the error code was unset, false otherwise |
* @access private |
* @since PHP 4.3.0 |
*/ |
function _checkDelExpect($error_code) |
{ |
$deleted = false; |
foreach ($this->_expected_errors AS $key => $error_array) { |
if (in_array($error_code, $error_array)) { |
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); |
$deleted = true; |
} |
// clean up empty arrays |
if (0 == count($this->_expected_errors[$key])) { |
unset($this->_expected_errors[$key]); |
} |
} |
return $deleted; |
} |
// }}} |
// {{{ delExpect() |
/** |
* This method deletes all occurences of the specified element from |
* the expected error codes stack. |
* |
* @param mixed $error_code error code that should be deleted |
* @return mixed list of error codes that were deleted or error |
* @access public |
* @since PHP 4.3.0 |
*/ |
function delExpect($error_code) |
{ |
$deleted = false; |
if ((is_array($error_code) && (0 != count($error_code)))) { |
// $error_code is a non-empty array here; |
// we walk through it trying to unset all |
// values |
foreach($error_code as $key => $error) { |
if ($this->_checkDelExpect($error)) { |
$deleted = true; |
} else { |
$deleted = false; |
} |
} |
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} elseif (!empty($error_code)) { |
// $error_code comes alone, trying to unset it |
if ($this->_checkDelExpect($error_code)) { |
return true; |
} else { |
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} |
} else { |
// $error_code is empty |
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME |
} |
} |
// }}} |
// {{{ raiseError() |
/** |
* This method is a wrapper that returns an instance of the |
* configured error class with this object's default error |
* handling applied. If the $mode and $options parameters are not |
* specified, the object's defaults are used. |
* |
* @param mixed $message a text error message or a PEAR error object |
* |
* @param int $code a numeric error code (it is up to your class |
* to define these if you want to use codes) |
* |
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter |
* specifies the PHP-internal error level (one of |
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* If $mode is PEAR_ERROR_CALLBACK, this |
* parameter specifies the callback function or |
* method. In other error modes this parameter |
* is ignored. |
* |
* @param string $userinfo If you need to pass along for example debug |
* information, this parameter is meant for that. |
* |
* @param string $error_class The returned error object will be |
* instantiated from this class, if specified. |
* |
* @param bool $skipmsg If true, raiseError will only pass error codes, |
* the error message parameter will be dropped. |
* |
* @access public |
* @return object a PEAR error object |
* @see PEAR::setErrorHandling |
* @since PHP 4.0.5 |
*/ |
function &raiseError($message = null, |
$code = null, |
$mode = null, |
$options = null, |
$userinfo = null, |
$error_class = null, |
$skipmsg = false) |
{ |
// The error is yet a PEAR error object |
if (is_object($message)) { |
$code = $message->getCode(); |
$userinfo = $message->getUserInfo(); |
$error_class = $message->getType(); |
$message->error_message_prefix = ''; |
$message = $message->getMessage(); |
} |
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { |
if ($exp[0] == "*" || |
(is_int(reset($exp)) && in_array($code, $exp)) || |
(is_string(reset($exp)) && in_array($message, $exp))) { |
$mode = PEAR_ERROR_RETURN; |
} |
} |
// No mode given, try global ones |
if ($mode === null) { |
// Class error handler |
if (isset($this) && isset($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
// Global error handler |
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { |
$mode = $GLOBALS['_PEAR_default_error_mode']; |
$options = $GLOBALS['_PEAR_default_error_options']; |
} |
} |
if ($error_class !== null) { |
$ec = $error_class; |
} elseif (isset($this) && isset($this->_error_class)) { |
$ec = $this->_error_class; |
} else { |
$ec = 'PEAR_Error'; |
} |
if (intval(PHP_VERSION) < 5) { |
// little non-eval hack to fix bug #12147 |
include 'PEAR/FixPHP5PEARWarnings.php'; |
return $a; |
} |
if ($skipmsg) { |
$a = new $ec($code, $mode, $options, $userinfo); |
} else { |
$a = new $ec($message, $code, $mode, $options, $userinfo); |
} |
return $a; |
} |
// }}} |
// {{{ throwError() |
/** |
* Simpler form of raiseError with fewer options. In most cases |
* message, code and userinfo are enough. |
* |
* @param string $message |
* |
*/ |
function &throwError($message = null, |
$code = null, |
$userinfo = null) |
{ |
if (isset($this) && is_a($this, 'PEAR')) { |
$a = &$this->raiseError($message, $code, null, null, $userinfo); |
return $a; |
} else { |
$a = &PEAR::raiseError($message, $code, null, null, $userinfo); |
return $a; |
} |
} |
// }}} |
function staticPushErrorHandling($mode, $options = null) |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
$def_options = &$GLOBALS['_PEAR_default_error_options']; |
$stack[] = array($def_mode, $def_options); |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$def_mode = $mode; |
$def_options = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$def_mode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$def_options = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
$stack[] = array($mode, $options); |
return true; |
} |
function staticPopErrorHandling() |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
$setmode = &$GLOBALS['_PEAR_default_error_mode']; |
$setoptions = &$GLOBALS['_PEAR_default_error_options']; |
array_pop($stack); |
list($mode, $options) = $stack[sizeof($stack) - 1]; |
array_pop($stack); |
switch ($mode) { |
case PEAR_ERROR_EXCEPTION: |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case null: |
$setmode = $mode; |
$setoptions = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$setmode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$setoptions = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
return true; |
} |
// {{{ pushErrorHandling() |
/** |
* Push a new error handler on top of the error handler options stack. With this |
* you can easily override the actual error handler for some code and restore |
* it later with popErrorHandling. |
* |
* @param mixed $mode (same as setErrorHandling) |
* @param mixed $options (same as setErrorHandling) |
* |
* @return bool Always true |
* |
* @see PEAR::setErrorHandling |
*/ |
function pushErrorHandling($mode, $options = null) |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
if (isset($this) && is_a($this, 'PEAR')) { |
$def_mode = &$this->_default_error_mode; |
$def_options = &$this->_default_error_options; |
} else { |
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
$def_options = &$GLOBALS['_PEAR_default_error_options']; |
} |
$stack[] = array($def_mode, $def_options); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
$stack[] = array($mode, $options); |
return true; |
} |
// }}} |
// {{{ popErrorHandling() |
/** |
* Pop the last error handler used |
* |
* @return bool Always true |
* |
* @see PEAR::pushErrorHandling |
*/ |
function popErrorHandling() |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
array_pop($stack); |
list($mode, $options) = $stack[sizeof($stack) - 1]; |
array_pop($stack); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
return true; |
} |
// }}} |
// {{{ loadExtension() |
/** |
* OS independant PHP extension load. Remember to take care |
* on the correct extension name for case sensitive OSes. |
* |
* @param string $ext The extension name |
* @return bool Success or not on the dl() call |
*/ |
function loadExtension($ext) |
{ |
if (!extension_loaded($ext)) { |
// if either returns true dl() will produce a FATAL error, stop that |
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { |
return false; |
} |
if (OS_WINDOWS) { |
$suffix = '.dll'; |
} elseif (PHP_OS == 'HP-UX') { |
$suffix = '.sl'; |
} elseif (PHP_OS == 'AIX') { |
$suffix = '.a'; |
} elseif (PHP_OS == 'OSX') { |
$suffix = '.bundle'; |
} else { |
$suffix = '.so'; |
} |
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); |
} |
return true; |
} |
// }}} |
} |
// {{{ _PEAR_call_destructors() |
function _PEAR_call_destructors() |
{ |
global $_PEAR_destructor_object_list; |
if (is_array($_PEAR_destructor_object_list) && |
sizeof($_PEAR_destructor_object_list)) |
{ |
reset($_PEAR_destructor_object_list); |
if (PEAR::getStaticProperty('PEAR', 'destructlifo')) { |
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); |
} |
while (list($k, $objref) = each($_PEAR_destructor_object_list)) { |
$classname = get_class($objref); |
while ($classname) { |
$destructor = "_$classname"; |
if (method_exists($objref, $destructor)) { |
$objref->$destructor(); |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// Empty the object list to ensure that destructors are |
// not called more than once. |
$_PEAR_destructor_object_list = array(); |
} |
// Now call the shutdown functions |
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { |
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { |
call_user_func_array($value[0], $value[1]); |
} |
} |
} |
// }}} |
/** |
* Standard PEAR error class for PHP 4 |
* |
* This class is supserseded by {@link PEAR_Exception} in PHP 5 |
* |
* @category pear |
* @package PEAR |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Gregory Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.2 |
* @link http://pear.php.net/manual/en/core.pear.pear-error.php |
* @see PEAR::raiseError(), PEAR::throwError() |
* @since Class available since PHP 4.0.2 |
*/ |
class PEAR_Error |
{ |
// {{{ properties |
var $error_message_prefix = ''; |
var $mode = PEAR_ERROR_RETURN; |
var $level = E_USER_NOTICE; |
var $code = -1; |
var $message = ''; |
var $userinfo = ''; |
var $backtrace = null; |
// }}} |
// {{{ constructor |
/** |
* PEAR_Error constructor |
* |
* @param string $message message |
* |
* @param int $code (optional) error code |
* |
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, |
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION |
* |
* @param mixed $options (optional) error level, _OR_ in the case of |
* PEAR_ERROR_CALLBACK, the callback function or object/method |
* tuple. |
* |
* @param string $userinfo (optional) additional user/debug info |
* |
* @access public |
* |
*/ |
function PEAR_Error($message = 'unknown error', $code = null, |
$mode = null, $options = null, $userinfo = null) |
{ |
if ($mode === null) { |
$mode = PEAR_ERROR_RETURN; |
} |
$this->message = $message; |
$this->code = $code; |
$this->mode = $mode; |
$this->userinfo = $userinfo; |
if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { |
$this->backtrace = debug_backtrace(); |
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { |
unset($this->backtrace[0]['object']); |
} |
} |
if ($mode & PEAR_ERROR_CALLBACK) { |
$this->level = E_USER_NOTICE; |
$this->callback = $options; |
} else { |
if ($options === null) { |
$options = E_USER_NOTICE; |
} |
$this->level = $options; |
$this->callback = null; |
} |
if ($this->mode & PEAR_ERROR_PRINT) { |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
} else { |
$format = $options; |
} |
printf($format, $this->getMessage()); |
} |
if ($this->mode & PEAR_ERROR_TRIGGER) { |
trigger_error($this->getMessage(), $this->level); |
} |
if ($this->mode & PEAR_ERROR_DIE) { |
$msg = $this->getMessage(); |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
if (substr($msg, -1) != "\n") { |
$msg .= "\n"; |
} |
} else { |
$format = $options; |
} |
die(sprintf($format, $msg)); |
} |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_callable($this->callback)) { |
call_user_func($this->callback, $this); |
} |
} |
if ($this->mode & PEAR_ERROR_EXCEPTION) { |
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); |
eval('$e = new Exception($this->message, $this->code);throw($e);'); |
} |
} |
// }}} |
// {{{ getMode() |
/** |
* Get the error mode from an error object. |
* |
* @return int error mode |
* @access public |
*/ |
function getMode() { |
return $this->mode; |
} |
// }}} |
// {{{ getCallback() |
/** |
* Get the callback function/method from an error object. |
* |
* @return mixed callback function or object/method array |
* @access public |
*/ |
function getCallback() { |
return $this->callback; |
} |
// }}} |
// {{{ getMessage() |
/** |
* Get the error message from an error object. |
* |
* @return string full error message |
* @access public |
*/ |
function getMessage() |
{ |
return ($this->error_message_prefix . $this->message); |
} |
// }}} |
// {{{ getCode() |
/** |
* Get error code from an error object |
* |
* @return int error code |
* @access public |
*/ |
function getCode() |
{ |
return $this->code; |
} |
// }}} |
// {{{ getType() |
/** |
* Get the name of this error/exception. |
* |
* @return string error/exception name (type) |
* @access public |
*/ |
function getType() |
{ |
return get_class($this); |
} |
// }}} |
// {{{ getUserInfo() |
/** |
* Get additional user-supplied information. |
* |
* @return string user-supplied information |
* @access public |
*/ |
function getUserInfo() |
{ |
return $this->userinfo; |
} |
// }}} |
// {{{ getDebugInfo() |
/** |
* Get additional debug information supplied by the application. |
* |
* @return string debug information |
* @access public |
*/ |
function getDebugInfo() |
{ |
return $this->getUserInfo(); |
} |
// }}} |
// {{{ getBacktrace() |
/** |
* Get the call backtrace from where the error was generated. |
* Supported with PHP 4.3.0 or newer. |
* |
* @param int $frame (optional) what frame to fetch |
* @return array Backtrace, or NULL if not available. |
* @access public |
*/ |
function getBacktrace($frame = null) |
{ |
if (defined('PEAR_IGNORE_BACKTRACE')) { |
return null; |
} |
if ($frame === null) { |
return $this->backtrace; |
} |
return $this->backtrace[$frame]; |
} |
// }}} |
// {{{ addUserInfo() |
function addUserInfo($info) |
{ |
if (empty($this->userinfo)) { |
$this->userinfo = $info; |
} else { |
$this->userinfo .= " ** $info"; |
} |
} |
// }}} |
// {{{ toString() |
function __toString() |
{ |
return $this->getMessage(); |
} |
// }}} |
// {{{ toString() |
/** |
* Make a string representation of this object. |
* |
* @return string a string with an object summary |
* @access public |
*/ |
function toString() { |
$modes = array(); |
$levels = array(E_USER_NOTICE => 'notice', |
E_USER_WARNING => 'warning', |
E_USER_ERROR => 'error'); |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_array($this->callback)) { |
$callback = (is_object($this->callback[0]) ? |
strtolower(get_class($this->callback[0])) : |
$this->callback[0]) . '::' . |
$this->callback[1]; |
} else { |
$callback = $this->callback; |
} |
return sprintf('[%s: message="%s" code=%d mode=callback '. |
'callback=%s prefix="%s" info="%s"]', |
strtolower(get_class($this)), $this->message, $this->code, |
$callback, $this->error_message_prefix, |
$this->userinfo); |
} |
if ($this->mode & PEAR_ERROR_PRINT) { |
$modes[] = 'print'; |
} |
if ($this->mode & PEAR_ERROR_TRIGGER) { |
$modes[] = 'trigger'; |
} |
if ($this->mode & PEAR_ERROR_DIE) { |
$modes[] = 'die'; |
} |
if ($this->mode & PEAR_ERROR_RETURN) { |
$modes[] = 'return'; |
} |
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. |
'prefix="%s" info="%s"]', |
strtolower(get_class($this)), $this->message, $this->code, |
implode("|", $modes), $levels[$this->level], |
$this->error_message_prefix, |
$this->userinfo); |
} |
// }}} |
} |
/* |
* Local Variables: |
* mode: php |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/tags/0.9.2/lib/security.php |
---|
Новый файл |
0,0 → 1,65 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
class Security extends Core { |
public function __construct() { |
} |
/** |
* Проверка на валидность целочисленных значений |
* |
* @author Alexander Wolf |
* @category Security |
* |
* @param int $value |
* @return int |
*/ |
public function checkInt($value) { |
return abs(intval($value)); |
} |
/** |
* Обработка строковых переменных |
* |
* @author Alexander Wolf |
* @category Security |
* |
* @param string $value |
* @param byte $mode |
* @return string |
*/ |
public function checkStr($value, $mode = 0) { |
// mode - 0 -> wrap; mode - 1 -> strip; |
if ($mode == 0) { |
$result = mysql_real_escape_string($value); |
} else { |
$result = stripslashes($value); |
} |
return $result; |
} |
/** |
* генерация хеша пароля |
* |
* @author Alexander Wolf |
* @category Security |
* |
* @param string $string |
* @return string |
*/ |
public function encryptStr($string) { |
return md5(md5($string)."-CN-ANT-NG-".sha1($string)); |
} |
} |
?> |
/tags/0.9.2/lib/core.php |
---|
Новый файл |
0,0 → 1,2437 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
class Core { |
protected $db = NULL; |
protected $prefix = NULL; |
protected $secure = NULL; |
protected $cookie = NULL; |
/** |
* Конструктор класса Core - ядро генератора |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $database |
* @param string $prefix |
* @param object $secure |
* @param string $cookie |
*/ |
public function __construct($database, $prefix, $secure, $cookie) { |
$this->db = $database; |
$this->prefix = $prefix; |
$this->secure = $secure; |
$this->cookie = $cookie; |
} |
/** |
* Получение данных о настройке |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $attr |
* @return array |
*/ |
public function getOption($attr) { |
$result = array(); |
$query = "SELECT optvalue FROM ".$this->prefix."settings WHERE opt='".$this->secure->checkStr($attr)."'"; |
$rq =& $this->db->query($query); |
if ($rq->numRows()!=0) { |
$rq->fetchInto($element); |
$result["ERR"] = 0; |
$result["OptValue"] = $element["optvalue"]; |
} else { |
$result["ERR"] = 1; |
$result["ERRINFO"] = "Empty result"; |
} |
return $result; |
} |
/** |
* Установка данных о настройке |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $attr |
* @param string $value |
* @return array |
*/ |
public function setOption($attr, $value) { |
$result = array(); |
if ($attr != "passwd") { |
$sValue = $this->secure->checkStr($value); |
} else { |
$sValue = $value; |
} |
$query = "UPDATE ".$this->prefix."settings SET optvalue='".$sValue."' WHERE opt='".$attr."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Создание настройки |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $attr |
* @param string $value |
* @return array |
*/ |
public function addOption($attr, $value) { |
$result = array(); |
$sValue = $this->secure->checkStr($value); |
$query = "INSERT INTO ".$this->prefix."settings SET opt='".$attr."', optvalue='".$sValue."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Получение и отображение списка дистрибутвов |
* |
* @author Alexander Wolf |
* @category Core |
* @deprecated may be deprecated XXX |
* |
* @param string $name |
* @param string $heads |
* @param string $info |
* @param string $format |
* @return string |
*/ |
public function showDistributionList($name, $heads = "", $info = "", $format = 'html') { |
$query = "SELECT * FROM ".$this->prefix."distribution ORDER BY dist_id ASC"; |
$rq =& $this->db->query($query); |
switch ($format) { |
case 'html': |
$show = "<fieldset><legend>".$heads."</legend>\n<select id='".$name."' name='".$name."'>\n"; |
$show .= "<option value=''>".$info."</option>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<option value='".$this->secure->checkInt($element["dist_id"])."'>".$this->secure->checkStr($element["distname"],1)."</option>\n"; |
} |
$show .= "</select></fieldset>"; |
break; |
case 'json': |
$show = '[{value:"",text:"'.$info.'"}'; |
while ($rq->fetchInto($element)) { |
$show .= ',{value:"'.$this->secure->checkInt($element["dist_id"]).'",text:"'.$this->secure->checkStr($element["distname"],1).'"}'; |
} |
$show .= ']'; |
break; |
case 'innerhtml': |
$show = "<select id='".$name."' name='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<option value='".$this->secure->checkInt($element["dist_id"])."'>".$this->secure->checkStr($element["distname"],1)."</option>\n"; |
} |
$show .= "</select>"; |
break; |
case 'list': |
$show = "<ul>"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$heads."?mode=".$name."&action=edit&uuid=".$this->secure->checkInt($element["dist_id"])."' class='edit'>править</a>][<a href='".$heads."?mode=".$name."&action=delete&uuid=".$this->secure->checkInt($element["dist_id"])."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["distname"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
} |
return $show; |
} |
/** |
* Получение названия дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $distID |
* @return array |
*/ |
public function getDistName($distID) { |
$result = array(); |
$query = "SELECT distname FROM ".$this->prefix."distribution WHERE dist_id='".$this->secure->checkInt($distID)."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$rq->fetchInto($element); |
$result["ERR"] = 0; |
$result["DistName"] = $this->secure->checkStr($element["distname"],1); |
} |
return $result; |
} |
/** |
* Получение названия программы, ее версии и описания |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $attr |
* @return string |
*/ |
public function getEngineAttr($attr = 'codename') { |
$cname = $this->getOption($attr); |
return $this->secure->checkStr($cname["OptValue"],1); |
} |
/** |
* Получение и отображение списка версий дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param integer $distID |
* @param string $format |
* @return string |
*/ |
public function showDistVersionsList($name, $distID, $format = 'html', $actor = '') { |
$distname = $this->getDistName($distID); |
if ($distID == 0) { |
$query = "SELECT * FROM ".$this->prefix."version v JOIN ".$this->prefix."distribution d ON v.dist_id=d.dist_id ORDER BY d.dist_id,v.version ASC"; |
} else { |
$query = "SELECT * FROM ".$this->prefix."version WHERE dist_id='".$this->secure->checkInt($distID)."' ORDER BY version ASC"; |
} |
$rq =& $this->db->query($query); |
switch ($format) { |
case 'html': |
$show = "<fieldset><legend>Версии ".$distname["DistName"]."</legend>\n<select id='".$name."' name='".$name."'>\n"; |
$show .= "<option value=''>Выбери версию ".$distname["DistName"]."</option>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<option value='".$this->secure->checkInt($element["version_id"])."'>".$this->secure->checkStr($element["version"],1)." ".$this->secure->checkStr($element["vname"],1)."</option>\n"; |
} |
$show .= "</select></fieldset>"; |
break; |
case 'json': |
$show = '[{value:"",text:"Выбери версию '.$distname["DistName"].'"}'; |
while ($rq->fetchInto($element)) { |
$show .= ',{value:"'.$this->secure->checkInt($element["version_id"]).'",text:"'.$this->secure->checkStr($element["version"],1).' '.$this->secure->checkStr($element["vname"],1).'"}'; |
} |
$show .= ']'; |
break; |
case 'list': |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$this->secure->checkInt($element["version_id"])."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$this->secure->checkInt($element["version_id"])."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["distname"],1)." ".$this->secure->checkStr($element["version"],1)." “<em>".$this->secure->checkStr($element["vname"],1)."</em>”</li>\n"; |
} |
$show .= "</ul>"; |
break; |
} |
return $show; |
} |
/** |
* Получение и отображение списка секций основного (официального) репозитория |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $version |
* @param string $format |
* @return string |
*/ |
public function showBranchesList($version, $format = 'html') { |
$query = "SELECT rtype FROM ".$this->prefix."rtype WHERE rtype_id='1'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($types); |
$query = "SELECT s.*,t.rtype FROM ".$this->prefix."section s "; |
$query .= "JOIN ".$this->prefix."sect2rep l ON s.sect_id=l.sect_id "; |
$query .= "JOIN ".$this->prefix."repository r ON r.rep_id=l.rep_id "; |
$query .= "JOIN ".$this->prefix."rtype t ON r.rtype_id=t.rtype_id "; |
$query .= "WHERE t.rtype_id='1' AND r.version='".$this->secure->checkInt($version)."' "; |
$query .= "ORDER BY s.sect_id ASC"; |
$rq =& $this->db->query($query); |
switch ($format) { |
case 'html': |
$show = "<fieldset><legend>".$this->secure->checkStr($types["rtype"],1)."</legend>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<div class='sections'><input type='checkbox' name='section[]' value='".$element["sect_id"]."'> ".$this->secure->checkStr($element["secname"],1)." — ".$this->secure->checkStr($element["sectinfo"],1)."</div>\n"; |
} |
$show .= "</fieldset>\n"; |
break; |
case 'json': |
//TODO Доделать JSON-вывод списка секций основного репозитория |
break; |
} |
return $show; |
} |
/** |
* Получение и отображение списка репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $version |
* @param integer $reptype |
* @param string $format |
* @return string |
*/ |
public function showRepList($version, $reptype, $format = 'html') { |
$query = "SELECT rtype FROM ".$this->prefix."rtype WHERE rtype_id='".$this->secure->checkInt($reptype)."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($types); |
$query = "SELECT * FROM ".$this->prefix."repository WHERE version='".$this->secure->checkInt($version)."' AND rtype_id='".$this->secure->checkInt($reptype)."'"; |
$rq =& $this->db->query($query); |
switch ($format) { |
case 'html': |
if ($rq->numRows()>0) { |
$show = "<fieldset><legend>".$this->secure->checkStr($types["rtype"],1)."</legend>\n"; |
while ($rq->fetchInto($element)) { |
//TODO Сделать вывод информации об архитектурах репозитория |
$show .= "<div class='repository'><input type='checkbox' name='repository[]' value='".$element["rep_id"]."'> ".$this->secure->checkStr($element["repname"],1)." — ".$this->secure->checkStr($element["repinfo"],1)."</div>\n"; |
} |
$show .= "</fieldset>\n"; |
} |
break; |
case 'json': |
//TODO Доделать JSON-вывод списка репозиториев |
break; |
} |
return $show; |
} |
/** |
* Добавление поддержки нового apt-дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $distname |
* @param integer $disttype |
* @param string $distua |
* @param byte $distlogo |
* @return array |
*/ |
public function addDistribution($distname, $disttype, $distua = '', $distlogo = 0) { |
$result = array(); |
$sDName = $this->secure->checkStr($distname); |
$sDType = $this->secure->checkInt($disttype); |
$sDUAgt = $this->secure->checkStr($distua); |
$sDLogo = $this->secure->checkInt($distlogo); |
$query = "INSERT INTO ".$this->prefix."distribution SET distname='".$sDName."', distua='".$sDUAgt."', disttype='".$sDType."', distlogo='".$sDLogo."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о дистрибутиве |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $distID |
* @param string $distname |
* @param integer $disttype |
* @param string $distua |
* @param integer $distlogo |
* @return array |
*/ |
public function updateDistribution($distID, $distname, $disttype, $distua, $distlogo = 0) { |
$result = array(); |
$sDID = $this->secure->checkInt($distID); |
$sDName = $this->secure->checkStr($distname); |
$sDType = $this->secure->checkInt($disttype); |
$sDUAgt = $this->secure->checkStr($distua); |
$sDLogo = $this->secure->checkInt($distlogo); |
if ($sDLogo!=0) { |
$query = "UPDATE ".$this->prefix."distribution SET distname='".$sDName."', distua='".$sDUAgt."', disttype='".$sDType."', distlogo='".$sDLogo."' WHERE dist_id='".$sDID."'"; |
} else { |
$query = "UPDATE ".$this->prefix."distribution SET distname='".$sDName."', distua='".$sDUAgt."', disttype='".$sDType."' WHERE dist_id='".$sDID."'"; |
} |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о дистрибутиве |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $distID |
* @return array |
*/ |
public function dropDistribution($distID) { |
$result = array(); |
$sDID = $this->secure->checkInt($distID); |
// Удаление дистрибутива |
$query = "DELETE FROM ".$this->prefix."distribution WHERE dist_id='".$sDID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
// Удаление версий дистрибутива |
$query = "DELETE FROM ".$this->prefix."version WHERE dist_id='".$sDID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Добавление поддержки новой версии apt-дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $distID |
* @param integer $version |
* @param string $vname |
* @param integer $vcodename |
* @return array |
*/ |
public function addDistVersion($distID, $version, $vname = "", $vcodename = "") { |
$result = array(); |
$sDistID = $this->secure->checkInt($distID); |
$sDVersion = $this->secure->checkStr($version); |
$sDVName = $this->secure->checkStr($vname); |
$sDVCName = $this->secure->checkStr($vcodename); |
$query = "INSERT INTO ".$this->prefix."version SET dist_id='".$sDistID."', vname='".$sDVName."', version='".$sDVersion."', vcodename='".$sDVCName."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Редактирование информации о версии дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $versionID |
* @param string $version |
* @param string $vname |
* @param string $vcodename |
* @return array |
*/ |
public function updateDistVersion($versionID, $version, $vname = "", $vcodename = "") { |
$result = array(); |
$sVersID = $this->secure->checkInt($versionID); |
$sDVersion = $this->secure->checkStr($version,1); |
$sDVName = $this->secure->checkStr($vname,1); |
$sDVCName = $this->secure->checkStr($vcodename,1); |
$query = "UPDATE ".$this->prefix."version SET vname='".$sDVName."', version='".$sDVersion."', vcodename='".$sDVCName."' WHERE version_id='".$sVersID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о версии дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $versionID |
* @return array |
*/ |
public function dropDistVersion($versionID) { |
$result = array(); |
$sVersID = $this->secure->checkInt($versionID); |
// Удаление версии дистрибутива |
$query = "DELETE FROM ".$this->prefix."version WHERE version_id='".$sVersID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
// Удаление репозиториев этой версии дистрибутива |
$query = "DELETE FROM ".$this->prefix."repository WHERE version='".$sVersID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Отображение типа дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param byte $type |
* @return string |
*/ |
public function showDistTypeForm($name = "dtype",$type = 0) { |
$query = "SELECT * FROM ".$this->prefix."dtype"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["type_id"] == $type) { |
$show .= "<option value='".$element["type_id"]."' selected>".$this->secure->checkStr($element["type"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$element["type_id"]."'>".$this->secure->checkStr($element["type"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
return $show; |
} |
/** |
* Отображение формы создания и редактирования apt-дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $distID |
* @return string |
*/ |
public function showDistributionForm($distID = 0, $info = '') { |
$sDistID = $this->secure->checkInt($distID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Дистрибутив"; |
} |
if ($sDistID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."distribution WHERE dist_id='".$sDistID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
if ($element["distlogo"] == 1) { |
$image = "<img src='./img/d/".$this->secure->checkStr($element["distua"],1).".png' width='32' height='32' id='adm-dist-logo' alt='Логотип дистрибутива ".$this->secure->checkStr($element["distname"],1)."' title='Логотип дистрибутива ".$this->secure->checkStr($element["distname"],1)."'>"; |
} else { |
$image = "<img src='./img/d/empty-logo.png' width='32' height='32' id='adm-dist-logo' alt='Логотип дистрибутива' title='Логотип дистрибутива не загружен'>"; |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='dname'>Название дистрибутива:</label> <input type='text' name='dname' id='dname' value='".$this->secure->checkStr($element["distname"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='dua'>UA дистрибутива:</label> <input type='text' name='dua' id='dua' value='".$this->secure->checkStr($element["distua"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='dtype'>Тип дистрибутива:</label> ".$this->showDistTypeForm("dtype",$element["disttype"])."</div>\n"; |
$show .= "<div class='inputbox'><table><tr><td class='td-name'>Логотип дистрибутива:</td>\n"; |
$show .= "<td>".$image."</td>\n<td><input type='file' name='distlogo'></td>\n</tr></table>\n</div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Генератор sources.list |
* |
* @author Alexander Wolf |
* @category Core |
* @version 1.0 |
* |
* @param array $data |
* @return string |
*/ |
public function showSourcesList($data) { |
// Извлекаем информацию о дистрибутиве и его версии |
$query = "SELECT * FROM ".$this->prefix."distribution d "; |
$query .= "JOIN ".$this->prefix."version v ON v.dist_id=d.dist_id "; |
$query .= "JOIN ".$this->prefix."dtype t ON d.disttype=t.type_id "; |
$query .= "WHERE d.dist_id='".$data["dist_id"]."' AND v.version_id='".$data["version_id"]."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($dist); |
$show = "# Список репозиториев для ".$this->secure->checkStr($dist["distname"],1)." ".$this->secure->checkStr($dist["version"],1)." ".$this->secure->checkStr($dist["vname"],1)."\n"; |
$show .= "# Этот sources.list сгенерирован при помощи ".$this->getEngineAttr('codename')." ".$this->getEngineAttr('version')."\n"; |
$show .= "# Адрес проекта: http://alex-w.org.ru/p/ant-ng/\n\n"; |
// Извлекаем информацию о репозиториях и строим sources.list |
if ($dist["type"]=="deb") { |
// Базовый репозиторий |
$query = "SELECT * FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."protos p ON r.proto_id=p.proto_id "; |
$query .= "JOIN ".$this->prefix."rephost h ON r.rhost_id=h.rhost_id "; |
$query .= "JOIN ".$this->prefix."repfolder f ON r.rfolder_id=f.rfolder_id "; |
$query .= "JOIN ".$this->prefix."version v ON r.version=v.version_id "; |
$query .= "JOIN ".$this->prefix."rtype t ON r.rtype_id=t.rtype_id "; |
$query .= "JOIN ".$this->prefix."repscheme s ON r.scheme_id=s.scheme_id "; |
$query .= "WHERE v.version_id='".$data["version_id"]."' AND r.rtype_id='1'"; |
$rq =& $this->db->query($query); |
if ($rq->numRows()>0) { |
$rq->fetchInto($base); |
// Формируем type proto://host/folder |
$show .= "# ".$this->secure->checkStr($base["repinfo"],1)."\n"; |
if ($base["repkey"]!="") { |
$show .= "# Установка ключа: ".$this->secure->checkStr($base["repkey"],1)."\n"; |
} |
$show .= $this->secure->checkStr($dist["type"],1)." ".$this->secure->checkStr($base["proto"],1).$this->secure->checkStr($base["rhost"],1).$this->secure->checkStr($base["rfolder"],1); |
$dvname = str_replace("{DIST}",$this->secure->checkStr($dist["vcodename"],1),$this->secure->checkStr($base["scheme"],1)); |
// Формируем distname |
$show .= " ".$dvname." "; |
// Формируем sections |
$query = "SELECT * FROM ".$this->prefix."section s "; |
$query .= "JOIN ".$this->prefix."sect2rep r ON s.sect_id=r.sect_id "; |
$query .= "WHERE r.rep_id='".$base["rep_id"]."' AND ("; |
for($i=0;$i<count($data["section"]);$i++) { |
$query .= "s.sect_id='".$data["section"][$i]."' "; |
if ($i<count($data["section"])-1) { |
$query .= " OR "; |
} |
} |
$query .= ")"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($sections)) { |
$show .= $sections["secname"]." "; |
} |
$show .= "\n\n"; |
} |
if (count($data["repository"])>0) { |
// Репозитории обновлений и третьих лиц |
$query = "SELECT * FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."protos p ON r.proto_id=p.proto_id "; |
$query .= "JOIN ".$this->prefix."rephost h ON r.rhost_id=h.rhost_id "; |
$query .= "JOIN ".$this->prefix."repfolder f ON r.rfolder_id=f.rfolder_id "; |
$query .= "JOIN ".$this->prefix."version v ON r.version=v.version_id "; |
$query .= "JOIN ".$this->prefix."rtype t ON r.rtype_id=t.rtype_id "; |
$query .= "JOIN ".$this->prefix."repscheme s ON r.scheme_id=s.scheme_id "; |
$query .= "WHERE r.rtype_id>'1' AND ("; |
for($i=0;$i<count($data["repository"]);$i++) { |
$query .= "r.rep_id='".$data["repository"][$i]."' "; |
if ($i<count($data["repository"])-1) { |
$query .= " OR "; |
} |
} |
$query .= ") ORDER BY r.rtype_id ASC"; |
$req =& $this->db->query($query); |
while ($req->fetchInto($updates)) { |
// Формируем type proto://host/folder |
$show .= "# ".$this->secure->checkStr($updates["repinfo"],1)."\n"; |
if ($updates["repkey"]!="") { |
$show .= "# Установка ключа: ".$this->secure->checkStr($updates["repkey"],1)."\n"; |
} |
$show .= $this->secure->checkStr($dist["type"],1)." ".$this->secure->checkStr($updates["proto"],1).$this->secure->checkStr($updates["rhost"],1).$this->secure->checkStr($updates["rfolder"],1); |
$dvname = str_replace("{DIST}",$this->secure->checkStr($dist["vcodename"],1),$this->secure->checkStr($updates["scheme"],1)); |
// Формируем distname |
$show .= " ".$dvname." "; |
// Формируем sections |
$query = "SELECT * FROM ".$this->prefix."section s "; |
$query .= "JOIN ".$this->prefix."sect2rep r ON s.sect_id=r.sect_id "; |
$query .= "WHERE r.rep_id='".$updates["rep_id"]."'"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($sections)) { |
$show .= $sections["secname"]." "; |
} |
$show .= "\n\n"; |
} |
$show .= "\n"; |
} |
} else { |
// Базовый репозиторий |
$query = "SELECT * FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."protos p ON r.proto_id=p.proto_id "; |
$query .= "JOIN ".$this->prefix."rephost h ON r.rhost_id=h.rhost_id "; |
$query .= "JOIN ".$this->prefix."repfolder f ON r.rfolder_id=f.rfolder_id "; |
$query .= "JOIN ".$this->prefix."version v ON r.version=v.version_id "; |
$query .= "JOIN ".$this->prefix."rtype t ON r.rtype_id=t.rtype_id "; |
$query .= "JOIN ".$this->prefix."repscheme s ON r.scheme_id=s.scheme_id "; |
$query .= "WHERE v.version_id='".$data["version_id"]."' AND r.rtype_id='1'"; |
$rq =& $this->db->query($query); |
if ($rq->numRows()>0) { |
$rq->fetchInto($base); |
// Формируем type proto://host/folder |
$show .= "# ".$this->secure->checkStr($base["repinfo"],1)."\n"; |
$show .= $this->secure->checkStr($dist["type"],1)." "; |
if ($base["sign_id"]!=0) { |
$query = "SELECT * FROM ".$this->prefix."signs WHERE sign_id='".$base["sign_id"]."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($sign); |
$show .= "[".$this->secure->checkStr($sign["sname"],1)."] "; |
} |
$show .= $this->secure->checkStr($base["proto"],1).$this->secure->checkStr($base["rhost"],1).$this->secure->checkStr($base["rfolder"],1)." "; |
$show .= $this->secure->checkStr($base["scheme"],1)." "; |
// Формируем sections |
$query = "SELECT * FROM ".$this->prefix."section s "; |
$query .= "JOIN ".$this->prefix."sect2rep r ON s.sect_id=r.sect_id "; |
$query .= "WHERE r.rep_id='".$base["rep_id"]."' AND ("; |
for($i=0;$i<count($data["section"]);$i++) { |
$query .= "s.sect_id='".$data["section"][$i]."' "; |
if ($i<count($data["section"])-1) { |
$query .= " OR "; |
} |
} |
$query .= ")"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($sections)) { |
$show .= $sections["secname"]." "; |
} |
$show .= "\n\n"; |
} |
if (count($data["repository"])>0) { |
// Репозитории обновлений и третьих лиц |
$query = "SELECT * FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."protos p ON r.proto_id=p.proto_id "; |
$query .= "JOIN ".$this->prefix."rephost h ON r.rhost_id=h.rhost_id "; |
$query .= "JOIN ".$this->prefix."repfolder f ON r.rfolder_id=f.rfolder_id "; |
$query .= "JOIN ".$this->prefix."version v ON r.version=v.version_id "; |
$query .= "JOIN ".$this->prefix."rtype t ON r.rtype_id=t.rtype_id "; |
$query .= "JOIN ".$this->prefix."repscheme s ON r.scheme_id=s.scheme_id "; |
$query .= "WHERE r.rtype_id>'1' AND ("; |
for($i=0;$i<count($data["repository"]);$i++) { |
$query .= "r.rep_id='".$data["repository"][$i]."' "; |
if ($i<count($data["repository"])-1) { |
$query .= " OR "; |
} |
} |
$query .= ") ORDER BY r.rtype_id ASC"; |
$req =& $this->db->query($query); |
while ($req->fetchInto($updates)) { |
// Формируем type proto://host/folder |
$show .= "# ".$this->secure->checkStr($updates["repinfo"],1)."\n"; |
$show .= $this->secure->checkStr($dist["type"],1)." "; |
if ($updates["sign_id"]!=0) { |
$query = "SELECT * FROM ".$this->prefix."signs WHERE sign_id='".$base["sign_id"]."'"; |
$rqs =& $this->db->query($query); |
$rqs->fetchInto($sign); |
$show .= "[".$this->secure->checkStr($sign["sname"],1)."] "; |
} |
$show .= $this->secure->checkStr($updates["proto"],1).$this->secure->checkStr($updates["rhost"],1).$this->secure->checkStr($updates["rfolder"],1)." "; |
$show .= $this->secure->checkStr($updates["scheme"],1)." "; |
// Формируем sections |
$query = "SELECT * FROM ".$this->prefix."section s "; |
$query .= "JOIN ".$this->prefix."sect2rep r ON s.sect_id=r.sect_id "; |
$query .= "WHERE r.rep_id='".$updates["rep_id"]."'"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($sections)) { |
$show .= $sections["secname"]." "; |
} |
$show .= "\n\n"; |
} |
$show .= "\n"; |
} |
} |
$HTTPHeader1 = "Content-length: ".strlen($show); |
$HTTPHeader2 = "Content-disposition: attachment; filename=sources.list\n\n"; |
header($HTTPHeader1); |
header($HTTPHeader2); |
return $show; |
} |
/** |
* Показывает список секций |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showSectionsList($name, $actor, $format = 'html') { |
switch($format) { |
case 'html': |
$query = "SELECT * FROM ".$this->prefix."section"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["sect_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["sect_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["secname"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$show = ""; |
$repID = $this->secure->checkInt($actor); |
if ($repID==0) { |
$query = "SELECT * FROM ".$this->prefix."section"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["sect_id"]."'> ".$this->secure->checkStr($element["secname"],1)." "; |
} |
} else { |
$query = "SELECT * FROM ".$this->prefix."section s JOIN ".$this->prefix."sect2rep r ON s.sect_id=r.sect_id WHERE r.rep_id='$repID'"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["sect_id"]."' checked> ".$this->secure->checkStr($element["secname"],1)." "; |
} |
$query = "SELECT s.* FROM ".$this->prefix."section s WHERE s.sect_id NOT IN (SELECT sect_id FROM ".$this->prefix."sect2rep WHERE rep_id='$repID')"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["sect_id"]."'> ".$this->secure->checkStr($element["secname"],1)." "; |
} |
} |
break; |
} |
return $show; |
} |
/** |
* Вывод формы редактирования/добавления секций |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @param string $info |
* @return string |
*/ |
public function showSectionsForm($sectionID = 0, $info = "") { |
$sSectID = $this->secure->checkInt($sectionID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Секция"; |
} |
if ($sSectID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."section WHERE sect_id='".$sSectID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='sname'>Название секции:</label> <input type='text' name='sname' id='sname' value='".$this->secure->checkStr($element["secname"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='sinfo'>Описание секции:</label> <input type='text' name='sinfo' id='sinfo' value='".$this->secure->checkStr($element["sectinfo"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Обновление информации о секции |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @param string $sname |
* @param string $sinfo |
* @return array |
*/ |
public function updateSection($sectionID, $sname, $sinfo = "") { |
$result = array(); |
$sSectID = $this->secure->checkInt($sectionID); |
$sSName = $this->secure->checkStr($sname); |
$sSInfo = $this->secure->checkStr($sinfo); |
$query = "UPDATE ".$this->prefix."section SET secname='".$sSName."', sectinfo='".$sSInfo."' WHERE sect_id='".$sSectID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о секции |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @return array |
*/ |
public function dropSection($sectionID) { |
$result = array(); |
$sSectID = $this->secure->checkInt($sectionID); |
// Удаление секции |
$query = "DELETE FROM ".$this->prefix."section WHERE sect_id='".$sSectID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Добавление новой секции |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $sname |
* @param string $sinfo |
* @return array |
*/ |
public function addSection($sname, $sinfo = "") { |
$result = array(); |
$sSName = $this->secure->checkStr($sname); |
$sSInfo = $this->secure->checkStr($sinfo); |
$query = "INSERT INTO ".$this->prefix."section SET secname='".$sSName."', sectinfo='".$sSInfo."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод списка поддерживаемых архитектур |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showArchList($name, $actor, $format = 'list') { |
switch($format) { |
case 'list': |
$query = "SELECT * FROM ".$this->prefix."arch"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["arch_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["arch_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["arch"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$show = ""; |
$repID = $this->secure->checkInt($actor); |
if ($repID==0) { |
$query = "SELECT * FROM ".$this->prefix."arch"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["arch_id"]."'> ".$this->secure->checkStr($element["arch"],1)." "; |
} |
} else { |
$query = "SELECT * FROM ".$this->prefix."arch a JOIN ".$this->prefix."arch2rep r ON a.arch_id=r.arch_id WHERE r.rep_id='$repID'"; |
$rq =& $this->db->query($query); |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["arch_id"]."' checked> ".$this->secure->checkStr($element["arch"],1)." "; |
} |
$query = "SELECT a.* FROM ".$this->prefix."arch a WHERE a.arch_id NOT IN (SELECT arch_id FROM ".$this->prefix."arch2rep WHERE rep_id='$repID')"; |
$rq =& $this->db->query($query); |
if ($rq->numRows()>0) { |
while ($rq->fetchInto($element)) { |
$show .= "<input type='checkbox' name='".$name."[]' value='".$element["arch_id"]."'> ".$this->secure->checkStr($element["arch"],1)." "; |
} |
} |
} |
break; |
} |
return $show; |
} |
/** |
* Добавление новой архитектуры |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $arch |
* @return array |
*/ |
public function addArch($arch) { |
$result = array(); |
$sArch = $this->secure->checkStr($arch); |
$query = "INSERT INTO ".$this->prefix."arch SET arch='".$sArch."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации об архитектуре |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $archID |
* @return array |
*/ |
public function dropArch($archID) { |
$result = array(); |
$sArchID = $this->secure->checkInt($archID); |
// Удаление архитектуры |
$query = "DELETE FROM ".$this->prefix."arch WHERE arch_id='".$sArchID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
// Удаление архитектуры из списка репозиториев |
$query = "DELETE FROM ".$this->prefix."arch2rep WHERE arch_id='".$sArchID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации об архитектуре |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $archID |
* @param string $arch |
* @return array |
*/ |
public function updateArch($archID, $arch) { |
$result = array(); |
$sArchID = $this->secure->checkInt($archID); |
$sArch = $this->secure->checkStr($arch); |
$query = "UPDATE ".$this->prefix."arch SET arch='".$sArch."' WHERE arch_id='".$sArchID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод формы редактирования/добавления архитектур |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $archID |
* @param string $info |
* @return string |
*/ |
public function showArchForm($archID = 0, $info = "") { |
$sArchID = $this->secure->checkInt($archID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Архитектура"; |
} |
if ($sArchID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."arch WHERE arch_id='".$sArchID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='arch'>Архитектура:</label> <input type='text' name='arch' id='arch' value='".$this->secure->checkStr($element["arch"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Вывод списка схем репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showSchemeList($name, $actor, $format = 'list') { |
switch($format) { |
case 'list': |
$query = "SELECT * FROM ".$this->prefix."repscheme"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["scheme_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["scheme_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["scheme"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$schemeID = $this->secure->checkInt($actor); |
$query = "SELECT * FROM ".$this->prefix."repscheme"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["scheme_id"]==$schemeID) { |
$show .= "<option value='".$this->secure->checkInt($element["scheme_id"])."' selected>".$this->secure->checkStr($element["scheme"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["scheme_id"])."'>".$this->secure->checkStr($element["scheme"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
break; |
} |
return $show; |
} |
/** |
* Добавление новой схемы репозитория |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $scheme |
* @return array |
*/ |
public function addScheme($scheme) { |
$result = array(); |
$sScheme = $this->secure->checkStr($scheme); |
$query = "INSERT INTO ".$this->prefix."repscheme SET scheme='".$sScheme."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о схеме репозитория |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $schemeID |
* @return array |
*/ |
public function dropScheme($schemeID) { |
$result = array(); |
$sSchemeID = $this->secure->checkInt($schemeID); |
// Удаление схемы |
$query = "DELETE FROM ".$this->prefix."repscheme WHERE scheme_id='".$sSchemeID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о схеме репозитория |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $schemeID |
* @param string $info |
* @return array |
*/ |
public function updateScheme($schemeID, $info) { |
$result = array(); |
$sSchemeID = $this->secure->checkInt($schemeID); |
$sScheme = $this->secure->checkStr($info); |
$query = "UPDATE ".$this->prefix."repscheme SET scheme='".$sScheme."' WHERE scheme_id='".$sSchemeID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод формы редактирования/добавления схем репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $schemeID |
* @param string $info |
* @return string |
*/ |
public function showSchemeForm($schemeID = 0, $info = "") { |
$sSchemeID = $this->secure->checkInt($schemeID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Схема репозитория"; |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
if ($sSchemeID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."repscheme WHERE scheme_id='".$sSchemeID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show .= "<div class='inputbox'><label for='scheme'>Схема репозитория:</label> <input type='text' name='scheme' id='scheme' value='".$this->secure->checkStr($element["scheme"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Вывод списка протоколов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showProtoList($name, $actor, $format = 'list') { |
switch($format) { |
case 'list': |
$query = "SELECT * FROM ".$this->prefix."protos"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["proto_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["proto_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["proto"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$protoID = $this->secure->checkInt($actor); |
$query = "SELECT * FROM ".$this->prefix."protos"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["proto_id"]==$protoID) { |
$show .= "<option value='".$this->secure->checkInt($element["proto_id"])."' selected>".$this->secure->checkStr($element["proto"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["proto_id"])."'>".$this->secure->checkStr($element["proto"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
break; |
} |
return $show; |
} |
/** |
* Добавление нового протокола |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $proto |
* @return array |
*/ |
public function addProto($proto) { |
$result = array(); |
$sProto = $this->secure->checkStr($proto); |
$query = "INSERT INTO ".$this->prefix."protos SET proto='".$sProto."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о протоколе |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $protoID |
* @return array |
*/ |
public function dropProto($protoID) { |
$result = array(); |
$sProtoID = $this->secure->checkInt($protoID); |
// Удаление протокола |
$query = "DELETE FROM ".$this->prefix."protos WHERE proto_id='".$sProtoID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о протоколе |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $protoID |
* @param string $info |
* @return array |
*/ |
public function updateProto($protoID, $info) { |
$result = array(); |
$sProtoID = $this->secure->checkInt($protoID); |
$sProto = $this->secure->checkStr($info); |
$query = "UPDATE ".$this->prefix."protos SET proto='".$sProto."' WHERE proto_id='".$sProtoID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод формы редактирования/добавления протоколов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $protoID |
* @param string $info |
* @return string |
*/ |
public function showProtoForm($protoID = 0, $info = "") { |
$sProtoID = $this->secure->checkInt($protoID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Протокол доступа"; |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
if ($sProtoID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."protos WHERE proto_id='".$sProtoID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show .= "<div class='inputbox'><label for='proto'>Протокол доступа:</label> <input type='text' name='proto' id='proto' value='".$this->secure->checkStr($element["proto"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Вывод списка хостов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showHostsList($name, $actor, $format = 'list') { |
switch($format) { |
case 'list': |
$query = "SELECT * FROM ".$this->prefix."rephost"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["rhost_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["rhost_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["rhost"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$hostID = $this->secure->checkInt($actor); |
$query = "SELECT * FROM ".$this->prefix."rephost"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["rhost_id"]==$hostID) { |
$show .= "<option value='".$this->secure->checkInt($element["rhost_id"])."' selected>".$this->secure->checkStr($element["rhost"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["rhost_id"])."'>".$this->secure->checkStr($element["rhost"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
break; |
} |
return $show; |
} |
/** |
* Добавление нового хоста |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $host |
* @return array |
*/ |
public function addHost($host) { |
$result = array(); |
$sHost = $this->secure->checkStr($host); |
$query = "INSERT INTO ".$this->prefix."rephost SET rhost='".$sHost."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о хосте |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $hostID |
* @return array |
*/ |
public function dropHost($hostID) { |
$result = array(); |
$sHostID = $this->secure->checkInt($hostID); |
// Удаление хоста |
$query = "DELETE FROM ".$this->prefix."rephost WHERE rhost_id='".$sHostID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о хосте |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $hostID |
* @param string $info |
* @return array |
*/ |
public function updateHost($hostID, $info) { |
$result = array(); |
$sHostID = $this->secure->checkInt($hostID); |
$sHost = $this->secure->checkStr($info); |
$query = "UPDATE ".$this->prefix."rephost SET rhost='".$sHost."' WHERE rhost_id='".$sHostID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод формы редактирования/добавления хостов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $hostID |
* @param string $info |
* @return string |
*/ |
public function showHostForm($hostID = 0, $info = "") { |
$sHostID = $this->secure->checkInt($hostID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Хост репозитория"; |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
if ($sHostID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."rephost WHERE rhost_id='".$sHostID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show .= "<div class='inputbox'><label for='rhost'>Хост репозитория:</label> <input type='text' name='rhost' id='rhost' value='".$this->secure->checkStr($element["rhost"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Вывод списка корневых папок |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showFoldersList($name, $actor, $format = 'list') { |
switch($format) { |
case 'list': |
$query = "SELECT * FROM ".$this->prefix."repfolder"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["rfolder_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["rfolder_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["rfolder"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$folderID = $this->secure->checkInt($actor); |
$query = "SELECT * FROM ".$this->prefix."repfolder"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["rfolder_id"]==$folderID) { |
$show .= "<option value='".$this->secure->checkInt($element["rfolder_id"])."' selected>".$this->secure->checkStr($element["rfolder"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["rfolder_id"])."'>".$this->secure->checkStr($element["rfolder"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
break; |
} |
return $show; |
} |
/** |
* Добавление нового корневого каталога |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $flder |
* @return array |
*/ |
public function addFolder($folder) { |
$result = array(); |
$sFolder = $this->secure->checkStr($folder); |
$query = "INSERT INTO ".$this->prefix."repfolder SET rfolder='".$sFolder."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о корневой папке |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $folderID |
* @return array |
*/ |
public function dropFolder($folderID) { |
$result = array(); |
$sFolderID = $this->secure->checkInt($folderID); |
// Удаление корневой папки |
$query = "DELETE FROM ".$this->prefix."repfolder WHERE rfolder_id='".$sFolderID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о корневой папки |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $folderID |
* @param string $info |
* @return array |
*/ |
public function updateFolder($folderID, $info) { |
$result = array(); |
$sFolderID = $this->secure->checkInt($folderID); |
$sFolder = $this->secure->checkStr($info); |
$query = "UPDATE ".$this->prefix."repfolder SET rfolder='".$sFolder."' WHERE rfolder_id='".$sFolderID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод формы редактирования/добавления корневых папок |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $folderID |
* @param string $info |
* @return string |
*/ |
public function showFolderForm($folderID = 0, $info = "") { |
$sFolderID = $this->secure->checkInt($folderID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Корневая папка"; |
} |
if ($sFolderID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."repfolder WHERE rfolder_id='".$sFolderID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='rfolder'>Корневая папка:</label> <input type='text' name='rfolder' id='rfolder' value='".$this->secure->checkStr($element["rfolder"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Показывает список подписей |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showSignsList($name, $actor, $format = 'list') { |
$query = "SELECT * FROM ".$this->prefix."signs"; |
$rq =& $this->db->query($query); |
switch ($format) { |
case 'list': |
$show = "<ul>\n"; |
while ($rq->fetchInto($element)) { |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$element["sign_id"]."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$element["sign_id"]."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["sname"],1)."</li>\n"; |
} |
$show .= "</ul>"; |
break; |
case 'innerhtml': |
$signID = $this->secure->checkInt($actor); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
$show .= "<option value='0'>Подписи нет</option>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["sign_id"]==$signID) { |
$show .= "<option value='".$this->secure->checkInt($element["sign_id"])."' selected>".$this->secure->checkStr($element["sname"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["sign_id"])."'>".$this->secure->checkStr($element["sname"],1)."</option>\n"; |
} |
} |
$show .= "</select>\n"; |
break; |
} |
return $show; |
} |
/** |
* Вывод формы редактирования/добавления подписей |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @param string $info |
* @return string |
*/ |
public function showSignsForm($signID = 0, $info = "") { |
$sSignID = $this->secure->checkInt($signID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Подписи"; |
} |
if ($sSignID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."signs WHERE sign_id='".$sSignID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='sname'>Название подписи:</label> <input type='text' name='sname' id='sname' value='".$this->secure->checkStr($element["sname"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='sinfo'>Описание подписи:</label> <input type='text' name='sinfo' id='sinfo' value='".$this->secure->checkStr($element["sinfo"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div>\n</fieldset>\n"; |
return $show; |
} |
/** |
* Обновление информации о секции |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @param string $sname |
* @param string $sinfo |
* @return array |
*/ |
public function updateSign($signID, $sname, $sinfo = "") { |
$result = array(); |
$sSignID = $this->secure->checkInt($signID); |
$sSName = $this->secure->checkStr($sname); |
$sSInfo = $this->secure->checkStr($sinfo); |
$query = "UPDATE ".$this->prefix."signs SET sname='".$sSName."', sinfo='".$sSInfo."' WHERE sign_id='".$sSignID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о подписи |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $sectionID |
* @return array |
*/ |
public function dropSign($signID) { |
$result = array(); |
$sSignID = $this->secure->checkInt($signID); |
// Удаление подписи |
$query = "DELETE FROM ".$this->prefix."signs WHERE sign_id='".$sSignID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Добавление новой подписи |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $sname |
* @param string $sinfo |
* @return array |
*/ |
public function addSign($sname, $sinfo = "") { |
$result = array(); |
$sSName = $this->secure->checkStr($sname); |
$sSInfo = $this->secure->checkStr($sinfo); |
$query = "INSERT INTO ".$this->prefix."signs SET sname='".$sSName."', sinfo='".$sSInfo."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Проверка пароля (из формы авторизации) |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $word |
* @return array |
*/ |
public function checkSign($word) { |
$result = array(); |
$sHash = $this->secure->encryptStr($word); |
$pwd = $this->getOption("passwd"); |
if ($sHash == $pwd["OptValue"]) { |
$result["ERR"] = 0; |
$result["Location"] = "manager.php"; |
setcookie($this->cookie, $sHash); |
} else { |
$result["ERR"] = 1; |
$result["ERRINFO"] = "Password not valid"; |
$result["Location"] = "manager.php?error=1"; |
} |
return $result; |
} |
/** |
* Проверка пароля (из cookies) |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $hash |
* @return array |
*/ |
public function checkCookieSign($hash) { |
$result = array(); |
$pwd = $this->getOption("passwd"); |
if ($hash == $pwd["OptValue"]) { |
$result["ERR"] = 0; |
} else { |
$result["ERR"] = 1; |
$result["ERRINFO"] = "Hash not valid"; |
$result["Location"] = "manager.php"; |
} |
return $result; |
} |
/** |
* Форма ввода пароля |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @return string |
*/ |
public function showSigninForm() { |
$show = "<div id='regform'>"; |
$show .= "<form action='process.php' method='post'>\n"; |
$show .= "<fieldset><legend>Пароль</legend>\n"; |
$show .= "<input type='hidden' name='mode' value='authorize'>\n"; |
$show .= "<input type='password' name='word' value=''>\n"; |
$show .= "<input type='submit' value=' Войти '>\n"; |
$show .= "</fieldset>\n</form></div>\n"; |
return $show; |
} |
/** |
* Обновление пароля |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $word1 |
* @param string $word2 |
* @return array |
*/ |
public function updatePassword($word1, $word2) { |
$result = array(); |
if ($word1 == $word2) { |
$sWord = $this->secure->encryptStr($word1); |
$r = $this->setOption("passwd", $sWord); |
$result = $r; |
} else { |
$result["ERR"] = 1; |
$result["ERRINFO"] = "Passwords is mismatch"; |
} |
return $result; |
} |
/** |
* Отображение формы создания и редактирования версии apt-дистрибутива |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param integer $versionID |
* @return string |
*/ |
public function showDistVersionsForm($versionID = 0, $info = '') { |
$sVersionID = $this->secure->checkInt($versionID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Версия дистрибутива"; |
} |
if ($sVersionID != 0) { |
// Режим редактирования |
$query = "SELECT * FROM ".$this->prefix."version v JOIN ".$this->prefix."distribution d ON v.dist_id=d.dist_id WHERE v.version_id='".$sVersionID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
if ($sVersionID != 0) { |
$show .= "<div class='inputbox'><label for='distname'>Дистрибутив:</label> <input type='text' name='distname' value='".$this->secure->checkStr($element["distname"],1)."' readonly='readonly'></div>\n"; |
} else { |
$show .= "<div class='inputbox'><label for='distname'>Дистрибутив:</label> ".$this->showDistributionList("distname", "", "", "innerhtml")."</div>\n"; |
} |
$show .= "<div class='inputbox'><label for='vname'>Название версии:</label> <input type='text' name='vname' value='".$this->secure->checkStr($element["vname"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='version'>Номер версии:</label> <input type='text' name='version' value='".$this->secure->checkStr($element["version"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><label for='vcodename'>Кодовое имя версии:</label> <input type='text' name='vcodename' value='".$this->secure->checkStr($element["vcodename"],1)."'></div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div></fieldset>\n"; |
return $show; |
} |
/** |
* Парсер схемы адреса репозитория |
* FIXME Возможно не потребуется |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $repstring |
* @return integer |
*/ |
public function repositoryParser($repstring) { |
$tokens = array(); |
$sections = array(); |
$tokens = split(" ",$repstring); |
if ($tokens[0] == "deb") { |
// debian/ubuntu репозиторий "type proto://host/folder distr sections" |
$url = parse_url($tokens[1]); |
$distr = $tokens[2]; |
for($i=3;$i<count($tokens);$i++) { |
$sections[] = $tokens[$i]; |
} |
} else { |
// altlinux репозиторий "type [sign] proto://host/folder base repname" |
if (stripos($tokens[1],"]")!=0) { |
$sign = $tokens[1]; |
$url = parse_url($tokens[2]); |
$base = $tokens[3]; |
$repname = $tokens[4]; |
} else { |
$url = parse_url($tokens[1]); |
$base = $tokens[2]; |
$repname = $tokens[3]; |
} |
} |
$proto = $url["scheme"]."://"; |
$addr = $url["host"]; |
if ($url["port"]!="") { |
$addr .= ":".$url["port"]; |
} |
$path = $url["path"]; |
return 0; |
} |
/** |
* Выгрузка картинок логотипов дистрибутивов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $path |
* @param string $dist |
* @param array $datafile |
* @return integer |
*/ |
public function uploadPicture($path, $dist, $datafile) { |
$folder = $path.$dist."-orig.png"; |
$folderN = $path.$dist.".png"; |
$folderEM = $path.$dist."-em.png"; |
$distlogo = 0; |
if (move_uploaded_file($datafile["distlogo"]["tmp_name"],$folder)) { |
chmod($folder, 0644); |
list($width, $height) = GetImageSize($folder); |
$percent = 32/$height; |
$newwidth = $width * $percent; |
$newheight = $height * $percent; |
$output = ImageCreateTrueColor($newwidth, $newheight); |
$source = ImageCreateFromPNG($folder); |
ImageCopyResampled($output, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); |
ImagePNG($output, $folderEM); |
$percent = 15/$height; |
$newwidth = $width * $percent; |
$newheight = $height * $percent; |
$output = ImageCreateTrueColor($newwidth, $newheight); |
ImageCopyResized($output, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); |
ImagePNG($output, $folderN); |
unlink($folder); |
$distlogo = 1; |
} |
return $distlogo; |
} |
/** |
* Показ списка репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showRepositoriesList($name, $actor, $format = 'list') { |
$query = "SELECT r.*,rt.*,v.version_id,CONCAT(d.distname,' ',v.version,' “',v.vname,'”') AS fullname FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."rtype rt ON rt.rtype_id=r.rtype_id "; |
$query .= "JOIN ".$this->prefix."version v ON v.version_id=r.version "; |
$query .= "JOIN ".$this->prefix."distribution d ON d.dist_id=v.dist_id "; |
$query .= "ORDER BY v.version_id,rt.rtype_id,r.rep_id ASC"; |
$rq =& $this->db->query($query); |
$show = "<ul><li class='nomarker'></li>"; |
$splitter = 0; |
while ($rq->fetchInto($element)) { |
if ($splitter != $this->secure->checkInt($element["version_id"])) { |
$splitter = $this->secure->checkInt($element["version_id"]); |
$show .= "</ul><ul><li class='nomarker'><strong>Репозитории для ".$this->secure->checkStr($element["fullname"],1)."</strong></li>"; |
} |
$show .= "<li>[<a href='".$actor."?mode=".$name."&action=edit&uuid=".$this->secure->checkInt($element["rep_id"])."' class='edit'>править</a>][<a href='".$actor."?mode=".$name."&action=delete&uuid=".$this->secure->checkInt($element["rep_id"])."' class='delete'>удалить</a>] ".$this->secure->checkStr($element["repname"],1)." (<em>".$this->secure->checkStr($element["rtype"],1)."</em>)</li>\n"; |
} |
$show .= "</ul>"; |
return $show; |
} |
/** |
* Вывод списка типов репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $reptype |
* @param string $name |
* @return string |
*/ |
public function showRepType($reptype = 0, $name = "") { |
$sRT = $this->secure->checkInt($reptype); |
$sNM = $this->secure->checkStr($name,1); |
$query = "SELECT * FROM ".$this->prefix."rtype"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$sNM."' id='".$sNM."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["rtype_id"]==$sRT) { |
$show .= "<option value='".$this->secure->checkInt($element["rtype_id"])."' selected>".$this->secure->checkStr($element["rtype"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["rtype_id"])."'>".$this->secure->checkStr($element["rtype"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
return $show; |
} |
/** |
* Вывод списка версий дистрибутивов |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param integer $versionID |
* @return string |
*/ |
public function showVDList($name, $versionID = 0) { |
$query = "SELECT v.version_id, CONCAT(d.distname, ' ', v.version, ' ', v.vname) AS fullname FROM ".$this->prefix."version v "; |
$query .= "JOIN ".$this->prefix."distribution d ON v.dist_id=d.dist_id"; |
$rq =& $this->db->query($query); |
$show = "<select name='".$name."' id='".$name."'>\n"; |
while ($rq->fetchInto($element)) { |
if ($element["version_id"]==$versionID) { |
$show .= "<option value='".$this->secure->checkInt($element["version_id"])."' selected>".$this->secure->checkStr($element["fullname"],1)."</option>\n"; |
} else { |
$show .= "<option value='".$this->secure->checkInt($element["version_id"])."'>".$this->secure->checkStr($element["fullname"],1)."</option>\n"; |
} |
} |
$show .= "</select>"; |
return $show; |
} |
/** |
* Форма создания/редактирвоания репозиториев |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $repID |
* @param string $info |
* @param string $reptype |
* @return string |
*/ |
public function showRepositoriesForm($repID = 0, $info = "") { |
$sRepID = $this->secure->checkInt($repID); |
$sInfo = $this->secure->checkStr($info, 1); |
if ($sInfo == "") { |
$sInfo = "Репозиторий"; |
} |
if ($sRepID != 0) { |
// Режим редактирования |
$query = "SELECT r.*,v.*,d.dist_id,dt.type FROM ".$this->prefix."repository r "; |
$query .= "JOIN ".$this->prefix."version v ON r.version=v.version_id "; |
$query .= "JOIN ".$this->prefix."distribution d ON v.dist_id=d.dist_id "; |
$query .= "JOIN ".$this->prefix."dtype dt ON d.disttype=dt.type_id "; |
$query .= "WHERE r.rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($element); |
} |
$show = "<fieldset><legend>".$sInfo."</legend>\n"; |
$show .= "<div class='inputbox'><label for='rdist'>Дистрибутив:</label> ".$this->showVDList("rdist",$this->secure->checkInt($element["version_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rname'>Название репозитория:</label> <input type='text' name='rname' value=\"".$this->secure->checkStr($element["repname"],1)."\"></div>\n"; |
$show .= "<div class='inputbox'><label for='rinfo'>Описание репозитория:</label> <input type='text' name='rinfo' value=\"".$this->secure->checkStr($element["repinfo"],1)."\"></div>\n"; |
$show .= "<div class='inputbox'><label for='rkey'>Ключ подписи репозитория:</label> <input type='text' name='rkey' value=\"".$this->secure->checkStr($element["repkey"],1)."\"></div>\n"; |
$show .= "<div class='inputbox'><label for='rproto'>Протокол доступа:</label> ".$this->showProtoList("rproto",$this->secure->checkInt($element["proto_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rhost'>Хост репозитория:</label> ".$this->showHostsList("rhost",$this->secure->checkInt($element["rhost_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rfolder'>Корневая папка:</label> ".$this->showFoldersList("rfolder",$this->secure->checkInt($element["rfolder_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rtype'>Тип репозитория:</label> ".$this->showRepType($this->secure->checkInt($element["rtype_id"]), "rtype")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rsects'>Секции репозитория:</label> <div class='formwrapper'>".$this->showSectionsList("rsects",$sRepID,"innerhtml")."</div></div>\n"; |
$show .= "<div class='inputbox'><label for='rarchs'>Архитектуры:</label> <div class='formwrapper'>".$this->showArchList("rarchs",$sRepID,"innerhtml")."</div></div>\n"; |
$show .= "<div class='inputbox'><label for='rscheme'>Схема репозитория:</label> ".$this->showSchemeList("rscheme",$this->secure->checkInt($element["scheme_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><label for='rsign'>Подпись репозитория:</label> ".$this->showSignsList("rsign",$this->secure->checkInt($element["sign_id"]),"innerhtml")."</div>\n"; |
$show .= "<div class='inputbox'><input type='submit' value=' Отправить данные '></div></fieldset>\n"; |
return $show; |
} |
/** |
* Добавление нового репозитория |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $verionID |
* @param string $rname |
* @param string $rinfo |
* @param string $rkey |
* @param integer $proto |
* @param integer $rhost |
* @param integer $rfolder |
* @param integer $rtype |
* @param array $sections |
* @param array $arch |
* @param integer $scheme |
* @param integer $sign |
* @return array |
*/ |
public function addRepository($verionID, $rname, $rinfo, $rkey, $proto, $rhost, $rfolder, $rtype, $scheme, $sign, $sections, $arch) { |
$result = array(); |
$sVersionID = $this->secure->checkInt($verionID); |
$sRName = $this->secure->checkStr($rname); |
$sRInfo = $this->secure->checkStr($rinfo); |
$sRKey = $this->secure->checkStr($rkey); |
$sProto = $this->secure->checkInt($proto); |
$sRHost = $this->secure->checkInt($rhost); |
$sRFolder = $this->secure->checkInt($rfolder); |
$sRType = $this->secure->checkInt($rtype); |
$sRScheme = $this->secure->checkInt($scheme); |
$sRSign = $this->secure->checkInt($sign); |
$query = "INSERT INTO ".$this->prefix."repository SET proto_id='".$sProto."', rhost_id='".$sRHost."', rfolder_id='".$sRFolder."', version='".$sVersionID."', rtype_id='".$sRType."', scheme_id='".$sRScheme."', sign_id='".$sRSign."', repname='".$sRName."', repinfo='".$sRInfo."', repkey='".$sRKey."'"; |
$rq =& $this->db->query($query); |
$query = "SELECT rep_id FROM ".$this->prefix."repository ORDER BY rep_id DESC LIMIT 0, 1"; |
$rq =& $this->db->query($query); |
$rq->fetchInto($repository); |
for($i=0;$i<count($sections);$i++) { |
$query = "INSERT INTO ".$this->prefix."sect2rep SET rep_id='".$repository["rep_id"]."', sect_id='".$sections[$i]."'"; |
$rq =& $this->db->query($query); |
} |
for($i=0;$i<count($arch);$i++) { |
$query = "INSERT INTO ".$this->prefix."arch2rep SET rep_id='".$repository["rep_id"]."', arch_id='".$arch[$i]."'"; |
$rq =& $this->db->query($query); |
} |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Обновление информации о репозитории |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $repID |
* @param integer $verionID |
* @param string $rname |
* @param string $rinfo |
* @param string $rkey |
* @param integer $proto |
* @param integer $rhost |
* @param integer $rfolder |
* @param integer $rtype |
* @param array $sections |
* @param array $arch |
* @param integer $scheme |
* @param integer $sign |
* @return array |
*/ |
public function updateRepository($repID, $verionID, $rname, $rinfo, $rkey, $proto, $rhost, $rfolder, $rtype, $scheme, $sign, $sections, $arch) { |
$result = array(); |
$sRepID = $this->secure->checkInt($repID); |
$sVersionID = $this->secure->checkInt($verionID); |
$sRName = $this->secure->checkStr($rname); |
$sRInfo = $this->secure->checkStr($rinfo); |
$sRKey = $this->secure->checkStr($rkey); |
$sProto = $this->secure->checkInt($proto); |
$sRHost = $this->secure->checkInt($rhost); |
$sRFolder = $this->secure->checkInt($rfolder); |
$sRType = $this->secure->checkInt($rtype); |
$sRScheme = $this->secure->checkInt($scheme); |
$sRSign = $this->secure->checkInt($sign); |
$query = "UPDATE ".$this->prefix."repository SET proto_id='".$sProto."', rhost_id='".$sRHost."', rfolder_id='".$sRFolder."', version='".$sVersionID."', rtype_id='".$sRType."', scheme_id='".$sRScheme."', sign_id='".$sRSign."', repname='".$sRName."', repinfo='".$sRInfo."', repkey='".$sRKey."' WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
$query = "DELETE FROM ".$this->prefix."sect2rep WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
for($i=0;$i<count($sections);$i++) { |
$query = "INSERT INTO ".$this->prefix."sect2rep SET rep_id='".$sRepID."', sect_id='".$sections[$i]."'"; |
$rq =& $this->db->query($query); |
} |
$query = "DELETE FROM ".$this->prefix."arch2rep WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
for($i=0;$i<count($arch);$i++) { |
$query = "INSERT INTO ".$this->prefix."arch2rep SET rep_id='".$sRepID."', arch_id='".$arch[$i]."'"; |
$rq =& $this->db->query($query); |
} |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Удаление информации о репозитории |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param integer $repID |
* @return array |
*/ |
public function dropRepository($repID) { |
$result = array(); |
$sRepID = $this->secure->checkInt($repID); |
// Удаление репозитория |
$query = "DELETE FROM ".$this->prefix."repository WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
// Удаление секций репозитория |
$query = "DELETE FROM ".$this->prefix."sect2rep WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
// Удаление архитектур репозитория |
$query = "DELETE FROM ".$this->prefix."arch2rep WHERE rep_id='".$sRepID."'"; |
$rq =& $this->db->query($query); |
if (PEAR::isError($this->db)) { |
$result["ERR"] = 1; |
$result["ERRINFO"] = $this->db->getMessage(); |
} else { |
$result["ERR"] = 0; |
} |
return $result; |
} |
/** |
* Вывод списка настроек |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @param string $name |
* @param string $actor |
* @param string $format |
* @return string |
*/ |
public function showSettingsList($name, $actor, $format = 'list') { |
$query = "SELECT * FROM ".$this->prefix."settings"; |
$rq =& $this->db->query($query); |
$show = "<ul>\n"; |
$show .= "<li><a href='".$actor."?mode=".$name."&action=update-password' class='edit'>Изменить пароль доступа</a></li>\n"; |
$show .= "</ul>"; |
return $show; |
} |
/** |
* Форма обновления пароля |
* |
* @author Alexander Wolf |
* @category Core |
* |
* @return string |
*/ |
public function showUpdatePasswordForm() { |
$show .= "<fieldset><legend>Обновление пароля доступа</legend>\n"; |
$show .= "<div class='inputbox'><label for='oword'>Текущий пароль:</label> <input type='password' name='oword' value=''></div>\n"; |
$show .= "<div class='inputbox'><label for='nword'>Новый пароль:</label> <input type='password' name='nword' value=''></div>\n"; |
$show .= "<div class='inputbox'><label for='again'>Повторно:</label> <input type='password' name='again' value=''></div>\n"; |
$show .= "<input type='submit' value=' Войти '>\n"; |
$show .= "</fieldset>\n\n"; |
return $show; |
} |
} |
?> |
/tags/0.9.2/lib/template.php |
---|
Новый файл |
0,0 → 1,77 |
<?php |
/** |
* |
* Codename: ant-ng - generator of sources.list for apt-distributives |
* http://alex-w.org.ru/p/antng/ |
* |
* Copyright (c) 2009 Alexander Wolf |
* Dual licensed under the MIT and GNU LGPL licenses. |
* http://alex-w.org.ru/p/antng/license |
* |
*/ |
class Template { |
private $path = NULL; |
protected $self = array(); |
/** |
* Конструктора класса Template - работа с шаблонами |
* |
* @author Alexander Wolf |
* @category Template |
* |
* @param string $folder |
*/ |
public function __construct($folder) { |
$this->path = $folder; |
} |
/** |
* Отображение шаблона |
* |
* @author Alexander Wolf |
* @category Template |
* |
* @param string $name |
*/ |
public function display($name) { |
$fh = fopen($this->path.$name, "r"); |
$content = fread($fh, filesize($this->path.$name)); |
fclose($fh); |
preg_match_all("/{([\d\w]+)}/", $content, $matches); |
$tmpl = $matches[1]; |
for($i=0;$i<=count($tmpl);$i++) { |
$content = str_replace("{".$tmpl[$i]."}", $this->__get($tmpl[$i]), $content); |
} |
echo $content; |
} |
/** |
* Связывание блока с визуальным отображением оного (назначение значения переменной) |
* |
* @author Alexander Wolf |
* @category Template |
* |
* @param string $attr |
* @param string $value |
* @return string |
*/ |
public function assign($attr, $value) { |
return $this->self[$attr] = $value; |
} |
/** |
* Извлечение визуального вида блока по его имени (возвращение значения переменной) |
* |
* @author Alexander Wolf |
* @category Template |
* |
* @param string $attr |
* @return string |
*/ |
public function __get($attr = null) { |
return $this->self[$attr]; |
} |
} |
?> |
/tags/0.9.2/lib/DB/mysql.php |
---|
Новый файл |
0,0 → 1,1045 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* The PEAR DB driver for PHP's mysql extension |
* for interacting with MySQL databases |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: mysql.php,v 1.126 2007/09/21 13:32:52 aharvey Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB_common class so it can be extended from |
*/ |
require_once 'lib/DB/common.php'; |
/** |
* The methods PEAR DB uses to interact with PHP's mysql extension |
* for interacting with MySQL databases |
* |
* These methods overload the ones declared in DB_common. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_mysql extends DB_common |
{ |
// {{{ properties |
/** |
* The DB driver type (mysql, oci8, odbc, etc.) |
* @var string |
*/ |
var $phptype = 'mysql'; |
/** |
* The database syntax variant to be used (db2, access, etc.), if any |
* @var string |
*/ |
var $dbsyntax = 'mysql'; |
/** |
* The capabilities of this DB implementation |
* |
* The 'new_link' element contains the PHP version that first provided |
* new_link support for this DBMS. Contains false if it's unsupported. |
* |
* Meaning of the 'limit' element: |
* + 'emulate' = emulate with fetch row by number |
* + 'alter' = alter the query |
* + false = skip rows |
* |
* @var array |
*/ |
var $features = array( |
'limit' => 'alter', |
'new_link' => '4.2.0', |
'numrows' => true, |
'pconnect' => true, |
'prepare' => false, |
'ssl' => false, |
'transactions' => true, |
); |
/** |
* A mapping of native error codes to DB error codes |
* @var array |
*/ |
var $errorcode_map = array( |
1004 => DB_ERROR_CANNOT_CREATE, |
1005 => DB_ERROR_CANNOT_CREATE, |
1006 => DB_ERROR_CANNOT_CREATE, |
1007 => DB_ERROR_ALREADY_EXISTS, |
1008 => DB_ERROR_CANNOT_DROP, |
1022 => DB_ERROR_ALREADY_EXISTS, |
1044 => DB_ERROR_ACCESS_VIOLATION, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1049 => DB_ERROR_NOSUCHDB, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1061 => DB_ERROR_ALREADY_EXISTS, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1091 => DB_ERROR_NOT_FOUND, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1142 => DB_ERROR_ACCESS_VIOLATION, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => DB_ERROR_CONSTRAINT, |
1356 => DB_ERROR_DIVZERO, |
1451 => DB_ERROR_CONSTRAINT, |
1452 => DB_ERROR_CONSTRAINT, |
); |
/** |
* The raw database connection created by PHP |
* @var resource |
*/ |
var $connection; |
/** |
* The DSN information for connecting to a database |
* @var array |
*/ |
var $dsn = array(); |
/** |
* Should data manipulation queries be committed automatically? |
* @var bool |
* @access private |
*/ |
var $autocommit = true; |
/** |
* The quantity of transactions begun |
* |
* {@internal While this is private, it can't actually be designated |
* private in PHP 5 because it is directly accessed in the test suite.}} |
* |
* @var integer |
* @access private |
*/ |
var $transaction_opcount = 0; |
/** |
* The database specified in the DSN |
* |
* It's a fix to allow calls to different databases in the same script. |
* |
* @var string |
* @access private |
*/ |
var $_db = ''; |
// }}} |
// {{{ constructor |
/** |
* This constructor calls <kbd>$this->DB_common()</kbd> |
* |
* @return void |
*/ |
function DB_mysql() |
{ |
$this->DB_common(); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to the database server, log in and open the database |
* |
* Don't call this method directly. Use DB::connect() instead. |
* |
* PEAR DB's mysql driver supports the following extra DSN options: |
* + new_link If set to true, causes subsequent calls to connect() |
* to return a new connection link instead of the |
* existing one. WARNING: this is not portable to |
* other DBMS's. Available since PEAR DB 1.7.0. |
* + client_flags Any combination of MYSQL_CLIENT_* constants. |
* Only used if PHP is at version 4.3.0 or greater. |
* Available since PEAR DB 1.7.0. |
* |
* @param array $dsn the data source name |
* @param bool $persistent should the connection be persistent? |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function connect($dsn, $persistent = false) |
{ |
if (!PEAR::loadExtension('mysql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsn; |
if ($dsn['dbsyntax']) { |
$this->dbsyntax = $dsn['dbsyntax']; |
} |
$params = array(); |
if ($dsn['protocol'] && $dsn['protocol'] == 'unix') { |
$params[0] = ':' . $dsn['socket']; |
} else { |
$params[0] = $dsn['hostspec'] ? $dsn['hostspec'] |
: 'localhost'; |
if ($dsn['port']) { |
$params[0] .= ':' . $dsn['port']; |
} |
} |
$params[] = $dsn['username'] ? $dsn['username'] : null; |
$params[] = $dsn['password'] ? $dsn['password'] : null; |
if (!$persistent) { |
if (isset($dsn['new_link']) |
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) |
{ |
$params[] = true; |
} else { |
$params[] = false; |
} |
} |
if (version_compare(phpversion(), '4.3.0', '>=')) { |
$params[] = isset($dsn['client_flags']) |
? $dsn['client_flags'] : null; |
} |
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect'; |
$ini = ini_get('track_errors'); |
$php_errormsg = ''; |
if ($ini) { |
$this->connection = @call_user_func_array($connect_function, |
$params); |
} else { |
@ini_set('track_errors', 1); |
$this->connection = @call_user_func_array($connect_function, |
$params); |
@ini_set('track_errors', $ini); |
} |
if (!$this->connection) { |
if (($err = @mysql_error()) != '') { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$err); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, |
null, null, null, |
$php_errormsg); |
} |
} |
if ($dsn['database']) { |
if (!@mysql_select_db($dsn['database'], $this->connection)) { |
return $this->mysqlRaiseError(); |
} |
$this->_db = $dsn['database']; |
} |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Disconnects from the database server |
* |
* @return bool TRUE on success, FALSE on failure |
*/ |
function disconnect() |
{ |
$ret = @mysql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Sends a query to the database server |
* |
* Generally uses mysql_query(). If you want to use |
* mysql_unbuffered_query() set the "result_buffering" option to 0 using |
* setOptions(). This option was added in Release 1.7.0. |
* |
* @param string the SQL query string |
* |
* @return mixed + a PHP result resrouce for successful SELECT queries |
* + the DB_OK constant for other successful queries |
* + a DB_Error object on failure |
*/ |
function simpleQuery($query) |
{ |
$ismanip = $this->_checkManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); |
$result = @mysql_query('BEGIN', $this->connection); |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
if (!$this->options['result_buffering']) { |
$result = @mysql_unbuffered_query($query, $this->connection); |
} else { |
$result = @mysql_query($query, $this->connection); |
} |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
if (is_resource($result)) { |
return $result; |
} |
return DB_OK; |
} |
// }}} |
// {{{ nextResult() |
/** |
* Move the internal mysql result pointer to the next available result |
* |
* This method has not been implemented yet. |
* |
* @param a valid sql result resource |
* |
* @return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Places a row from the result set into the given array |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* This method is not meant to be called directly. Use |
* DB_result::fetchInto() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result the query result resource |
* @param array $arr the referenced array to put the data in |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch (0 = first row) |
* |
* @return mixed DB_OK on success, NULL when the end of a result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
*/ |
function fetchInto($result, &$arr, $fetchmode, $rownum = null) |
{ |
if ($rownum !== null) { |
if (!@mysql_data_seek($result, $rownum)) { |
return null; |
} |
} |
if ($fetchmode & DB_FETCHMODE_ASSOC) { |
$arr = @mysql_fetch_array($result, MYSQL_ASSOC); |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { |
$arr = array_change_key_case($arr, CASE_LOWER); |
} |
} else { |
$arr = @mysql_fetch_row($result); |
} |
if (!$arr) { |
return null; |
} |
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { |
/* |
* Even though this DBMS already trims output, we do this because |
* a field might have intentional whitespace at the end that |
* gets removed by DB_PORTABILITY_RTRIM under another driver. |
*/ |
$this->_rtrimArrayValues($arr); |
} |
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { |
$this->_convertNullArrayValuesToEmpty($arr); |
} |
return DB_OK; |
} |
// }}} |
// {{{ freeResult() |
/** |
* Deletes the result set and frees the memory occupied by the result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::free() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_result::free() |
*/ |
function freeResult($result) |
{ |
return is_resource($result) ? mysql_free_result($result) : false; |
} |
// }}} |
// {{{ numCols() |
/** |
* Gets the number of columns in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numCols() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of columns. A DB_Error object on failure. |
* |
* @see DB_result::numCols() |
*/ |
function numCols($result) |
{ |
$cols = @mysql_num_fields($result); |
if (!$cols) { |
return $this->mysqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Gets the number of rows in a result set |
* |
* This method is not meant to be called directly. Use |
* DB_result::numRows() instead. It can't be declared "protected" |
* because DB_result is a separate object. |
* |
* @param resource $result PHP's query result resource |
* |
* @return int the number of rows. A DB_Error object on failure. |
* |
* @see DB_result::numRows() |
*/ |
function numRows($result) |
{ |
$rows = @mysql_num_rows($result); |
if ($rows === null) { |
return $this->mysqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
// XXX if $this->transaction_opcount > 0, we should probably |
// issue a warning here. |
$this->autocommit = $onoff ? true : false; |
return DB_OK; |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('COMMIT', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
if ($this->transaction_opcount > 0) { |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
$result = @mysql_query('ROLLBACK', $this->connection); |
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); |
$this->transaction_opcount = 0; |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
if ($this->_last_query_manip) { |
return @mysql_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::nextID(), DB_common::getSequenceName(), |
* DB_mysql::createSequence(), DB_mysql::dropSequence() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
$seqname = $this->getSequenceName($seq_name); |
do { |
$repeat = 0; |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$result = $this->query("UPDATE ${seqname} ". |
'SET id=LAST_INSERT_ID(id+1)'); |
$this->popErrorHandling(); |
if ($result === DB_OK) { |
// COMMON CASE |
$id = @mysql_insert_id($this->connection); |
if ($id != 0) { |
return $id; |
} |
// EMPTY SEQ TABLE |
// Sequence table must be empty for some reason, so fill |
// it and return 1 and obtain a user-level lock |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
if ($result == 0) { |
// Failed to get the lock |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
// add the default value |
$result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// Release the lock |
$result = $this->getOne('SELECT RELEASE_LOCK(' |
. "'${seqname}_lock')"); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
// We know what the result will be, so no need to try again |
return 1; |
} elseif ($ondemand && DB::isError($result) && |
$result->getCode() == DB_ERROR_NOSUCHTABLE) |
{ |
// ONDEMAND TABLE CREATION |
$result = $this->createSequence($seq_name); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} else { |
$repeat = 1; |
} |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// BACKWARDS COMPAT |
// see _BCsequence() comment |
$result = $this->_BCsequence($seqname); |
if (DB::isError($result)) { |
return $this->raiseError($result); |
} |
$repeat = 1; |
} |
} while ($repeat); |
return $this->raiseError($result); |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_mysql::nextID(), DB_mysql::dropSequence() |
*/ |
function createSequence($seq_name) |
{ |
$seqname = $this->getSequenceName($seq_name); |
$res = $this->query('CREATE TABLE ' . $seqname |
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,' |
. ' PRIMARY KEY(id))'); |
if (DB::isError($res)) { |
return $res; |
} |
// insert yields value 1, nextId call will generate ID 2 |
$res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); |
if (DB::isError($res)) { |
return $res; |
} |
// so reset to zero |
return $this->query("UPDATE ${seqname} SET id = 0"); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_mysql::nextID(), DB_mysql::createSequence() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); |
} |
// }}} |
// {{{ _BCsequence() |
/** |
* Backwards compatibility with old sequence emulation implementation |
* (clean up the dupes) |
* |
* @param string $seqname the sequence name to clean up |
* |
* @return bool true on success. A DB_Error object on failure. |
* |
* @access private |
*/ |
function _BCsequence($seqname) |
{ |
// Obtain a user-level lock... this will release any previous |
// application locks, but unlike LOCK TABLES, it does not abort |
// the current transaction and is much less frequently used. |
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); |
if (DB::isError($result)) { |
return $result; |
} |
if ($result == 0) { |
// Failed to get the lock, can't do the conversion, bail |
// with a DB_ERROR_NOT_LOCKED error |
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); |
} |
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); |
if (DB::isError($highest_id)) { |
return $highest_id; |
} |
// This should kill all rows except the highest |
// We should probably do something if $highest_id isn't |
// numeric, but I'm at a loss as how to handle that... |
$result = $this->query('DELETE FROM ' . $seqname |
. " WHERE id <> $highest_id"); |
if (DB::isError($result)) { |
return $result; |
} |
// If another thread has been waiting for this lock, |
// it will go thru the above procedure, but will have no |
// real effect |
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); |
if (DB::isError($result)) { |
return $result; |
} |
return true; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* (WARNING: using names that require this is a REALLY BAD IDEA) |
* |
* WARNING: Older versions of MySQL can't handle the backtick |
* character (<kbd>`</kbd>) in table or column names. |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @see DB_common::quoteIdentifier() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '`' . str_replace('`', '``', $str) . '`'; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($str) |
{ |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
if (function_exists('mysql_real_escape_string')) { |
return @mysql_real_escape_string($str, $this->connection); |
} else { |
return @mysql_escape_string($str); |
} |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* This little hack lets you know how many rows were deleted |
* when running a "DELETE FROM table" query. Only implemented |
* if the DB_PORTABILITY_DELETE_COUNT portability option is on. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_common::setOption() |
*/ |
function modifyQuery($query) |
{ |
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { |
// "DELETE FROM table" gives 0 affected rows in MySQL. |
// This little hack lets you know how many rows were deleted. |
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { |
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', |
'DELETE FROM \1 WHERE 1=1', $query); |
} |
} |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if (DB::isManip($query) || $this->_next_query_manip) { |
return $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqlRaiseError() |
/** |
* Produces a DB_Error object regarding the current problem |
* |
* @param int $errno if the error is being manually raised pass a |
* DB_ERROR* constant here. If this isn't passed |
* the error information gathered from the DBMS. |
* |
* @return object the DB_Error object |
* |
* @see DB_common::raiseError(), |
* DB_mysql::errorNative(), DB_common::errorCode() |
*/ |
function mysqlRaiseError($errno = null) |
{ |
if ($errno === null) { |
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { |
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; |
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; |
} else { |
// Doing this in case mode changes during runtime. |
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; |
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; |
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; |
} |
$errno = $this->errorCode(mysql_errno($this->connection)); |
} |
return $this->raiseError($errno, null, null, null, |
@mysql_errno($this->connection) . ' ** ' . |
@mysql_error($this->connection)); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return int the DBMS' error code |
*/ |
function errorNative() |
{ |
return @mysql_errno($this->connection); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode a valid tableInfo mode |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) |
{ |
if (is_string($result)) { |
// Fix for bug #11580. |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @mysql_query("SELECT * FROM $result LIMIT 0", |
$this->connection); |
$got_string = true; |
} elseif (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} else { |
/* |
* Probably received a result resource identifier. |
* Copy it. |
* Deprecated. Here for compatibility only. |
*/ |
$id = $result; |
$got_string = false; |
} |
if (!is_resource($id)) { |
return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); |
} |
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { |
$case_func = 'strtolower'; |
} else { |
$case_func = 'strval'; |
} |
$count = @mysql_num_fields($id); |
$res = array(); |
if ($mode) { |
$res['num_fields'] = $count; |
} |
for ($i = 0; $i < $count; $i++) { |
$res[$i] = array( |
'table' => $case_func(@mysql_field_table($id, $i)), |
'name' => $case_func(@mysql_field_name($id, $i)), |
'type' => @mysql_field_type($id, $i), |
'len' => @mysql_field_len($id, $i), |
'flags' => @mysql_field_flags($id, $i), |
); |
if ($mode & DB_TABLEINFO_ORDER) { |
$res['order'][$res[$i]['name']] = $i; |
} |
if ($mode & DB_TABLEINFO_ORDERTABLE) { |
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; |
} |
} |
// free the result only if we were called on a table |
if ($got_string) { |
@mysql_free_result($id); |
} |
return $res; |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SHOW TABLES'; |
case 'users': |
return 'SELECT DISTINCT User FROM mysql.user'; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/tags/0.9.2/lib/DB/common.php |
---|
Новый файл |
0,0 → 1,2257 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Contains the DB_common base class |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: common.php,v 1.143 2007/09/21 13:40:41 aharvey Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the PEAR class so it can be extended from |
*/ |
require_once 'lib/PEAR.php'; |
/** |
* DB_common is the base class from which each database driver class extends |
* |
* All common methods are declared here. If a given DBMS driver contains |
* a particular method, that method will overload the one here. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V. Cox <cox@idecnet.com> |
* @author Daniel Convissor <danielc@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_common extends PEAR |
{ |
// {{{ properties |
/** |
* The current default fetch mode |
* @var integer |
*/ |
var $fetchmode = DB_FETCHMODE_ORDERED; |
/** |
* The name of the class into which results should be fetched when |
* DB_FETCHMODE_OBJECT is in effect |
* |
* @var string |
*/ |
var $fetchmode_object_class = 'stdClass'; |
/** |
* Was a connection present when the object was serialized()? |
* @var bool |
* @see DB_common::__sleep(), DB_common::__wake() |
*/ |
var $was_connected = null; |
/** |
* The most recently executed query |
* @var string |
*/ |
var $last_query = ''; |
/** |
* Run-time configuration options |
* |
* The 'optimize' option has been deprecated. Use the 'portability' |
* option instead. |
* |
* @var array |
* @see DB_common::setOption() |
*/ |
var $options = array( |
'result_buffering' => 500, |
'persistent' => false, |
'ssl' => false, |
'debug' => 0, |
'seqname_format' => '%s_seq', |
'autofree' => false, |
'portability' => DB_PORTABILITY_NONE, |
'optimize' => 'performance', // Deprecated. Use 'portability'. |
); |
/** |
* The parameters from the most recently executed query |
* @var array |
* @since Property available since Release 1.7.0 |
*/ |
var $last_parameters = array(); |
/** |
* The elements from each prepared statement |
* @var array |
*/ |
var $prepare_tokens = array(); |
/** |
* The data types of the various elements in each prepared statement |
* @var array |
*/ |
var $prepare_types = array(); |
/** |
* The prepared queries |
* @var array |
*/ |
var $prepared_queries = array(); |
/** |
* Flag indicating that the last query was a manipulation query. |
* @access protected |
* @var boolean |
*/ |
var $_last_query_manip = false; |
/** |
* Flag indicating that the next query <em>must</em> be a manipulation |
* query. |
* @access protected |
* @var boolean |
*/ |
var $_next_query_manip = false; |
// }}} |
// {{{ DB_common |
/** |
* This constructor calls <kbd>$this->PEAR('DB_Error')</kbd> |
* |
* @return void |
*/ |
function DB_common() |
{ |
$this->PEAR('DB_Error'); |
} |
// }}} |
// {{{ __sleep() |
/** |
* Automatically indicates which properties should be saved |
* when PHP's serialize() function is called |
* |
* @return array the array of properties names that should be saved |
*/ |
function __sleep() |
{ |
if ($this->connection) { |
// Don't disconnect(), people use serialize() for many reasons |
$this->was_connected = true; |
} else { |
$this->was_connected = false; |
} |
if (isset($this->autocommit)) { |
return array('autocommit', |
'dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} else { |
return array('dbsyntax', |
'dsn', |
'features', |
'fetchmode', |
'fetchmode_object_class', |
'options', |
'was_connected', |
); |
} |
} |
// }}} |
// {{{ __wakeup() |
/** |
* Automatically reconnects to the database when PHP's unserialize() |
* function is called |
* |
* The reconnection attempt is only performed if the object was connected |
* at the time PHP's serialize() function was run. |
* |
* @return void |
*/ |
function __wakeup() |
{ |
if ($this->was_connected) { |
$this->connect($this->dsn, $this->options); |
} |
} |
// }}} |
// {{{ __toString() |
/** |
* Automatic string conversion for PHP 5 |
* |
* @return string a string describing the current PEAR DB object |
* |
* @since Method available since Release 1.7.0 |
*/ |
function __toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= ': (phptype=' . $this->phptype . |
', dbsyntax=' . $this->dbsyntax . |
')'; |
if ($this->connection) { |
$info .= ' [connected]'; |
} |
return $info; |
} |
// }}} |
// {{{ toString() |
/** |
* DEPRECATED: String conversion method |
* |
* @return string a string describing the current PEAR DB object |
* |
* @deprecated Method deprecated in Release 1.7.0 |
*/ |
function toString() |
{ |
return $this->__toString(); |
} |
// }}} |
// {{{ quoteString() |
/** |
* DEPRECATED: Quotes a string so it can be safely used within string |
* delimiters in a query |
* |
* @param string $string the string to be quoted |
* |
* @return string the quoted string |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function quoteString($string) |
{ |
$string = $this->quote($string); |
if ($string{0} == "'") { |
return substr($string, 1, -1); |
} |
return $string; |
} |
// }}} |
// {{{ quote() |
/** |
* DEPRECATED: Quotes a string so it can be safely used in a query |
* |
* @param string $string the string to quote |
* |
* @return string the quoted string or the string <samp>NULL</samp> |
* if the value submitted is <kbd>null</kbd>. |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Deprecated in release 1.6.0 |
*/ |
function quote($string = null) |
{ |
return ($string === null) ? 'NULL' |
: "'" . str_replace("'", "''", $string) . "'"; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quotes a string so it can be safely used as a table or column name |
* |
* Delimiting style depends on which database driver is being used. |
* |
* NOTE: just because you CAN use delimited identifiers doesn't mean |
* you SHOULD use them. In general, they end up causing way more |
* problems than they solve. |
* |
* Portability is broken by using the following characters inside |
* delimited identifiers: |
* + backtick (<kbd>`</kbd>) -- due to MySQL |
* + double quote (<kbd>"</kbd>) -- due to Oracle |
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access |
* |
* Delimited identifiers are known to generally work correctly under |
* the following drivers: |
* + mssql |
* + mysql |
* + mysqli |
* + oci8 |
* + odbc(access) |
* + odbc(db2) |
* + pgsql |
* + sqlite |
* + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime |
* prior to use) |
* |
* InterBase doesn't seem to be able to use delimited identifiers |
* via PHP 4. They work fine under PHP 5. |
* |
* @param string $str the identifier name to be quoted |
* |
* @return string the quoted identifier |
* |
* @since Method available since Release 1.6.0 |
*/ |
function quoteIdentifier($str) |
{ |
return '"' . str_replace('"', '""', $str) . '"'; |
} |
// }}} |
// {{{ quoteSmart() |
/** |
* Formats input so it can be safely used in a query |
* |
* The output depends on the PHP data type of input and the database |
* type being used. |
* |
* @param mixed $in the data to be formatted |
* |
* @return mixed the formatted data. The format depends on the input's |
* PHP type: |
* <ul> |
* <li> |
* <kbd>input</kbd> -> <samp>returns</samp> |
* </li> |
* <li> |
* <kbd>null</kbd> -> the string <samp>NULL</samp> |
* </li> |
* <li> |
* <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number |
* </li> |
* <li> |
* <kbd>bool</kbd> -> output depends on the driver in use |
* Most drivers return integers: <samp>1</samp> if |
* <kbd>true</kbd> or <samp>0</samp> if |
* <kbd>false</kbd>. |
* Some return strings: <samp>TRUE</samp> if |
* <kbd>true</kbd> or <samp>FALSE</samp> if |
* <kbd>false</kbd>. |
* Finally one returns strings: <samp>T</samp> if |
* <kbd>true</kbd> or <samp>F</samp> if |
* <kbd>false</kbd>. Here is a list of each DBMS, |
* the values returned and the suggested column type: |
* <ul> |
* <li> |
* <kbd>dbase</kbd> -> <samp>T/F</samp> |
* (<kbd>Logical</kbd>) |
* </li> |
* <li> |
* <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>ibase</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>ifx</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>msql</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>mssql</kbd> -> <samp>1/0</samp> |
* (<kbd>BIT</kbd>) |
* </li> |
* <li> |
* <kbd>mysql</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>mysqli</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* <li> |
* <kbd>oci8</kbd> -> <samp>1/0</samp> |
* (<kbd>NUMBER(1)</kbd>) |
* </li> |
* <li> |
* <kbd>odbc</kbd> -> <samp>1/0</samp> |
* (<kbd>SMALLINT</kbd>) [1] |
* </li> |
* <li> |
* <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp> |
* (<kbd>BOOLEAN</kbd>) |
* </li> |
* <li> |
* <kbd>sqlite</kbd> -> <samp>1/0</samp> |
* (<kbd>INTEGER</kbd>) |
* </li> |
* <li> |
* <kbd>sybase</kbd> -> <samp>1/0</samp> |
* (<kbd>TINYINT(1)</kbd>) |
* </li> |
* </ul> |
* [1] Accommodate the lowest common denominator because not all |
* versions of have <kbd>BOOLEAN</kbd>. |
* </li> |
* <li> |
* other (including strings and numeric strings) -> |
* the data with single quotes escaped by preceeding |
* single quotes, backslashes are escaped by preceeding |
* backslashes, then the whole string is encapsulated |
* between single quotes |
* </li> |
* </ul> |
* |
* @see DB_common::escapeSimple() |
* @since Method available since Release 1.6.0 |
*/ |
function quoteSmart($in) |
{ |
if (is_int($in)) { |
return $in; |
} elseif (is_float($in)) { |
return $this->quoteFloat($in); |
} elseif (is_bool($in)) { |
return $this->quoteBoolean($in); |
} elseif (is_null($in)) { |
return 'NULL'; |
} else { |
if ($this->dbsyntax == 'access' |
&& preg_match('/^#.+#$/', $in)) |
{ |
return $this->escapeSimple($in); |
} |
return "'" . $this->escapeSimple($in) . "'"; |
} |
} |
// }}} |
// {{{ quoteBoolean() |
/** |
* Formats a boolean value for use within a query in a locale-independent |
* manner. |
* |
* @param boolean the boolean value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteBoolean($boolean) { |
return $boolean ? '1' : '0'; |
} |
// }}} |
// {{{ quoteFloat() |
/** |
* Formats a float value for use within a query in a locale-independent |
* manner. |
* |
* @param float the float value to be quoted. |
* @return string the quoted string. |
* @see DB_common::quoteSmart() |
* @since Method available since release 1.7.8. |
*/ |
function quoteFloat($float) { |
return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'"; |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escapes a string according to the current DBMS's standards |
* |
* In SQLite, this makes things safe for inserts/updates, but may |
* cause problems when performing text comparisons against columns |
* containing binary data. See the |
* {@link http://php.net/sqlite_escape_string PHP manual} for more info. |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @see DB_common::quoteSmart() |
* @since Method available since Release 1.6.0 |
*/ |
function escapeSimple($str) |
{ |
return str_replace("'", "''", $str); |
} |
// }}} |
// {{{ provides() |
/** |
* Tells whether the present driver supports a given feature |
* |
* @param string $feature the feature you're curious about |
* |
* @return bool whether this driver supports $feature |
*/ |
function provides($feature) |
{ |
return $this->features[$feature]; |
} |
// }}} |
// {{{ setFetchMode() |
/** |
* Sets the fetch mode that should be used by default for query results |
* |
* @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC |
* or DB_FETCHMODE_OBJECT |
* @param string $object_class the class name of the object to be returned |
* by the fetch methods when the |
* DB_FETCHMODE_OBJECT mode is selected. |
* If no class is specified by default a cast |
* to object from the assoc array row will be |
* done. There is also the posibility to use |
* and extend the 'DB_row' class. |
* |
* @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT |
*/ |
function setFetchMode($fetchmode, $object_class = 'stdClass') |
{ |
switch ($fetchmode) { |
case DB_FETCHMODE_OBJECT: |
$this->fetchmode_object_class = $object_class; |
case DB_FETCHMODE_ORDERED: |
case DB_FETCHMODE_ASSOC: |
$this->fetchmode = $fetchmode; |
break; |
default: |
return $this->raiseError('invalid fetchmode mode'); |
} |
} |
// }}} |
// {{{ setOption() |
/** |
* Sets run-time configuration options for PEAR DB |
* |
* Options, their data types, default values and description: |
* <ul> |
* <li> |
* <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should results be freed automatically when there are no |
* more rows? |
* </li><li> |
* <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp> |
* <br />how many rows of the result set should be buffered? |
* <br />In mysql: mysql_unbuffered_query() is used instead of |
* mysql_query() if this value is 0. (Release 1.7.0) |
* <br />In oci8: this value is passed to ocisetprefetch(). |
* (Release 1.7.0) |
* </li><li> |
* <var>debug</var> <kbd>integer</kbd> = <samp>0</samp> |
* <br />debug level |
* </li><li> |
* <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />should the connection be persistent? |
* </li><li> |
* <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp> |
* <br />portability mode constant (see below) |
* </li><li> |
* <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp> |
* <br />the sprintf() format string used on sequence names. This |
* format is applied to sequence names passed to |
* createSequence(), nextID() and dropSequence(). |
* </li><li> |
* <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp> |
* <br />use ssl to connect? |
* </li> |
* </ul> |
* |
* ----------------------------------------- |
* |
* PORTABILITY MODES |
* |
* These modes are bitwised, so they can be combined using <kbd>|</kbd> |
* and removed using <kbd>^</kbd>. See the examples section below on how |
* to do this. |
* |
* <samp>DB_PORTABILITY_NONE</samp> |
* turn off all portability features |
* |
* This mode gets automatically turned on if the deprecated |
* <var>optimize</var> option gets set to <samp>performance</samp>. |
* |
* |
* <samp>DB_PORTABILITY_LOWERCASE</samp> |
* convert names of tables and fields to lower case when using |
* <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd> |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_RTRIM</samp> |
* right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd> |
* |
* |
* <samp>DB_PORTABILITY_DELETE_COUNT</samp> |
* force reporting the number of rows deleted |
* |
* Some DBMS's don't count the number of rows deleted when performing |
* simple <kbd>DELETE FROM tablename</kbd> queries. This portability |
* mode tricks such DBMS's into telling the count by adding |
* <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries. |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + fbsql |
* + mysql |
* + mysqli |
* + sqlite |
* |
* |
* <samp>DB_PORTABILITY_NUMROWS</samp> |
* enable hack that makes <kbd>numRows()</kbd> work in Oracle |
* |
* This mode gets automatically turned on in the following databases |
* if the deprecated option <var>optimize</var> gets set to |
* <samp>portability</samp>: |
* + oci8 |
* |
* |
* <samp>DB_PORTABILITY_ERRORS</samp> |
* makes certain error messages in certain drivers compatible |
* with those from other DBMS's |
* |
* + mysql, mysqli: change unique/primary key constraints |
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT |
* |
* + odbc(access): MS's ODBC driver reports 'no such field' as code |
* 07001, which means 'too few parameters.' When this option is on |
* that code gets mapped to DB_ERROR_NOSUCHFIELD. |
* DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD |
* |
* <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp> |
* convert null values to empty strings in data output by get*() and |
* fetch*(). Needed because Oracle considers empty strings to be null, |
* while most other DBMS's know the difference between empty and null. |
* |
* |
* <samp>DB_PORTABILITY_ALL</samp> |
* turn on all portability features |
* |
* ----------------------------------------- |
* |
* Example 1. Simple setOption() example |
* <code> |
* $db->setOption('autofree', true); |
* </code> |
* |
* Example 2. Portability for lowercasing and trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); |
* </code> |
* |
* Example 3. All portability options except trimming |
* <code> |
* $db->setOption('portability', |
* DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM); |
* </code> |
* |
* @param string $option option name |
* @param mixed $value value for the option |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::$options |
*/ |
function setOption($option, $value) |
{ |
if (isset($this->options[$option])) { |
$this->options[$option] = $value; |
/* |
* Backwards compatibility check for the deprecated 'optimize' |
* option. Done here in case settings change after connecting. |
*/ |
if ($option == 'optimize') { |
if ($value == 'portability') { |
switch ($this->phptype) { |
case 'oci8': |
$this->options['portability'] = |
DB_PORTABILITY_LOWERCASE | |
DB_PORTABILITY_NUMROWS; |
break; |
case 'fbsql': |
case 'mysql': |
case 'mysqli': |
case 'sqlite': |
$this->options['portability'] = |
DB_PORTABILITY_DELETE_COUNT; |
break; |
} |
} else { |
$this->options['portability'] = DB_PORTABILITY_NONE; |
} |
} |
return DB_OK; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ getOption() |
/** |
* Returns the value of an option |
* |
* @param string $option the option name you're curious about |
* |
* @return mixed the option's value |
*/ |
function getOption($option) |
{ |
if (isset($this->options[$option])) { |
return $this->options[$option]; |
} |
return $this->raiseError("unknown option $option"); |
} |
// }}} |
// {{{ prepare() |
/** |
* Prepares a query for multiple execution with execute() |
* |
* Creates a query that can be run multiple times. Each time it is run, |
* the placeholders, if any, will be replaced by the contents of |
* execute()'s $data argument. |
* |
* Three types of placeholders can be used: |
* + <kbd>?</kbd> scalar value (i.e. strings, integers). The system |
* will automatically quote and escape the data. |
* + <kbd>!</kbd> value is inserted 'as is' |
* + <kbd>&</kbd> requires a file name. The file's contents get |
* inserted into the query (i.e. saving binary |
* data in a db) |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $db->execute($sth, $data); |
* </code> |
* |
* Use backslashes to escape placeholder characters if you don't want |
* them to be interpreted as placeholders: |
* <pre> |
* "UPDATE foo SET col=? WHERE col='over \& under'" |
* </pre> |
* |
* With some database backends, this is emulated. |
* |
* {@internal ibase and oci8 have their own prepare() methods.}} |
* |
* @param string $query the query to be prepared |
* |
* @return mixed DB statement resource on success. A DB_Error object |
* on failure. |
* |
* @see DB_common::execute() |
*/ |
function prepare($query) |
{ |
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1, |
PREG_SPLIT_DELIM_CAPTURE); |
$token = 0; |
$types = array(); |
$newtokens = array(); |
foreach ($tokens as $val) { |
switch ($val) { |
case '?': |
$types[$token++] = DB_PARAM_SCALAR; |
break; |
case '&': |
$types[$token++] = DB_PARAM_OPAQUE; |
break; |
case '!': |
$types[$token++] = DB_PARAM_MISC; |
break; |
default: |
$newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val); |
} |
} |
$this->prepare_tokens[] = &$newtokens; |
end($this->prepare_tokens); |
$k = key($this->prepare_tokens); |
$this->prepare_types[$k] = $types; |
$this->prepared_queries[$k] = implode(' ', $newtokens); |
return $k; |
} |
// }}} |
// {{{ autoPrepare() |
/** |
* Automaticaly generates an insert or update query and pass it to prepare() |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return resource the query handle |
* |
* @uses DB_common::prepare(), DB_common::buildManipSQL() |
*/ |
function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
if (DB::isError($query)) { |
return $query; |
} |
return $this->prepare($query); |
} |
// }}} |
// {{{ autoExecute() |
/** |
* Automaticaly generates an insert or update query and call prepare() |
* and execute() with it |
* |
* @param string $table the table name |
* @param array $fields_values the associative array where $key is a |
* field name and $value its value |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @uses DB_common::autoPrepare(), DB_common::execute() |
*/ |
function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, |
$where = false) |
{ |
$sth = $this->autoPrepare($table, array_keys($fields_values), $mode, |
$where); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret = $this->execute($sth, array_values($fields_values)); |
$this->freePrepared($sth); |
return $ret; |
} |
// }}} |
// {{{ buildManipSQL() |
/** |
* Produces an SQL query string for autoPrepare() |
* |
* Example: |
* <pre> |
* buildManipSQL('table_sql', array('field1', 'field2', 'field3'), |
* DB_AUTOQUERY_INSERT); |
* </pre> |
* |
* That returns |
* <samp> |
* INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) |
* </samp> |
* |
* NOTES: |
* - This belongs more to a SQL Builder class, but this is a simple |
* facility. |
* - Be carefull! If you don't give a $where param with an UPDATE |
* query, all the records of the table will be updated! |
* |
* @param string $table the table name |
* @param array $table_fields the array of field names |
* @param int $mode a type of query to make: |
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE |
* @param string $where for update queries: the WHERE clause to |
* append to the SQL statement. Don't |
* include the "WHERE" keyword. |
* |
* @return string the sql query for autoPrepare() |
*/ |
function buildManipSQL($table, $table_fields, $mode, $where = false) |
{ |
if (count($table_fields) == 0) { |
return $this->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
$first = true; |
switch ($mode) { |
case DB_AUTOQUERY_INSERT: |
$values = ''; |
$names = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$names .= ','; |
$values .= ','; |
} |
$names .= $value; |
$values .= '?'; |
} |
return "INSERT INTO $table ($names) VALUES ($values)"; |
case DB_AUTOQUERY_UPDATE: |
$set = ''; |
foreach ($table_fields as $value) { |
if ($first) { |
$first = false; |
} else { |
$set .= ','; |
} |
$set .= "$value = ?"; |
} |
$sql = "UPDATE $table SET $set"; |
if ($where) { |
$sql .= " WHERE $where"; |
} |
return $sql; |
default: |
return $this->raiseError(DB_ERROR_SYNTAX); |
} |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare() |
* |
* Example 1. |
* <code> |
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $db->execute($sth, $data); |
* </code> |
* |
* @param resource $stmt a DB statement resource returned from prepare() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* {@internal ibase and oci8 have their own execute() methods.}} |
* |
* @see DB_common::prepare() |
*/ |
function &execute($stmt, $data = array()) |
{ |
$realquery = $this->executeEmulateQuery($stmt, $data); |
if (DB::isError($realquery)) { |
return $realquery; |
} |
$result = $this->simpleQuery($realquery); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp = new DB_result($this, $result); |
return $tmp; |
} |
} |
// }}} |
// {{{ executeEmulateQuery() |
/** |
* Emulates executing prepared statements if the DBMS not support them |
* |
* @param resource $stmt a DB statement resource returned from execute() |
* @param mixed $data array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a string containing the real query run when emulating |
* prepare/execute. A DB_Error object on failure. |
* |
* @access protected |
* @see DB_common::execute() |
*/ |
function executeEmulateQuery($stmt, $data = array()) |
{ |
$stmt = (int)$stmt; |
$data = (array)$data; |
$this->last_parameters = $data; |
if (count($this->prepare_types[$stmt]) != count($data)) { |
$this->last_query = $this->prepared_queries[$stmt]; |
return $this->raiseError(DB_ERROR_MISMATCH); |
} |
$realquery = $this->prepare_tokens[$stmt][0]; |
$i = 0; |
foreach ($data as $value) { |
if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { |
$realquery .= $this->quoteSmart($value); |
} elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { |
$fp = @fopen($value, 'rb'); |
if (!$fp) { |
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); |
} |
$realquery .= $this->quoteSmart(fread($fp, filesize($value))); |
fclose($fp); |
} else { |
$realquery .= $value; |
} |
$realquery .= $this->prepare_tokens[$stmt][++$i]; |
} |
return $realquery; |
} |
// }}} |
// {{{ executeMultiple() |
/** |
* Performs several execute() calls on the same statement handle |
* |
* $data must be an array indexed numerically |
* from 0, one execute call is done for every "row" in the array. |
* |
* If an error occurs during execute(), executeMultiple() does not |
* execute the unfinished rows, but rather returns that error. |
* |
* @param resource $stmt query handle from prepare() |
* @param array $data numeric array containing the |
* data to insert into the query |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::prepare(), DB_common::execute() |
*/ |
function executeMultiple($stmt, $data) |
{ |
foreach ($data as $value) { |
$res = $this->execute($stmt, $value); |
if (DB::isError($res)) { |
return $res; |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ freePrepared() |
/** |
* Frees the internal resources associated with a prepared query |
* |
* @param resource $stmt the prepared statement's PHP resource |
* @param bool $free_resource should the PHP resource be freed too? |
* Use false if you need to get data |
* from the result set later. |
* |
* @return bool TRUE on success, FALSE if $result is invalid |
* |
* @see DB_common::prepare() |
*/ |
function freePrepared($stmt, $free_resource = true) |
{ |
$stmt = (int)$stmt; |
if (isset($this->prepare_tokens[$stmt])) { |
unset($this->prepare_tokens[$stmt]); |
unset($this->prepare_types[$stmt]); |
unset($this->prepared_queries[$stmt]); |
return true; |
} |
return false; |
} |
// }}} |
// {{{ modifyQuery() |
/** |
* Changes a query string for various DBMS specific reasons |
* |
* It is defined here to ensure all drivers have this method available. |
* |
* @param string $query the query string to modify |
* |
* @return string the modified query string |
* |
* @access protected |
* @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(), |
* DB_sqlite::modifyQuery() |
*/ |
function modifyQuery($query) |
{ |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* Adds LIMIT clauses to a query string according to current DBMS standards |
* |
* It is defined here to assure that all implementations |
* have this method defined. |
* |
* @param string $query the query to modify |
* @param int $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return string the query string with LIMIT clauses added |
* |
* @access protected |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
return $query; |
} |
// }}} |
// {{{ query() |
/** |
* Sends a query to the database server |
* |
* The query string can be either a normal statement to be sent directly |
* to the server OR if <var>$params</var> are passed the query can have |
* placeholders and it will be passed through prepare() and execute(). |
* |
* @param string $query the SQL query or the statement to prepare |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
* |
* @see DB_result, DB_common::prepare(), DB_common::execute() |
*/ |
function &query($query, $params = array()) |
{ |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$ret = $this->execute($sth, $params); |
$this->freePrepared($sth, false); |
return $ret; |
} else { |
$this->last_parameters = array(); |
$result = $this->simpleQuery($query); |
if ($result === DB_OK || DB::isError($result)) { |
return $result; |
} else { |
$tmp = new DB_result($this, $result); |
return $tmp; |
} |
} |
} |
// }}} |
// {{{ limitQuery() |
/** |
* Generates and executes a LIMIT query |
* |
* @param string $query the query |
* @param intr $from the row to start to fetching (0 = the first row) |
* @param int $count the numbers of rows to fetch |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed a new DB_result object for successful SELECT queries |
* or DB_OK for successul data manipulation queries. |
* A DB_Error object on failure. |
*/ |
function &limitQuery($query, $from, $count, $params = array()) |
{ |
$query = $this->modifyLimitQuery($query, $from, $count, $params); |
if (DB::isError($query)){ |
return $query; |
} |
$result = $this->query($query, $params); |
if (is_a($result, 'DB_result')) { |
$result->setOption('limit_from', $from); |
$result->setOption('limit_count', $count); |
} |
return $result; |
} |
// }}} |
// {{{ getOne() |
/** |
* Fetches the first column of the first row from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return mixed the returned value of the query. |
* A DB_Error object on failure. |
*/ |
function &getOne($query, $params = array()) |
{ |
$params = (array)$params; |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row[0]; |
} |
// }}} |
// {{{ getRow() |
/** |
* Fetches the first row of data returned from a query result |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use |
* |
* @return array the first row of results as an array. |
* A DB_Error object on failure. |
*/ |
function &getRow($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
// modifyLimitQuery() would be nice here, but it causes BC issues |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, $fetchmode); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row; |
} |
// }}} |
// {{{ getCol() |
/** |
* Fetches a single column from a query result and returns it as an |
* indexed array |
* |
* @param string $query the SQL query |
* @param mixed $col which column to return (integer [column number, |
* starting at 0] or string [column name]) |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of items |
* passed must match quantity of placeholders in |
* query: meaning 1 placeholder for non-array |
* parameters or 1 placeholder per array element. |
* |
* @return array the results as an array. A DB_Error object on failure. |
* |
* @see DB_common::query() |
*/ |
function &getCol($query, $col = 0, $params = array()) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
$fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; |
if (!is_array($row = $res->fetchRow($fetchmode))) { |
$ret = array(); |
} else { |
if (!array_key_exists($col, $row)) { |
$ret = $this->raiseError(DB_ERROR_NOSUCHFIELD); |
} else { |
$ret = array($row[$col]); |
while (is_array($row = $res->fetchRow($fetchmode))) { |
$ret[] = $row[$col]; |
} |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$ret = $row; |
} |
return $ret; |
} |
// }}} |
// {{{ getAssoc() |
/** |
* Fetches an entire query result and returns it as an |
* associative array using the first column as the key |
* |
* If the result set contains more than two columns, the value |
* will be an array of the values from column 2-n. If the result |
* set contains only two columns, the returned value will be a |
* scalar with the value of the second column (unless forced to an |
* array with the $force_array parameter). A DB error code is |
* returned on errors. If the result set contains fewer than two |
* columns, a DB_ERROR_TRUNCATED error is returned. |
* |
* For example, if the table "mytable" contains: |
* |
* <pre> |
* ID TEXT DATE |
* -------------------------------- |
* 1 'one' 944679408 |
* 2 'two' 944679408 |
* 3 'three' 944679408 |
* </pre> |
* |
* Then the call getAssoc('SELECT id,text FROM mytable') returns: |
* <pre> |
* array( |
* '1' => 'one', |
* '2' => 'two', |
* '3' => 'three', |
* ) |
* </pre> |
* |
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns: |
* <pre> |
* array( |
* '1' => array('one', '944679408'), |
* '2' => array('two', '944679408'), |
* '3' => array('three', '944679408') |
* ) |
* </pre> |
* |
* If the more than one row occurs with the same value in the |
* first column, the last row overwrites all previous ones by |
* default. Use the $group parameter if you don't want to |
* overwrite like this. Example: |
* |
* <pre> |
* getAssoc('SELECT category,id,name FROM mytable', false, null, |
* DB_FETCHMODE_ASSOC, true) returns: |
* |
* array( |
* '1' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ), |
* '9' => array(array('id' => '4', 'name' => 'number four'), |
* array('id' => '6', 'name' => 'number six') |
* ) |
* ) |
* </pre> |
* |
* Keep in mind that database functions in PHP usually return string |
* values for results regardless of the database's internal type. |
* |
* @param string $query the SQL query |
* @param bool $force_array used only when the query returns |
* exactly two columns. If true, the values |
* of the returned array will be one-element |
* arrays instead of scalars. |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of |
* items passed must match quantity of |
* placeholders in query: meaning 1 |
* placeholder for non-array parameters or |
* 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use |
* @param bool $group if true, the values of the returned array |
* is wrapped in another array. If the same |
* key value (in the first column) repeats |
* itself, the values will be appended to |
* this array instead of overwriting the |
* existing values. |
* |
* @return array the associative array containing the query results. |
* A DB_Error object on failure. |
*/ |
function &getAssoc($query, $force_array = false, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
{ |
$params = (array)$params; |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if (DB::isError($res)) { |
return $res; |
} |
if ($fetchmode == DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
$cols = $res->numCols(); |
if ($cols < 2) { |
$tmp = $this->raiseError(DB_ERROR_TRUNCATED); |
return $tmp; |
} |
$results = array(); |
if ($cols > 2 || $force_array) { |
// return array values |
// XXX this part can be optimized |
if ($fetchmode == DB_FETCHMODE_ASSOC) { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { |
reset($row); |
$key = current($row); |
unset($row[key($row)]); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} elseif ($fetchmode == DB_FETCHMODE_OBJECT) { |
while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { |
$arr = get_object_vars($row); |
$key = current($arr); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} else { |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
// we shift away the first element to get |
// indices running from 0 again |
$key = array_shift($row); |
if ($group) { |
$results[$key][] = $row; |
} else { |
$results[$key] = $row; |
} |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} else { |
// return scalar values |
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { |
if ($group) { |
$results[$row[0]][] = $row[1]; |
} else { |
$results[$row[0]] = $row[1]; |
} |
} |
if (DB::isError($row)) { |
$results = $row; |
} |
} |
$res->free(); |
return $results; |
} |
// }}} |
// {{{ getAll() |
/** |
* Fetches all of the rows from a query result |
* |
* @param string $query the SQL query |
* @param mixed $params array, string or numeric data to be used in |
* execution of the statement. Quantity of |
* items passed must match quantity of |
* placeholders in query: meaning 1 |
* placeholder for non-array parameters or |
* 1 placeholder per array element. |
* @param int $fetchmode the fetch mode to use: |
* + DB_FETCHMODE_ORDERED |
* + DB_FETCHMODE_ASSOC |
* + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED |
* + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED |
* |
* @return array the nested array. A DB_Error object on failure. |
*/ |
function &getAll($query, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT) |
{ |
// compat check, the params and fetchmode parameters used to |
// have the opposite order |
if (!is_array($params)) { |
if (is_array($fetchmode)) { |
if ($params === null) { |
$tmp = DB_FETCHMODE_DEFAULT; |
} else { |
$tmp = $params; |
} |
$params = $fetchmode; |
$fetchmode = $tmp; |
} elseif ($params !== null) { |
$fetchmode = $params; |
$params = array(); |
} |
} |
if (sizeof($params) > 0) { |
$sth = $this->prepare($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$res = $this->execute($sth, $params); |
$this->freePrepared($sth); |
} else { |
$res = $this->query($query); |
} |
if ($res === DB_OK || DB::isError($res)) { |
return $res; |
} |
$results = array(); |
while (DB_OK === $res->fetchInto($row, $fetchmode)) { |
if ($fetchmode & DB_FETCHMODE_FLIPPED) { |
foreach ($row as $key => $val) { |
$results[$key][] = $val; |
} |
} else { |
$results[] = $row; |
} |
} |
$res->free(); |
if (DB::isError($row)) { |
$tmp = $this->raiseError($row); |
return $tmp; |
} |
return $results; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enables or disables automatic commits |
* |
* @param bool $onoff true turns it on, false turns it off |
* |
* @return int DB_OK on success. A DB_Error object if the driver |
* doesn't support auto-committing transactions. |
*/ |
function autoCommit($onoff = false) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ commit() |
/** |
* Commits the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function commit() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ rollback() |
/** |
* Reverts the current transaction |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
*/ |
function rollback() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numRows() |
/** |
* Determines the number of rows in a query result |
* |
* @param resource $result the query result idenifier produced by PHP |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function numRows($result) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Determines the number of rows affected by a data maniuplation query |
* |
* 0 is returned for queries that don't manipulate data. |
* |
* @return int the number of rows. A DB_Error object on failure. |
*/ |
function affectedRows() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getSequenceName() |
/** |
* Generates the name used inside the database for a sequence |
* |
* The createSequence() docblock contains notes about storing sequence |
* names. |
* |
* @param string $sqn the sequence's public name |
* |
* @return string the sequence's name in the backend |
* |
* @access protected |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::nextID(), DB_common::setOption() |
*/ |
function getSequenceName($sqn) |
{ |
return sprintf($this->getOption('seqname_format'), |
preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); |
} |
// }}} |
// {{{ nextId() |
/** |
* Returns the next free id in a sequence |
* |
* @param string $seq_name name of the sequence |
* @param boolean $ondemand when true, the seqence is automatically |
* created if it does not exist |
* |
* @return int the next id number in the sequence. |
* A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::getSequenceName() |
*/ |
function nextId($seq_name, $ondemand = true) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ createSequence() |
/** |
* Creates a new sequence |
* |
* The name of a given sequence is determined by passing the string |
* provided in the <var>$seq_name</var> argument through PHP's sprintf() |
* function using the value from the <var>seqname_format</var> option as |
* the sprintf()'s format argument. |
* |
* <var>seqname_format</var> is set via setOption(). |
* |
* @param string $seq_name name of the new sequence |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function createSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ dropSequence() |
/** |
* Deletes a sequence |
* |
* @param string $seq_name name of the sequence to be deleted |
* |
* @return int DB_OK on success. A DB_Error object on failure. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
*/ |
function dropSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ raiseError() |
/** |
* Communicates an error and invoke error callbacks, etc |
* |
* Basically a wrapper for PEAR::raiseError without the message string. |
* |
* @param mixed integer error code, or a PEAR error object (all |
* other parameters are ignored if this parameter is |
* an object |
* @param int error mode, see PEAR_Error docs |
* @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the |
* error level (E_USER_NOTICE etc). If error mode is |
* PEAR_ERROR_CALLBACK, this is the callback function, |
* either as a function name, or as an array of an |
* object and method name. For other error modes this |
* parameter is ignored. |
* @param string extra debug information. Defaults to the last |
* query and native error code. |
* @param mixed native error code, integer or string depending the |
* backend |
* |
* @return object the PEAR_Error object |
* |
* @see PEAR_Error |
*/ |
function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
$userinfo = null, $nativecode = null) |
{ |
// The error is yet a DB error object |
if (is_object($code)) { |
// because we the static PEAR::raiseError, our global |
// handler should be used if it is set |
if ($mode === null && !empty($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
} |
$tmp = PEAR::raiseError($code, null, $mode, $options, |
null, null, true); |
return $tmp; |
} |
if ($userinfo === null) { |
$userinfo = $this->last_query; |
} |
if ($nativecode) { |
$userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
} else { |
$userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']'; |
} |
$tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
'DB_Error', true); |
return $tmp; |
} |
// }}} |
// {{{ errorNative() |
/** |
* Gets the DBMS' native error code produced by the last query |
* |
* @return mixed the DBMS' error code. A DB_Error object on failure. |
*/ |
function errorNative() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ errorCode() |
/** |
* Maps native error codes to DB's portable ones |
* |
* Uses the <var>$errorcode_map</var> property defined in each driver. |
* |
* @param string|int $nativecode the error code returned by the DBMS |
* |
* @return int the portable DB error code. Return DB_ERROR if the |
* current driver doesn't have a mapping for the |
* $nativecode submitted. |
*/ |
function errorCode($nativecode) |
{ |
if (isset($this->errorcode_map[$nativecode])) { |
return $this->errorcode_map[$nativecode]; |
} |
// Fall back to DB_ERROR if there was no mapping. |
return DB_ERROR; |
} |
// }}} |
// {{{ errorMessage() |
/** |
* Maps a DB error code to a textual message |
* |
* @param integer $dbcode the DB error code |
* |
* @return string the error message corresponding to the error code |
* submitted. FALSE if the error code is unknown. |
* |
* @see DB::errorMessage() |
*/ |
function errorMessage($dbcode) |
{ |
return DB::errorMessage($this->errorcode_map[$dbcode]); |
} |
// }}} |
// {{{ tableInfo() |
/** |
* Returns information about a table or a result set |
* |
* The format of the resulting array depends on which <var>$mode</var> |
* you select. The sample output below is based on this query: |
* <pre> |
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId |
* FROM tblFoo |
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId |
* </pre> |
* |
* <ul> |
* <li> |
* |
* <kbd>null</kbd> (default) |
* <pre> |
* [0] => Array ( |
* [table] => tblFoo |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* [1] => Array ( |
* [table] => tblFoo |
* [name] => fldPhone |
* [type] => string |
* [len] => 20 |
* [flags] => |
* ) |
* [2] => Array ( |
* [table] => tblBar |
* [name] => fldId |
* [type] => int |
* [len] => 11 |
* [flags] => primary_key not_null |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDER</kbd> |
* |
* <p>In addition to the information found in the default output, |
* a notation of the number of columns is provided by the |
* <samp>num_fields</samp> element while the <samp>order</samp> |
* element provides an array with the column names as the keys and |
* their location index number (corresponding to the keys in the |
* the default output) as the values.</p> |
* |
* <p>If a result set has identical field names, the last one is |
* used.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [order] => Array ( |
* [fldId] => 2 |
* [fldTrans] => 1 |
* ) |
* </pre> |
* |
* </li><li> |
* |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd> |
* |
* <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more |
* dimensions to the array in which the table names are keys and |
* the field names are sub-keys. This is helpful for queries that |
* join tables which have identical field names.</p> |
* |
* <pre> |
* [num_fields] => 3 |
* [ordertable] => Array ( |
* [tblFoo] => Array ( |
* [fldId] => 0 |
* [fldPhone] => 1 |
* ) |
* [tblBar] => Array ( |
* [fldId] => 2 |
* ) |
* ) |
* </pre> |
* |
* </li> |
* </ul> |
* |
* The <samp>flags</samp> element contains a space separated list |
* of extra information about the field. This data is inconsistent |
* between DBMS's due to the way each DBMS works. |
* + <samp>primary_key</samp> |
* + <samp>unique_key</samp> |
* + <samp>multiple_key</samp> |
* + <samp>not_null</samp> |
* |
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp> |
* elements if <var>$result</var> is a table name. The following DBMS's |
* provide full information from queries: |
* + fbsql |
* + mysql |
* |
* If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp> |
* turned on, the names of tables and fields will be lowercased. |
* |
* @param object|string $result DB_result object from a query or a |
* string containing the name of a table. |
* While this also accepts a query result |
* resource identifier, this behavior is |
* deprecated. |
* @param int $mode either unused or one of the tableInfo modes: |
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd>, |
* <kbd>DB_TABLEINFO_ORDER</kbd> or |
* <kbd>DB_TABLEINFO_FULL</kbd> (which does both). |
* These are bitwise, so the first two can be |
* combined using <kbd>|</kbd>. |
* |
* @return array an associative array with the information requested. |
* A DB_Error object on failure. |
* |
* @see DB_common::setOption() |
*/ |
function tableInfo($result, $mode = null) |
{ |
/* |
* If the DB_<driver> class has a tableInfo() method, that one |
* overrides this one. But, if the driver doesn't have one, |
* this method runs and tells users about that fact. |
*/ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getTables() |
/** |
* Lists the tables in the current database |
* |
* @return array the list of tables. A DB_Error object on failure. |
* |
* @deprecated Method deprecated some time before Release 1.2 |
*/ |
function getTables() |
{ |
return $this->getListOf('tables'); |
} |
// }}} |
// {{{ getListOf() |
/** |
* Lists internal database information |
* |
* @param string $type type of information being sought. |
* Common items being sought are: |
* tables, databases, users, views, functions |
* Each DBMS's has its own capabilities. |
* |
* @return array an array listing the items sought. |
* A DB DB_Error object on failure. |
*/ |
function getListOf($type) |
{ |
$sql = $this->getSpecialQuery($type); |
if ($sql === null) { |
$this->last_query = ''; |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} elseif (is_int($sql) || DB::isError($sql)) { |
// Previous error |
return $this->raiseError($sql); |
} elseif (is_array($sql)) { |
// Already the result |
return $sql; |
} |
// Launch this query |
return $this->getCol($sql); |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Obtains the query string needed for listing a given type of objects |
* |
* @param string $type the kind of objects you want to retrieve |
* |
* @return string the SQL query string or null if the driver doesn't |
* support the object type requested |
* |
* @access protected |
* @see DB_common::getListOf() |
*/ |
function getSpecialQuery($type) |
{ |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} |
// }}} |
// {{{ nextQueryIsManip() |
/** |
* Sets (or unsets) a flag indicating that the next query will be a |
* manipulation query, regardless of the usual DB::isManip() heuristics. |
* |
* @param boolean true to set the flag overriding the isManip() behaviour, |
* false to clear it and fall back onto isManip() |
* |
* @return void |
* |
* @access public |
*/ |
function nextQueryIsManip($manip) |
{ |
$this->_next_query_manip = $manip; |
} |
// }}} |
// {{{ _checkManip() |
/** |
* Checks if the given query is a manipulation query. This also takes into |
* account the _next_query_manip flag and sets the _last_query_manip flag |
* (and resets _next_query_manip) according to the result. |
* |
* @param string The query to check. |
* |
* @return boolean true if the query is a manipulation query, false |
* otherwise |
* |
* @access protected |
*/ |
function _checkManip($query) |
{ |
if ($this->_next_query_manip || DB::isManip($query)) { |
$this->_last_query_manip = true; |
} else { |
$this->_last_query_manip = false; |
} |
$this->_next_query_manip = false; |
return $this->_last_query_manip; |
$manip = $this->_next_query_manip; |
} |
// }}} |
// {{{ _rtrimArrayValues() |
/** |
* Right-trims all strings in an array |
* |
* @param array $array the array to be trimmed (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _rtrimArrayValues(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_string($value)) { |
$array[$key] = rtrim($value); |
} |
} |
} |
// }}} |
// {{{ _convertNullArrayValuesToEmpty() |
/** |
* Converts all null values in an array to empty strings |
* |
* @param array $array the array to be de-nullified (passed by reference) |
* |
* @return void |
* |
* @access protected |
*/ |
function _convertNullArrayValuesToEmpty(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_null($value)) { |
$array[$key] = ''; |
} |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/tags/0.9.2/lib/DB/storage.php |
---|
Новый файл |
0,0 → 1,506 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Provides an object interface to a table row |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <stig@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: storage.php,v 1.24 2007/08/12 05:27:25 aharvey Exp $ |
* @link http://pear.php.net/package/DB |
*/ |
/** |
* Obtain the DB class so it can be extended from |
*/ |
require_once 'DB.php'; |
/** |
* Provides an object interface to a table row |
* |
* It lets you add, delete and change rows using objects rather than SQL |
* statements. |
* |
* @category Database |
* @package DB |
* @author Stig Bakken <stig@php.net> |
* @copyright 1997-2007 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.7.13 |
* @link http://pear.php.net/package/DB |
*/ |
class DB_storage extends PEAR |
{ |
// {{{ properties |
/** the name of the table (or view, if the backend database supports |
updates in views) we hold data from */ |
var $_table = null; |
/** which column(s) in the table contains primary keys, can be a |
string for single-column primary keys, or an array of strings |
for multiple-column primary keys */ |
var $_keycolumn = null; |
/** DB connection handle used for all transactions */ |
var $_dbh = null; |
/** an assoc with the names of database fields stored as properties |
in this object */ |
var $_properties = array(); |
/** an assoc with the names of the properties in this object that |
have been changed since they were fetched from the database */ |
var $_changes = array(); |
/** flag that decides if data in this object can be changed. |
objects that don't have their table's key column in their |
property lists will be flagged as read-only. */ |
var $_readonly = false; |
/** function or method that implements a validator for fields that |
are set, this validator function returns true if the field is |
valid, false if not */ |
var $_validator = null; |
// }}} |
// {{{ constructor |
/** |
* Constructor |
* |
* @param $table string the name of the database table |
* |
* @param $keycolumn mixed string with name of key column, or array of |
* strings if the table has a primary key of more than one column |
* |
* @param $dbh object database connection object |
* |
* @param $validator mixed function or method used to validate |
* each new value, called with three parameters: the name of the |
* field/column that is changing, a reference to the new value and |
* a reference to this object |
* |
*/ |
function DB_storage($table, $keycolumn, &$dbh, $validator = null) |
{ |
$this->PEAR('DB_Error'); |
$this->_table = $table; |
$this->_keycolumn = $keycolumn; |
$this->_dbh = $dbh; |
$this->_readonly = false; |
$this->_validator = $validator; |
} |
// }}} |
// {{{ _makeWhere() |
/** |
* Utility method to build a "WHERE" clause to locate ourselves in |
* the table. |
* |
* XXX future improvement: use rowids? |
* |
* @access private |
*/ |
function _makeWhere($keyval = null) |
{ |
if (is_array($this->_keycolumn)) { |
if ($keyval === null) { |
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { |
$keyval[] = $this->{$this->_keycolumn[$i]}; |
} |
} |
$whereclause = ''; |
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { |
if ($i > 0) { |
$whereclause .= ' AND '; |
} |
$whereclause .= $this->_keycolumn[$i]; |
if (is_null($keyval[$i])) { |
// there's not much point in having a NULL key, |
// but we support it anyway |
$whereclause .= ' IS NULL'; |
} else { |
$whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]); |
} |
} |
} else { |
if ($keyval === null) { |
$keyval = @$this->{$this->_keycolumn}; |
} |
$whereclause = $this->_keycolumn; |
if (is_null($keyval)) { |
// there's not much point in having a NULL key, |
// but we support it anyway |
$whereclause .= ' IS NULL'; |
} else { |
$whereclause .= ' = ' . $this->_dbh->quote($keyval); |
} |
} |
return $whereclause; |
} |
// }}} |
// {{{ setup() |
/** |
* Method used to initialize a DB_storage object from the |
* configured table. |
* |
* @param $keyval mixed the key[s] of the row to fetch (string or array) |
* |
* @return int DB_OK on success, a DB error if not |
*/ |
function setup($keyval) |
{ |
$whereclause = $this->_makeWhere($keyval); |
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause; |
$sth = $this->_dbh->query($query); |
if (DB::isError($sth)) { |
return $sth; |
} |
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC); |
if (DB::isError($row)) { |
return $row; |
} |
if (!$row) { |
return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
$query, null, true); |
} |
foreach ($row as $key => $value) { |
$this->_properties[$key] = true; |
$this->$key = $value; |
} |
return DB_OK; |
} |
// }}} |
// {{{ insert() |
/** |
* Create a new (empty) row in the configured table for this |
* object. |
*/ |
function insert($newpk) |
{ |
if (is_array($this->_keycolumn)) { |
$primarykey = $this->_keycolumn; |
} else { |
$primarykey = array($this->_keycolumn); |
} |
settype($newpk, "array"); |
for ($i = 0; $i < sizeof($primarykey); $i++) { |
$pkvals[] = $this->_dbh->quote($newpk[$i]); |
} |
$sth = $this->_dbh->query("INSERT INTO $this->_table (" . |
implode(",", $primarykey) . ") VALUES(" . |
implode(",", $pkvals) . ")"); |
if (DB::isError($sth)) { |
return $sth; |
} |
if (sizeof($newpk) == 1) { |
$newpk = $newpk[0]; |
} |
$this->setup($newpk); |
} |
// }}} |
// {{{ toString() |
/** |
* Output a simple description of this DB_storage object. |
* @return string object description |
*/ |
function toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= " (table="; |
$info .= $this->_table; |
$info .= ", keycolumn="; |
if (is_array($this->_keycolumn)) { |
$info .= "(" . implode(",", $this->_keycolumn) . ")"; |
} else { |
$info .= $this->_keycolumn; |
} |
$info .= ", dbh="; |
if (is_object($this->_dbh)) { |
$info .= $this->_dbh->toString(); |
} else { |
$info .= "null"; |
} |
$info .= ")"; |
if (sizeof($this->_properties)) { |
$info .= " [loaded, key="; |
$keyname = $this->_keycolumn; |
if (is_array($keyname)) { |
$info .= "("; |
for ($i = 0; $i < sizeof($keyname); $i++) { |
if ($i > 0) { |
$info .= ","; |
} |
$info .= $this->$keyname[$i]; |
} |
$info .= ")"; |
} else { |
$info .= $this->$keyname; |
} |
$info .= "]"; |
} |
if (sizeof($this->_changes)) { |
$info .= " [modified]"; |
} |
return $info; |
} |
// }}} |
// {{{ dump() |
/** |
* Dump the contents of this object to "standard output". |
*/ |
function dump() |
{ |
foreach ($this->_properties as $prop => $foo) { |
print "$prop = "; |
print htmlentities($this->$prop); |
print "<br />\n"; |
} |
} |
// }}} |
// {{{ &create() |
/** |
* Static method used to create new DB storage objects. |
* @param $data assoc. array where the keys are the names |
* of properties/columns |
* @return object a new instance of DB_storage or a subclass of it |
*/ |
function &create($table, &$data) |
{ |
$classname = strtolower(get_class($this)); |
$obj = new $classname($table); |
foreach ($data as $name => $value) { |
$obj->_properties[$name] = true; |
$obj->$name = &$value; |
} |
return $obj; |
} |
// }}} |
// {{{ loadFromQuery() |
/** |
* Loads data into this object from the given query. If this |
* object already contains table data, changes will be saved and |
* the object re-initialized first. |
* |
* @param $query SQL query |
* |
* @param $params parameter list in case you want to use |
* prepare/execute mode |
* |
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the |
* returned object is read-only (because the object's specified |
* key column was not found among the columns returned by $query), |
* or another DB error code in case of errors. |
*/ |
// XXX commented out for now |
/* |
function loadFromQuery($query, $params = null) |
{ |
if (sizeof($this->_properties)) { |
if (sizeof($this->_changes)) { |
$this->store(); |
$this->_changes = array(); |
} |
$this->_properties = array(); |
} |
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params); |
if (DB::isError($rowdata)) { |
return $rowdata; |
} |
reset($rowdata); |
$found_keycolumn = false; |
while (list($key, $value) = each($rowdata)) { |
if ($key == $this->_keycolumn) { |
$found_keycolumn = true; |
} |
$this->_properties[$key] = true; |
$this->$key = &$value; |
unset($value); // have to unset, or all properties will |
// refer to the same value |
} |
if (!$found_keycolumn) { |
$this->_readonly = true; |
return DB_WARNING_READ_ONLY; |
} |
return DB_OK; |
} |
*/ |
// }}} |
// {{{ set() |
/** |
* Modify an attriute value. |
*/ |
function set($property, $newvalue) |
{ |
// only change if $property is known and object is not |
// read-only |
if ($this->_readonly) { |
return $this->raiseError(null, DB_WARNING_READ_ONLY, null, |
null, null, null, true); |
} |
if (@isset($this->_properties[$property])) { |
if (empty($this->_validator)) { |
$valid = true; |
} else { |
$valid = @call_user_func($this->_validator, |
$this->_table, |
$property, |
$newvalue, |
$this->$property, |
$this); |
} |
if ($valid) { |
$this->$property = $newvalue; |
if (empty($this->_changes[$property])) { |
$this->_changes[$property] = 0; |
} else { |
$this->_changes[$property]++; |
} |
} else { |
return $this->raiseError(null, DB_ERROR_INVALID, null, |
null, "invalid field: $property", |
null, true); |
} |
return true; |
} |
return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null, |
null, "unknown field: $property", |
null, true); |
} |
// }}} |
// {{{ &get() |
/** |
* Fetch an attribute value. |
* |
* @param string attribute name |
* |
* @return attribute contents, or null if the attribute name is |
* unknown |
*/ |
function &get($property) |
{ |
// only return if $property is known |
if (isset($this->_properties[$property])) { |
return $this->$property; |
} |
$tmp = null; |
return $tmp; |
} |
// }}} |
// {{{ _DB_storage() |
/** |
* Destructor, calls DB_storage::store() if there are changes |
* that are to be kept. |
*/ |
function _DB_storage() |
{ |
if (sizeof($this->_changes)) { |
$this->store(); |
} |
$this->_properties = array(); |
$this->_changes = array(); |
$this->_table = null; |
} |
// }}} |
// {{{ store() |
/** |
* Stores changes to this object in the database. |
* |
* @return DB_OK or a DB error |
*/ |
function store() |
{ |
$params = array(); |
$vars = array(); |
foreach ($this->_changes as $name => $foo) { |
$params[] = &$this->$name; |
$vars[] = $name . ' = ?'; |
} |
if ($vars) { |
$query = 'UPDATE ' . $this->_table . ' SET ' . |
implode(', ', $vars) . ' WHERE ' . |
$this->_makeWhere(); |
$stmt = $this->_dbh->prepare($query); |
$res = $this->_dbh->execute($stmt, $params); |
if (DB::isError($res)) { |
return $res; |
} |
$this->_changes = array(); |
} |
return DB_OK; |
} |
// }}} |
// {{{ remove() |
/** |
* Remove the row represented by this object from the database. |
* |
* @return mixed DB_OK or a DB error |
*/ |
function remove() |
{ |
if ($this->_readonly) { |
return $this->raiseError(null, DB_WARNING_READ_ONLY, null, |
null, null, null, true); |
} |
$query = 'DELETE FROM ' . $this->_table .' WHERE '. |
$this->_makeWhere(); |
$res = $this->_dbh->query($query); |
if (DB::isError($res)) { |
return $res; |
} |
foreach ($this->_properties as $prop => $foo) { |
unset($this->$prop); |
} |
$this->_properties = array(); |
$this->_changes = array(); |
return DB_OK; |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/tags/0.9.2/img/bg.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/tags/0.9.2/img/bg.gif |
---|
Новый файл |
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/mail.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/mail.png |
=================================================================== |
--- tags/0.9.2/img/m/mail.png (revision 0) |
+++ tags/0.9.2/img/m/mail.png (revision 708) |
/tags/0.9.2/img/m/mail.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/nf.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/nf.png |
=================================================================== |
--- tags/0.9.2/img/m/nf.png (revision 0) |
+++ tags/0.9.2/img/m/nf.png (revision 708) |
/tags/0.9.2/img/m/nf.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/wiki.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/wiki.png |
=================================================================== |
--- tags/0.9.2/img/m/wiki.png (revision 0) |
+++ tags/0.9.2/img/m/wiki.png (revision 708) |
/tags/0.9.2/img/m/wiki.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/main.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/main.png |
=================================================================== |
--- tags/0.9.2/img/m/main.png (revision 0) |
+++ tags/0.9.2/img/m/main.png (revision 708) |
/tags/0.9.2/img/m/main.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/track.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/track.png |
=================================================================== |
--- tags/0.9.2/img/m/track.png (revision 0) |
+++ tags/0.9.2/img/m/track.png (revision 708) |
/tags/0.9.2/img/m/track.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/jabber.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/jabber.png |
=================================================================== |
--- tags/0.9.2/img/m/jabber.png (revision 0) |
+++ tags/0.9.2/img/m/jabber.png (revision 708) |
/tags/0.9.2/img/m/jabber.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/svn.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/svn.png |
=================================================================== |
--- tags/0.9.2/img/m/svn.png (revision 0) |
+++ tags/0.9.2/img/m/svn.png (revision 708) |
/tags/0.9.2/img/m/svn.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/m/forum.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/m/forum.png |
=================================================================== |
--- tags/0.9.2/img/m/forum.png (revision 0) |
+++ tags/0.9.2/img/m/forum.png (revision 708) |
/tags/0.9.2/img/m/forum.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/d/empty-logo.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/d/empty-logo.png |
=================================================================== |
--- tags/0.9.2/img/d/empty-logo.png (revision 0) |
+++ tags/0.9.2/img/d/empty-logo.png (revision 708) |
/tags/0.9.2/img/d/empty-logo.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/v/valid-html40-blue.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/v/valid-html40-blue.png |
=================================================================== |
--- tags/0.9.2/img/v/valid-html40-blue.png (revision 0) |
+++ tags/0.9.2/img/v/valid-html40-blue.png (revision 708) |
/tags/0.9.2/img/v/valid-html40-blue.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |
Index: tags/0.9.2/img/v/vcss-blue.png |
=================================================================== |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: tags/0.9.2/img/v/vcss-blue.png |
=================================================================== |
--- tags/0.9.2/img/v/vcss-blue.png (revision 0) |
+++ tags/0.9.2/img/v/vcss-blue.png (revision 708) |
/tags/0.9.2/img/v/vcss-blue.png |
---|
Изменения свойств: |
Added: svn:mime-type |
## -0,0 +1 ## |
+application/octet-stream |
\ No newline at end of property |