Fix merge conflicts
This commit is contained in:
commit
227ada3257
|
@ -19,10 +19,12 @@ _darcs/*
|
|||
CVS/*
|
||||
.svn/*
|
||||
RCS/*
|
||||
*.backup*
|
||||
|
||||
# kdevelop
|
||||
.kdev
|
||||
*.kdev4
|
||||
*.kate-swp
|
||||
|
||||
# Lokalize
|
||||
*lokalize*
|
||||
|
|
182
.tx/config
182
.tx/config
|
@ -1,182 +0,0 @@
|
|||
[main]
|
||||
host = https://www.transifex.net
|
||||
|
||||
[owncloud.core]
|
||||
file_filter = l10n/<lang>/core.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/core.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/core.po
|
||||
trans.ca = l10n/ca/core.po
|
||||
trans.cs_CZ = l10n/cs_CZ/core.po
|
||||
trans.da = l10n/da/core.po
|
||||
trans.de = l10n/de/core.po
|
||||
trans.el = l10n/el/core.po
|
||||
trans.es = l10n/es/core.po
|
||||
trans.et_EE = l10n/et_EE/core.po
|
||||
trans.fr = l10n/fr/core.po
|
||||
trans.id = l10n/id/core.po
|
||||
trans.it = l10n/it/core.po
|
||||
trans.lb = l10n/lb/core.po
|
||||
trans.ms_MY = l10n/ms_MY/core.po
|
||||
trans.nb_NO = l10n/nb_NO/core.po
|
||||
trans.nl = l10n/nl/core.po
|
||||
trans.pl = l10n/pl/core.po
|
||||
trans.pt_BR = l10n/pt_BR/core.po
|
||||
trans.pt_PT = l10n/pt_PT/core.po
|
||||
trans.ro = l10n/ro/core.po
|
||||
trans.ru = l10n/ru/core.po
|
||||
trans.sr = l10n/sr/core.po
|
||||
trans.sr@latin = l10n/sr@latin/core.po
|
||||
trans.sv = l10n/sv/core.po
|
||||
trans.zh_CN = l10n/zh_CN/core.po
|
||||
|
||||
[owncloud.settings]
|
||||
file_filter = l10n/<lang>/settings.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/settings.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/settings.po
|
||||
trans.ca = l10n/ca/settings.po
|
||||
trans.cs_CZ = l10n/cs_CZ/settings.po
|
||||
trans.da = l10n/da/settings.po
|
||||
trans.de = l10n/de/settings.po
|
||||
trans.el = l10n/el/settings.po
|
||||
trans.es = l10n/es/settings.po
|
||||
trans.et_EE = l10n/et_EE/settings.po
|
||||
trans.fr = l10n/fr/settings.po
|
||||
trans.id = l10n/id/settings.po
|
||||
trans.it = l10n/it/settings.po
|
||||
trans.lb = l10n/lb/settings.po
|
||||
trans.ms_MY = l10n/ms_MY/settings.po
|
||||
trans.nb_NO = l10n/nb_NO/settings.po
|
||||
trans.nl = l10n/nl/settings.po
|
||||
trans.pl = l10n/pl/settings.po
|
||||
trans.pt_BR = l10n/pt_BR/settings.po
|
||||
trans.pt_PT = l10n/pt_PT/settings.po
|
||||
trans.ro = l10n/ro/settings.po
|
||||
trans.ru = l10n/ru/settings.po
|
||||
trans.sr = l10n/sr/settings.po
|
||||
trans.sr@latin = l10n/sr@latin/settings.po
|
||||
trans.sv = l10n/sv/settings.po
|
||||
trans.zh_CN = l10n/zh_CN/settings.po
|
||||
|
||||
[owncloud.files]
|
||||
file_filter = translations/owncloud.files/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/files.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/files.po
|
||||
trans.ca = l10n/ca/files.po
|
||||
trans.cs_CZ = l10n/cs_CZ/files.po
|
||||
trans.da = l10n/da/files.po
|
||||
trans.de = l10n/de/files.po
|
||||
trans.el = l10n/el/files.po
|
||||
trans.es = l10n/es/files.po
|
||||
trans.et_EE = l10n/et_EE/files.po
|
||||
trans.fr = l10n/fr/files.po
|
||||
trans.id = l10n/id/files.po
|
||||
trans.it = l10n/it/files.po
|
||||
trans.lb = l10n/lb/files.po
|
||||
trans.ms_MY = l10n/ms_MY/files.po
|
||||
trans.nb_NO = l10n/nb_NO/files.po
|
||||
trans.nl = l10n/nl/files.po
|
||||
trans.pl = l10n/pl/files.po
|
||||
trans.pt_BR = l10n/pt_BR/files.po
|
||||
trans.pt_PT = l10n/pt_PT/files.po
|
||||
trans.ro = l10n/ro/files.po
|
||||
trans.ru = l10n/ru/files.po
|
||||
trans.sr = l10n/sr/files.po
|
||||
trans.sr@latin = l10n/sr@latin/files.po
|
||||
trans.sv = l10n/sv/files.po
|
||||
trans.zh_CN = l10n/zh_CN/files.po
|
||||
|
||||
[owncloud.media]
|
||||
file_filter = translations/owncloud.media/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/media.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/media.po
|
||||
trans.ca = l10n/ca/media.po
|
||||
trans.cs_CZ = l10n/cs_CZ/media.po
|
||||
trans.da = l10n/da/media.po
|
||||
trans.de = l10n/de/media.po
|
||||
trans.el = l10n/el/media.po
|
||||
trans.es = l10n/es/media.po
|
||||
trans.et_EE = l10n/et_EE/media.po
|
||||
trans.fr = l10n/fr/media.po
|
||||
trans.id = l10n/id/media.po
|
||||
trans.it = l10n/it/media.po
|
||||
trans.lb = l10n/lb/media.po
|
||||
trans.ms_MY = l10n/ms_MY/media.po
|
||||
trans.nb_NO = l10n/nb_NO/media.po
|
||||
trans.nl = l10n/nl/media.po
|
||||
trans.pl = l10n/pl/media.po
|
||||
trans.pt_BR = l10n/pt_BR/media.po
|
||||
trans.pt_PT = l10n/pt_PT/media.po
|
||||
trans.ro = l10n/ro/media.po
|
||||
trans.ru = l10n/ru/media.po
|
||||
trans.sr = l10n/sr/media.po
|
||||
trans.sr@latin = l10n/sr@latin/media.po
|
||||
trans.sv = l10n/sv/media.po
|
||||
trans.zh_CN = l10n/zh_CN/media.po
|
||||
|
||||
[owncloud.calendar]
|
||||
file_filter = l10n/<lang>/calendar.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/calendar.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/calendar.po
|
||||
trans.ca = l10n/ca/calendar.po
|
||||
trans.cs_CZ = l10n/cs_CZ/calendar.po
|
||||
trans.da = l10n/da/calendar.po
|
||||
trans.de = l10n/de/calendar.po
|
||||
trans.el = l10n/el/calendar.po
|
||||
trans.es = l10n/es/calendar.po
|
||||
trans.et_EE = l10n/et_EE/calendar.po
|
||||
trans.fr = l10n/fr/calendar.po
|
||||
trans.id = l10n/id/calendar.po
|
||||
trans.it = l10n/it/calendar.po
|
||||
trans.lb = l10n/lb/calendar.po
|
||||
trans.ms_MY = l10n/ms_MY/calendar.po
|
||||
trans.nb_NO = l10n/nb_NO/calendar.po
|
||||
trans.nl = l10n/nl/calendar.po
|
||||
trans.pl = l10n/pl/calendar.po
|
||||
trans.pt_BR = l10n/pt_BR/calendar.po
|
||||
trans.pt_PT = l10n/pt_PT/calendar.po
|
||||
trans.ro = l10n/ro/calendar.po
|
||||
trans.ru = l10n/ru/calendar.po
|
||||
trans.sr = l10n/sr/calendar.po
|
||||
trans.sr@latin = l10n/sr@latin/calendar.po
|
||||
trans.sv = l10n/sv/calendar.po
|
||||
trans.zh_CN = l10n/zh_CN/calendar.po
|
||||
|
||||
[owncloud.contacts]
|
||||
file_filter = translations/owncloud.contacts/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/contacts.pot
|
||||
source_lang = en
|
||||
trans.bg_BG = l10n/bg_BG/contacts.po
|
||||
trans.ca = l10n/ca/contacts.po
|
||||
trans.cs_CZ = l10n/cs_CZ/contacts.po
|
||||
trans.da = l10n/da/contacts.po
|
||||
trans.de = l10n/de/contacts.po
|
||||
trans.el = l10n/el/contacts.po
|
||||
trans.es = l10n/es/contacts.po
|
||||
trans.et_EE = l10n/et_EE/contacts.po
|
||||
trans.fr = l10n/fr/contacts.po
|
||||
trans.id = l10n/id/contacts.po
|
||||
trans.it = l10n/it/contacts.po
|
||||
trans.lb = l10n/lb/contacts.po
|
||||
trans.ms_MY = l10n/ms_MY/contacts.po
|
||||
trans.nb_NO = l10n/nb_NO/contacts.po
|
||||
trans.nl = l10n/nl/contacts.po
|
||||
trans.pl = l10n/pl/contacts.po
|
||||
trans.pt_BR = l10n/pt_BR/contacts.po
|
||||
trans.pt_PT = l10n/pt_PT/contacts.po
|
||||
trans.ro = l10n/ro/contacts.po
|
||||
trans.ru = l10n/ru/contacts.po
|
||||
trans.sr = l10n/sr/contacts.po
|
||||
trans.sr@latin = l10n/sr@latin/contacts.po
|
||||
trans.sv = l10n/sv/contacts.po
|
||||
trans.zh_CN = l10n/zh_CN/contacts.po
|
|
@ -1412,7 +1412,7 @@ class MDB2_Driver_Datatype_Common extends MDB2_Module_Common
|
|||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if (isset($db->function) && is_object($this->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) {
|
||||
if (isset($db->function) && is_object($db->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) {
|
||||
return $db->function->now('timestamp');
|
||||
}
|
||||
return 'CURRENT_TIMESTAMP';
|
||||
|
|
|
@ -0,0 +1,499 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 OCI8 driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_oci8 extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ _baseConvertResult()
|
||||
|
||||
/**
|
||||
* general type conversion method
|
||||
*
|
||||
* @param mixed $value refernce to a value to be converted
|
||||
* @param string $type specifies which type to convert to
|
||||
* @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
|
||||
* @return object a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _baseConvertResult($value, $type, $rtrim = true)
|
||||
{
|
||||
if (null === $value) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
if (is_object($value) && is_a($value, 'OCI-Lob')) {
|
||||
//LOB => fetch into variable
|
||||
$clob = $this->_baseConvertResult($value, 'clob', $rtrim);
|
||||
if (!PEAR::isError($clob) && is_resource($clob)) {
|
||||
$clob_value = '';
|
||||
while (!feof($clob)) {
|
||||
$clob_value .= fread($clob, 8192);
|
||||
}
|
||||
$this->destroyLOB($clob);
|
||||
}
|
||||
$value = $clob_value;
|
||||
}
|
||||
if ($rtrim) {
|
||||
$value = rtrim($value);
|
||||
}
|
||||
return $value;
|
||||
case 'date':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD'));
|
||||
case 'time':
|
||||
return substr($value, strlen('YYYY-MM-DD '), strlen('HH:MI:SS'));
|
||||
}
|
||||
return parent::_baseConvertResult($value, $type, $rtrim);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$length = !empty($field['length'])
|
||||
? $field['length'] : $db->options['default_text_field_length'];
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? 'CHAR('.$length.')' : 'VARCHAR2('.$length.')';
|
||||
case 'clob':
|
||||
return 'CLOB';
|
||||
case 'blob':
|
||||
return 'BLOB';
|
||||
case 'integer':
|
||||
if (!empty($field['length'])) {
|
||||
switch((int)$field['length']) {
|
||||
case 1: $digit = 3; break;
|
||||
case 2: $digit = 5; break;
|
||||
case 3: $digit = 8; break;
|
||||
case 4: $digit = 10; break;
|
||||
case 5: $digit = 13; break;
|
||||
case 6: $digit = 15; break;
|
||||
case 7: $digit = 17; break;
|
||||
case 8: $digit = 20; break;
|
||||
default: $digit = 10;
|
||||
}
|
||||
return 'NUMBER('.$digit.')';
|
||||
}
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'NUMBER(1)';
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
return 'DATE';
|
||||
case 'float':
|
||||
return 'NUMBER';
|
||||
case 'decimal':
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'NUMBER(*,'.$scale.')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteCLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteCLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
return 'EMPTY_CLOB()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
return 'EMPTY_BLOB()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDate()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDate($value, $quote, $escape_wildcards)
|
||||
{
|
||||
return $this->_quoteText("$value 00:00:00", $quote, $escape_wildcards);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTimestamp()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
//function _quoteTimestamp($value, $quote, $escape_wildcards)
|
||||
//{
|
||||
// return $this->_quoteText($value, $quote, $escape_wildcards);
|
||||
//}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTime()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteTime($value, $quote, $escape_wildcards)
|
||||
{
|
||||
return $this->_quoteText("0001-01-01 $value", $quote, $escape_wildcards);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ writeLOBToFile()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param array $lob array
|
||||
* @param string $file name of the file into which the LOb should be fetched
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function writeLOBToFile($lob, $file)
|
||||
{
|
||||
if (preg_match('/^(\w+:\/\/)(.*)$/', $file, $match)) {
|
||||
if ($match[1] == 'file://') {
|
||||
$file = $match[2];
|
||||
}
|
||||
}
|
||||
$lob_data = stream_get_meta_data($lob);
|
||||
$lob_index = $lob_data['wrapper_data']->lob_index;
|
||||
$result = $this->lobs[$lob_index]['resource']->writetofile($file);
|
||||
$this->lobs[$lob_index]['resource']->seek(0);
|
||||
if (!$result) {
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(null, null, null,
|
||||
'Unable to write LOB to file', __FUNCTION__);
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _retrieveLOB()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param array $lob array
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _retrieveLOB(&$lob)
|
||||
{
|
||||
if (!is_object($lob['resource'])) {
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'attemped to retrieve LOB from non existing or NULL column', __FUNCTION__);
|
||||
}
|
||||
|
||||
if (!$lob['loaded']
|
||||
# && !method_exists($lob['resource'], 'read')
|
||||
) {
|
||||
$lob['value'] = $lob['resource']->load();
|
||||
$lob['resource']->seek(0);
|
||||
}
|
||||
$lob['loaded'] = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _readLOB()
|
||||
|
||||
/**
|
||||
* Read data from large object input stream.
|
||||
*
|
||||
* @param array $lob array
|
||||
* @param blob $data reference to a variable that will hold data to be
|
||||
* read from the large object input stream
|
||||
* @param int $length integer value that indicates the largest ammount of
|
||||
* data to be read from the large object input stream.
|
||||
* @return mixed length on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _readLOB($lob, $length)
|
||||
{
|
||||
if ($lob['loaded']) {
|
||||
return parent::_readLOB($lob, $length);
|
||||
}
|
||||
|
||||
if (!is_object($lob['resource'])) {
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'attemped to retrieve LOB from non existing or NULL column', __FUNCTION__);
|
||||
}
|
||||
|
||||
$data = $lob['resource']->read($length);
|
||||
if (!is_string($data)) {
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(null, null, null,
|
||||
'Unable to read LOB', __FUNCTION__);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ patternEscapeString()
|
||||
|
||||
/**
|
||||
* build string to define escape pattern string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*
|
||||
* @return string define escape pattern
|
||||
*/
|
||||
function patternEscapeString()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return " ESCAPE '". $db->string_quoting['escape_pattern'] ."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$type = array();
|
||||
$length = $unsigned = $fixed = null;
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
}
|
||||
switch ($db_type) {
|
||||
case 'integer':
|
||||
case 'pls_integer':
|
||||
case 'binary_integer':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'varchar':
|
||||
case 'varchar2':
|
||||
case 'nvarchar2':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
case 'nchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'number':
|
||||
if (!empty($field['scale'])) {
|
||||
$type[] = 'decimal';
|
||||
$length = $length.','.$field['scale'];
|
||||
} else {
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'long':
|
||||
$type[] = 'text';
|
||||
case 'clob':
|
||||
case 'nclob':
|
||||
$type[] = 'clob';
|
||||
break;
|
||||
case 'blob':
|
||||
case 'raw':
|
||||
case 'long raw':
|
||||
case 'bfile':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'rowid':
|
||||
case 'urowid':
|
||||
default:
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 oci8 driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_oci8 extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'EXEC '.$name;
|
||||
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ functionTable()
|
||||
|
||||
/**
|
||||
* return string for internal table used when calling only a function
|
||||
*
|
||||
* @return string for internal table used when calling only a function
|
||||
* @access public
|
||||
*/
|
||||
function functionTable()
|
||||
{
|
||||
return ' FROM dual';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ now()
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time:
|
||||
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
|
||||
* - CURRENT_DATE (date, DATE type)
|
||||
* - CURRENT_TIME (time, TIME type)
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @access public
|
||||
*/
|
||||
function now($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
$utc_offset = 'CAST(SYS_EXTRACT_UTC(SYSTIMESTAMP) AS DATE) - CAST(SYSTIMESTAMP AS DATE)';
|
||||
$epoch_date = 'to_date(\'19700101\', \'YYYYMMDD\')';
|
||||
return '(CAST('.$expression.' AS DATE) - '.$epoch_date.' + '.$utc_offset.') * 86400 seconds';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (null !== $length) {
|
||||
return "SUBSTR($value, $position, $length)";
|
||||
}
|
||||
return "SUBSTR($value, $position)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return 'dbms_random.value';
|
||||
}
|
||||
|
||||
// }}}}
|
||||
// {{{ guid()
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @access public
|
||||
*/
|
||||
function guid()
|
||||
{
|
||||
return 'SYS_GUID()';
|
||||
}
|
||||
|
||||
// }}}}
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: oci8.php 215004 2006-06-18 21:59:05Z lsmith $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 Oracle driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Native_oci8 extends MDB2_Driver_Native_Common
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,625 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann, Lorenzo Alberton |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Lukas Smith <smith@pooteeweet.org> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 Oracle driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_oci8 extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table_name, $field_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($owner, $table) = $this->splitTableSchema($table_name);
|
||||
if (empty($owner)) {
|
||||
$owner = $db->dsn['username'];
|
||||
}
|
||||
|
||||
$query = 'SELECT column_name AS "name",
|
||||
data_type AS "type",
|
||||
nullable AS "nullable",
|
||||
data_default AS "default",
|
||||
COALESCE(data_precision, data_length) AS "length",
|
||||
data_scale AS "scale"
|
||||
FROM all_tab_columns
|
||||
WHERE (table_name=? OR table_name=?)
|
||||
AND (owner=? OR owner=?)
|
||||
AND (column_name=? OR column_name=?)
|
||||
ORDER BY column_id';
|
||||
$stmt = $db->prepare($query);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$args = array(
|
||||
$table,
|
||||
strtoupper($table),
|
||||
$owner,
|
||||
strtoupper($owner),
|
||||
$field_name,
|
||||
strtoupper($field_name)
|
||||
);
|
||||
$result = $stmt->execute($args);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$column = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($column)) {
|
||||
return $column;
|
||||
}
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
|
||||
if (empty($column)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$field_name . ' is not a column in table ' . $table_name, __FUNCTION__);
|
||||
}
|
||||
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column['name'] = strtolower($column['name']);
|
||||
} else {
|
||||
$column['name'] = strtoupper($column['name']);
|
||||
}
|
||||
}
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (!empty($column['nullable']) && $column['nullable'] == 'N') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if ($default === 'NULL') {
|
||||
$default = null;
|
||||
}
|
||||
//ugly hack, but works for the reverse direction
|
||||
if ($default == "''") {
|
||||
$default = '';
|
||||
}
|
||||
if ((null === $default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
|
||||
$definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
|
||||
if (null !== $length) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (null !== $unsigned) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (null !== $fixed) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
if ($type == 'integer') {
|
||||
$query= "SELECT trigger_body
|
||||
FROM all_triggers
|
||||
WHERE table_name=?
|
||||
AND triggering_event='INSERT'
|
||||
AND trigger_type='BEFORE EACH ROW'";
|
||||
// ^^ pretty reasonable mimic for "auto_increment" in oracle?
|
||||
$stmt = $db->prepare($query);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$result = $stmt->execute(strtoupper($table));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
while ($triggerstr = $result->fetchOne()) {
|
||||
if (preg_match('/.*SELECT\W+(.+)\.nextval +into +\:NEW\.'.$field_name.' +FROM +dual/im', $triggerstr, $matches)) {
|
||||
$definition[0]['autoincrement'] = $matches[1];
|
||||
}
|
||||
}
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table_name, $index_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($owner, $table) = $this->splitTableSchema($table_name);
|
||||
if (empty($owner)) {
|
||||
$owner = $db->dsn['username'];
|
||||
}
|
||||
|
||||
$query = 'SELECT aic.column_name AS "column_name",
|
||||
aic.column_position AS "column_position",
|
||||
aic.descend AS "descend",
|
||||
aic.table_owner AS "table_owner",
|
||||
alc.constraint_type AS "constraint_type"
|
||||
FROM all_ind_columns aic
|
||||
LEFT JOIN all_constraints alc
|
||||
ON aic.index_name = alc.constraint_name
|
||||
AND aic.table_name = alc.table_name
|
||||
AND aic.table_owner = alc.owner
|
||||
WHERE (aic.table_name=? OR aic.table_name=?)
|
||||
AND (aic.index_name=? OR aic.index_name=?)
|
||||
AND (aic.table_owner=? OR aic.table_owner=?)
|
||||
ORDER BY column_position';
|
||||
$stmt = $db->prepare($query);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$indexnames = array_unique(array($db->getIndexName($index_name), $index_name));
|
||||
$i = 0;
|
||||
$row = null;
|
||||
while ((null === $row) && array_key_exists($i, $indexnames)) {
|
||||
$args = array(
|
||||
$table,
|
||||
strtoupper($table),
|
||||
$indexnames[$i],
|
||||
strtoupper($indexnames[$i]),
|
||||
$owner,
|
||||
strtoupper($owner)
|
||||
);
|
||||
$result = $stmt->execute($args);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (null === $row) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name. ' is not an index on table '. $table_name, __FUNCTION__);
|
||||
}
|
||||
if ($row['constraint_type'] == 'U' || $row['constraint_type'] == 'P') {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name. ' is a constraint, not an index on table '. $table_name, __FUNCTION__);
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
while (null !== $row) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => (int)$row['column_position'],
|
||||
);
|
||||
if (!empty($row['descend'])) {
|
||||
$definition['fields'][$column_name]['sorting'] =
|
||||
($row['descend'] == 'ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name. ' is not an index on table '. $table_name, __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($owner, $table) = $this->splitTableSchema($table_name);
|
||||
if (empty($owner)) {
|
||||
$owner = $db->dsn['username'];
|
||||
}
|
||||
|
||||
$query = 'SELECT alc.constraint_name,
|
||||
CASE alc.constraint_type WHEN \'P\' THEN 1 ELSE 0 END "primary",
|
||||
CASE alc.constraint_type WHEN \'R\' THEN 1 ELSE 0 END "foreign",
|
||||
CASE alc.constraint_type WHEN \'U\' THEN 1 ELSE 0 END "unique",
|
||||
CASE alc.constraint_type WHEN \'C\' THEN 1 ELSE 0 END "check",
|
||||
alc.DELETE_RULE "ondelete",
|
||||
\'NO ACTION\' "onupdate",
|
||||
\'SIMPLE\' "match",
|
||||
CASE alc.deferrable WHEN \'NOT DEFERRABLE\' THEN 0 ELSE 1 END "deferrable",
|
||||
CASE alc.deferred WHEN \'IMMEDIATE\' THEN 0 ELSE 1 END "initiallydeferred",
|
||||
alc.search_condition AS "search_condition",
|
||||
alc.table_name,
|
||||
cols.column_name AS "column_name",
|
||||
cols.position,
|
||||
r_alc.table_name "references_table",
|
||||
r_cols.column_name "references_field",
|
||||
r_cols.position "references_field_position"
|
||||
FROM all_cons_columns cols
|
||||
LEFT JOIN all_constraints alc
|
||||
ON alc.constraint_name = cols.constraint_name
|
||||
AND alc.owner = cols.owner
|
||||
LEFT JOIN all_constraints r_alc
|
||||
ON alc.r_constraint_name = r_alc.constraint_name
|
||||
AND alc.r_owner = r_alc.owner
|
||||
LEFT JOIN all_cons_columns r_cols
|
||||
ON r_alc.constraint_name = r_cols.constraint_name
|
||||
AND r_alc.owner = r_cols.owner
|
||||
AND cols.position = r_cols.position
|
||||
WHERE (alc.constraint_name=? OR alc.constraint_name=?)
|
||||
AND alc.constraint_name = cols.constraint_name
|
||||
AND (alc.owner=? OR alc.owner=?)';
|
||||
$tablenames = array();
|
||||
if (!empty($table)) {
|
||||
$query.= ' AND (alc.table_name=? OR alc.table_name=?)';
|
||||
$tablenames = array($table, strtoupper($table));
|
||||
}
|
||||
$stmt = $db->prepare($query);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$constraintnames = array_unique(array($db->getIndexName($constraint_name), $constraint_name));
|
||||
$c = 0;
|
||||
$row = null;
|
||||
while ((null === $row) && array_key_exists($c, $constraintnames)) {
|
||||
$args = array(
|
||||
$constraintnames[$c],
|
||||
strtoupper($constraintnames[$c]),
|
||||
$owner,
|
||||
strtoupper($owner)
|
||||
);
|
||||
if (!empty($table)) {
|
||||
$args = array_merge($args, $tablenames);
|
||||
}
|
||||
$result = $stmt->execute($args);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
$c++;
|
||||
}
|
||||
|
||||
$definition = array(
|
||||
'primary' => (boolean)$row['primary'],
|
||||
'unique' => (boolean)$row['unique'],
|
||||
'foreign' => (boolean)$row['foreign'],
|
||||
'check' => (boolean)$row['check'],
|
||||
'deferrable' => (boolean)$row['deferrable'],
|
||||
'initiallydeferred' => (boolean)$row['initiallydeferred'],
|
||||
'ondelete' => $row['ondelete'],
|
||||
'onupdate' => $row['onupdate'],
|
||||
'match' => $row['match'],
|
||||
);
|
||||
|
||||
if ($definition['check']) {
|
||||
// pattern match constraint for check constraint values into enum-style output:
|
||||
$enumregex = '/'.$row['column_name'].' in \((.+?)\)/i';
|
||||
if (preg_match($enumregex, $row['search_condition'], $rangestr)) {
|
||||
$definition['fields'][$column_name] = array();
|
||||
$allowed = explode(',', $rangestr[1]);
|
||||
foreach ($allowed as $val) {
|
||||
$val = trim($val);
|
||||
$val = preg_replace('/^\'/', '', $val);
|
||||
$val = preg_replace('/\'$/', '', $val);
|
||||
array_push($definition['fields'][$column_name], $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (null !== $row) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => (int)$row['position']
|
||||
);
|
||||
if ($row['foreign']) {
|
||||
$ref_column_name = $row['references_field'];
|
||||
$ref_table_name = $row['references_table'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$ref_column_name = strtolower($ref_column_name);
|
||||
$ref_table_name = strtolower($ref_table_name);
|
||||
} else {
|
||||
$ref_column_name = strtoupper($ref_column_name);
|
||||
$ref_table_name = strtoupper($ref_table_name);
|
||||
}
|
||||
}
|
||||
$definition['references']['table'] = $ref_table_name;
|
||||
$definition['references']['fields'][$ref_column_name] = array(
|
||||
'position' => (int)$row['references_field_position']
|
||||
);
|
||||
}
|
||||
$lastrow = $row;
|
||||
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not a constraint on table '. $table_name, __FUNCTION__);
|
||||
}
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSequenceDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a sequence into an array
|
||||
*
|
||||
* @param string $sequence name of sequence that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getSequenceDefinition($sequence)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($sequence);
|
||||
$query = 'SELECT last_number FROM user_sequences';
|
||||
$query.= ' WHERE sequence_name='.$db->quote($sequence_name, 'text');
|
||||
$query.= ' OR sequence_name='.$db->quote(strtoupper($sequence_name), 'text');
|
||||
$start = $db->queryOne($query, 'integer');
|
||||
if (PEAR::isError($start)) {
|
||||
return $start;
|
||||
}
|
||||
$definition = array();
|
||||
if ($start != 1) {
|
||||
$definition = array('start' => $start);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT trigger_name AS "trigger_name",
|
||||
table_name AS "table_name",
|
||||
trigger_body AS "trigger_body",
|
||||
trigger_type AS "trigger_type",
|
||||
triggering_event AS "trigger_event",
|
||||
description AS "trigger_comment",
|
||||
1 AS "trigger_enabled",
|
||||
when_clause AS "when_clause"
|
||||
FROM user_triggers
|
||||
WHERE trigger_name = \''. strtoupper($trigger).'\'';
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
'trigger_comment' => 'text',
|
||||
'trigger_enabled' => 'boolean',
|
||||
'when_clause' => 'text',
|
||||
);
|
||||
$result = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if (!empty($result['trigger_type'])) {
|
||||
//$result['trigger_type'] = array_shift(explode(' ', $result['trigger_type']));
|
||||
$result['trigger_type'] = preg_replace('/(\S+).*/', '\\1', $result['trigger_type']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* NOTE: flags won't contain index information.
|
||||
*
|
||||
* @param object|string $result MDB2_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 MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
|
||||
if (!is_resource($resource)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Could not generate result resource', __FUNCTION__);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @OCINumCols($resource);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
$db->loadModule('Datatype', null, true);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$column = array(
|
||||
'table' => '',
|
||||
'name' => $case_func(@OCIColumnName($resource, $i+1)),
|
||||
'type' => @OCIColumnType($resource, $i+1),
|
||||
'length' => @OCIColumnSize($resource, $i+1),
|
||||
'flags' => '',
|
||||
);
|
||||
$res[$i] = $column;
|
||||
$res[$i]['mdb2type'] = $db->datatype->mapNativeDatatype($res[$i]);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -80,7 +80,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
|
|||
|
||||
protected $start_transaction = false;
|
||||
|
||||
protected $varchar_max_length = 255;
|
||||
public $varchar_max_length = 255;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -304,28 +304,29 @@ class Sabre_CalDAV_CalendarQueryValidator {
|
|||
// one is the first to trigger. Based on this, we can
|
||||
// determine if we can 'give up' expanding events.
|
||||
$firstAlarm = null;
|
||||
foreach($expandedEvent->VALARM as $expandedAlarm) {
|
||||
if ($expandedEvent->VALARM !== null) {
|
||||
foreach($expandedEvent->VALARM as $expandedAlarm) {
|
||||
|
||||
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
|
||||
if ($expandedAlarm->isInTimeRange($start, $end)) {
|
||||
return true;
|
||||
}
|
||||
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
|
||||
if ($expandedAlarm->isInTimeRange($start, $end)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
|
||||
// This is an alarm with a non-relative trigger
|
||||
// time, likely created by a buggy client. The
|
||||
// implication is that every alarm in this
|
||||
// recurring event trigger at the exact same
|
||||
// time. It doesn't make sense to traverse
|
||||
// further.
|
||||
} else {
|
||||
// We store the first alarm as a means to
|
||||
// figure out when we can stop traversing.
|
||||
if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
|
||||
$firstAlarm = $effectiveTrigger;
|
||||
if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
|
||||
// This is an alarm with a non-relative trigger
|
||||
// time, likely created by a buggy client. The
|
||||
// implication is that every alarm in this
|
||||
// recurring event trigger at the exact same
|
||||
// time. It doesn't make sense to traverse
|
||||
// further.
|
||||
} else {
|
||||
// We store the first alarm as a means to
|
||||
// figure out when we can stop traversing.
|
||||
if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
|
||||
$firstAlarm = $effectiveTrigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (is_null($firstAlarm)) {
|
||||
// No alarm was found.
|
||||
|
|
|
@ -49,23 +49,23 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
/**
|
||||
* The email handler for invites and other scheduling messages.
|
||||
*
|
||||
* @var Sabre_CalDAV_Schedule_IMip
|
||||
*
|
||||
* @var Sabre_CalDAV_Schedule_IMip
|
||||
*/
|
||||
protected $imipHandler;
|
||||
|
||||
/**
|
||||
* Sets the iMIP handler.
|
||||
*
|
||||
* iMIP = The email transport of iCalendar scheduling messages. Setting
|
||||
* this is optional, but if you want the server to allow invites to be sent
|
||||
* iMIP = The email transport of iCalendar scheduling messages. Setting
|
||||
* this is optional, but if you want the server to allow invites to be sent
|
||||
* out, you must set a handler.
|
||||
*
|
||||
* Specifically iCal will plain assume that the server supports this. If
|
||||
* the server doesn't, iCal will display errors when inviting people to
|
||||
* Specifically iCal will plain assume that the server supports this. If
|
||||
* the server doesn't, iCal will display errors when inviting people to
|
||||
* events.
|
||||
*
|
||||
* @param Sabre_CalDAV_Schedule_IMip $imipHandler
|
||||
* @param Sabre_CalDAV_Schedule_IMip $imipHandler
|
||||
* @return void
|
||||
*/
|
||||
public function setIMipHandler(Sabre_CalDAV_Schedule_IMip $imipHandler) {
|
||||
|
@ -723,12 +723,12 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
if (!$originator) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests');
|
||||
}
|
||||
}
|
||||
if (!$recipients) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests');
|
||||
}
|
||||
}
|
||||
|
||||
if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) {
|
||||
if (!preg_match('/^mailto:(.*)@(.*)$/i', $originator)) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address');
|
||||
}
|
||||
$originator = substr($originator,7);
|
||||
|
@ -737,14 +737,14 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
foreach($recipients as $k=>$recipient) {
|
||||
|
||||
$recipient = trim($recipient);
|
||||
if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) {
|
||||
if (!preg_match('/^mailto:(.*)@(.*)$/i', $recipient)) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address');
|
||||
}
|
||||
$recipient = substr($recipient, 7);
|
||||
$recipients[$k] = $recipient;
|
||||
}
|
||||
|
||||
// We need to make sure that 'originator' matches one of the email
|
||||
// We need to make sure that 'originator' matches one of the email
|
||||
// addresses of the selected principal.
|
||||
$principal = $outboxNode->getOwner();
|
||||
$props = $this->server->getProperties($principal,array(
|
||||
|
@ -760,7 +760,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header');
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
$vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
|
||||
} catch (Sabre_VObject_ParseException $e) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
|
||||
|
@ -785,9 +785,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
}
|
||||
|
||||
if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') {
|
||||
$this->iMIPMessage($originator, $recipients, $vObject);
|
||||
$result = $this->iMIPMessage($originator, $recipients, $vObject);
|
||||
$this->server->httpResponse->sendStatus(200);
|
||||
$this->server->httpResponse->sendBody('Messages sent');
|
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml');
|
||||
$this->server->httpResponse->sendBody($this->generateScheduleResponse($result));
|
||||
} else {
|
||||
throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
|
||||
}
|
||||
|
@ -796,18 +797,83 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
/**
|
||||
* Sends an iMIP message by email.
|
||||
*
|
||||
* @param string $originator
|
||||
* @param array $recipients
|
||||
* @param Sabre_VObject_Component $vObject
|
||||
* @return void
|
||||
*
|
||||
* This method must return an array with status codes per recipient.
|
||||
* This should look something like:
|
||||
*
|
||||
* array(
|
||||
* 'user1@example.org' => '2.0;Success'
|
||||
* )
|
||||
*
|
||||
* Formatting for this status code can be found at:
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.8.3
|
||||
*
|
||||
* A list of valid status codes can be found at:
|
||||
* https://tools.ietf.org/html/rfc5546#section-3.6
|
||||
*
|
||||
* @param string $originator
|
||||
* @param array $recipients
|
||||
* @param Sabre_VObject_Component $vObject
|
||||
* @return array
|
||||
*/
|
||||
protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
|
||||
|
||||
if (!$this->imipHandler) {
|
||||
throw new Sabre_DAV_Exception_NotImplemented('No iMIP handler is setup on this server.');
|
||||
$resultStatus = '5.2;This server does not support this operation';
|
||||
} else {
|
||||
$this->imipHandler->sendMessage($originator, $recipients, $vObject);
|
||||
$resultStatus = '2.0;Success';
|
||||
}
|
||||
$this->imipHandler->sendMessage($originator, $recipients, $vObject);
|
||||
|
||||
$result = array();
|
||||
foreach($recipients as $recipient) {
|
||||
$result[$recipient] = $resultStatus;
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a schedule-response XML body
|
||||
*
|
||||
* The recipients array is a key->value list, containing email addresses
|
||||
* and iTip status codes. See the iMIPMessage method for a description of
|
||||
* the value.
|
||||
*
|
||||
* @param array $recipients
|
||||
* @return string
|
||||
*/
|
||||
public function generateScheduleResponse(array $recipients) {
|
||||
|
||||
$dom = new DOMDocument('1.0','utf-8');
|
||||
$dom->formatOutput = true;
|
||||
$xscheduleResponse = $dom->createElement('cal:schedule-response');
|
||||
$dom->appendChild($xscheduleResponse);
|
||||
|
||||
foreach($this->server->xmlNamespaces as $namespace=>$prefix) {
|
||||
|
||||
$xscheduleResponse->setAttribute('xmlns:' . $prefix, $namespace);
|
||||
|
||||
}
|
||||
|
||||
foreach($recipients as $recipient=>$status) {
|
||||
$xresponse = $dom->createElement('cal:response');
|
||||
|
||||
$xrecipient = $dom->createElement('cal:recipient');
|
||||
$xrecipient->appendChild($dom->createTextNode($recipient));
|
||||
$xresponse->appendChild($xrecipient);
|
||||
|
||||
$xrequestStatus = $dom->createElement('cal:request-status');
|
||||
$xrequestStatus->appendChild($dom->createTextNode($status));
|
||||
$xresponse->appendChild($xrequestStatus);
|
||||
|
||||
$xscheduleResponse->appendChild($xresponse);
|
||||
|
||||
}
|
||||
|
||||
return $dom->saveXML();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.3';
|
||||
const VERSION = '1.6.4';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
|
@ -154,7 +154,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
$val = stream_get_contents($val);
|
||||
|
||||
// Taking out \r to not screw up the xml output
|
||||
$returnedProperties[200][$addressDataProp] = str_replace("\r","", $val);
|
||||
//$returnedProperties[200][$addressDataProp] = str_replace("\r","", $val);
|
||||
// The stripping of \r breaks the Mail App in OSX Mountain Lion
|
||||
// this is fixed in master, but not backported. /Tanghus
|
||||
$returnedProperties[200][$addressDataProp] = $val;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
$this->server->tree->getNodeForPath($uri);
|
||||
|
||||
// We need to call the beforeWriteContent event for RFC3744
|
||||
$this->server->broadcastEvent('beforeWriteContent',array($uri));
|
||||
// Edit: looks like this is not used, and causing problems now.
|
||||
//
|
||||
// See Issue 222
|
||||
// $this->server->broadcastEvent('beforeWriteContent',array($uri));
|
||||
|
||||
} catch (Sabre_DAV_Exception_NotFound $e) {
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class Sabre_DAV_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.3';
|
||||
const VERSION = '1.6.4';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
|
@ -46,7 +46,7 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
|
|||
|
||||
if (strpos(strtolower($auth),'basic')!==0) return false;
|
||||
|
||||
return explode(':', base64_decode(substr($auth, 6)));
|
||||
return explode(':', base64_decode(substr($auth, 6)),2);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class Sabre_HTTP_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.2';
|
||||
const VERSION = '1.6.4';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
|
@ -42,14 +42,15 @@ class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
|
|||
|
||||
$effectiveStart = $this->DTSTART->getDateTime();
|
||||
if (isset($this->DTEND)) {
|
||||
|
||||
// The DTEND property is considered non inclusive. So for a 3 day
|
||||
// event in july, dtstart and dtend would have to be July 1st and
|
||||
// July 4th respectively.
|
||||
//
|
||||
// See:
|
||||
// http://tools.ietf.org/html/rfc5545#page-54
|
||||
$effectiveEnd = $this->DTEND->getDateTime();
|
||||
// If this was an all-day event, we should just increase the
|
||||
// end-date by 1. Otherwise the event will last until the second
|
||||
// the date changed, by increasing this by 1 day the event lasts
|
||||
// all of the last day as well.
|
||||
if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
|
||||
$effectiveEnd->modify('+1 day');
|
||||
}
|
||||
|
||||
} elseif (isset($this->DURATION)) {
|
||||
$effectiveEnd = clone $effectiveStart;
|
||||
$effectiveEnd->add( Sabre_VObject_DateTimeParser::parseDuration($this->DURATION) );
|
||||
|
|
|
@ -337,6 +337,8 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
|
|||
$this->endDate = clone $this->startDate;
|
||||
if (isset($this->baseEvent->DURATION)) {
|
||||
$this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value));
|
||||
} elseif ($this->baseEvent->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) {
|
||||
$this->endDate->modify('+1 day');
|
||||
}
|
||||
}
|
||||
$this->currentDate = clone $this->startDate;
|
||||
|
@ -561,7 +563,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
|
|||
*/
|
||||
public function fastForward(DateTime $dt) {
|
||||
|
||||
while($this->valid() && $this->getDTEnd() < $dt) {
|
||||
while($this->valid() && $this->getDTEnd() <= $dt) {
|
||||
$this->next();
|
||||
}
|
||||
|
||||
|
@ -823,9 +825,40 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
|
|||
*/
|
||||
protected function nextYearly() {
|
||||
|
||||
$currentMonth = $this->currentDate->format('n');
|
||||
$currentYear = $this->currentDate->format('Y');
|
||||
$currentDayOfMonth = $this->currentDate->format('j');
|
||||
|
||||
// No sub-rules, so we just advance by year
|
||||
if (!$this->byMonth) {
|
||||
|
||||
// Unless it was a leap day!
|
||||
if ($currentMonth==2 && $currentDayOfMonth==29) {
|
||||
|
||||
$counter = 0;
|
||||
do {
|
||||
$counter++;
|
||||
// Here we increase the year count by the interval, until
|
||||
// we hit a date that's also in a leap year.
|
||||
//
|
||||
// We could just find the next interval that's dividable by
|
||||
// 4, but that would ignore the rule that there's no leap
|
||||
// year every year that's dividable by a 100, but not by
|
||||
// 400. (1800, 1900, 2100). So we just rely on the datetime
|
||||
// functions instead.
|
||||
$nextDate = clone $this->currentDate;
|
||||
$nextDate->modify('+ ' . ($this->interval*$counter) . ' years');
|
||||
} while ($nextDate->format('n')!=2);
|
||||
$this->currentDate = $nextDate;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// The easiest form
|
||||
$this->currentDate->modify('+' . $this->interval . ' years');
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
$currentMonth = $this->currentDate->format('n');
|
||||
|
@ -877,8 +910,8 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
|
|||
|
||||
} else {
|
||||
|
||||
// no byDay or byMonthDay, so we can just loop through the
|
||||
// months.
|
||||
// These are the 'byMonth' rules, if there are no byDay or
|
||||
// byMonthDay sub-rules.
|
||||
do {
|
||||
|
||||
$currentMonth++;
|
||||
|
@ -888,6 +921,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator {
|
|||
}
|
||||
} while (!in_array($currentMonth, $this->byMonth));
|
||||
$this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class Sabre_VObject_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.3.3';
|
||||
const VERSION = '1.3.4';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* Include this in any file to start coverage, coverage will automatically end
|
||||
* when process dies.
|
||||
*/
|
||||
require_once(dirname(__FILE__) .'/coverage.php');
|
||||
|
||||
if (CodeCoverage::isCoverageOn()) {
|
||||
$coverage = CodeCoverage::getInstance();
|
||||
$coverage->startCoverage();
|
||||
register_shutdown_function("stop_coverage");
|
||||
}
|
||||
|
||||
function stop_coverage() {
|
||||
# hack until i can think of a way to run tests first and w/o exiting
|
||||
$autorun = function_exists("run_local_tests");
|
||||
if ($autorun) {
|
||||
$result = run_local_tests();
|
||||
}
|
||||
CodeCoverage::getInstance()->stopCoverage();
|
||||
if ($autorun) {
|
||||
exit($result ? 0 : 1);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Close code coverage data collection, next step is to generate report
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* include coverage files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../coverage.php');
|
||||
$cc = CodeCoverage::getInstance();
|
||||
$cc->readSettings();
|
||||
$cc->writeUntouched();
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* Initialize code coverage data collection, next step is to run your tests
|
||||
* with ini setting auto_prepend_file=autocoverage.php ...
|
||||
*
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
# optional arguments:
|
||||
# --include=<some filepath regexp> these files should be included coverage report
|
||||
# --exclude=<come filepath regexp> these files should not be included in coverage report
|
||||
# --maxdepth=2 when considering which file were not touched, scan directories
|
||||
#
|
||||
# Example:
|
||||
# php-coverage-open.php --include='.*\.php$' --include='.*\.inc$' --exclude='.*/tests/.*'
|
||||
/**#@+
|
||||
* include coverage files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../coverage_utils.php');
|
||||
CoverageUtils::requireSqlite();
|
||||
require_once(dirname(__FILE__) . '/../coverage.php');
|
||||
/**#@-*/
|
||||
$cc = new CodeCoverage();
|
||||
$cc->log = 'coverage.sqlite';
|
||||
$args = CoverageUtils::parseArguments($_SERVER['argv'], TRUE);
|
||||
$cc->includes = CoverageUtils::issetOr($args['include[]'], array('.*\.php$'));
|
||||
$cc->excludes = CoverageUtils::issetOr($args['exclude[]']);
|
||||
$cc->maxDirectoryDepth = (int)CoverageUtils::issetOr($args['maxdepth'], '1');
|
||||
$cc->resetLog();
|
||||
$cc->writeSettings();
|
||||
?>
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* Generate a code coverage report
|
||||
*
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
# optional arguments:
|
||||
# --reportDir=some/directory the default is ./coverage-report
|
||||
# --title='My Coverage Report' title the main page of your report
|
||||
|
||||
/**#@+
|
||||
* include coverage files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../coverage_utils.php');
|
||||
require_once(dirname(__FILE__) . '/../coverage.php');
|
||||
require_once(dirname(__FILE__) . '/../coverage_reporter.php');
|
||||
/**#@-*/
|
||||
$cc = CodeCoverage::getInstance();
|
||||
$cc->readSettings();
|
||||
$handler = new CoverageDataHandler($cc->log);
|
||||
$report = new CoverageReporter();
|
||||
$args = CoverageUtils::parseArguments($_SERVER['argv']);
|
||||
$report->reportDir = CoverageUtils::issetOr($args['reportDir'], 'coverage-report');
|
||||
$report->title = CoverageUtils::issetOr($args['title'], "Simpletest Coverage");
|
||||
$report->coverage = $handler->read();
|
||||
$report->untouched = $handler->readUntouchedFiles();
|
||||
$report->generate();
|
||||
?>
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* load coverage data handle
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/coverage_data_handler.php';
|
||||
|
||||
/**
|
||||
* Orchestrates code coverage both in this thread and in subthread under apache
|
||||
* Assumes this is running on same machine as apache.
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class CodeCoverage {
|
||||
var $log;
|
||||
var $root;
|
||||
var $includes;
|
||||
var $excludes;
|
||||
var $directoryDepth;
|
||||
var $maxDirectoryDepth = 20; // reasonable, otherwise arbitrary
|
||||
var $title = "Code Coverage";
|
||||
|
||||
# NOTE: This assumes all code shares the same current working directory.
|
||||
var $settingsFile = './code-coverage-settings.dat';
|
||||
|
||||
static $instance;
|
||||
|
||||
function writeUntouched() {
|
||||
$touched = array_flip($this->getTouchedFiles());
|
||||
$untouched = array();
|
||||
$this->getUntouchedFiles($untouched, $touched, '.', '.');
|
||||
$this->includeUntouchedFiles($untouched);
|
||||
}
|
||||
|
||||
function &getTouchedFiles() {
|
||||
$handler = new CoverageDataHandler($this->log);
|
||||
$touched = $handler->getFilenames();
|
||||
return $touched;
|
||||
}
|
||||
|
||||
function includeUntouchedFiles($untouched) {
|
||||
$handler = new CoverageDataHandler($this->log);
|
||||
foreach ($untouched as $file) {
|
||||
$handler->writeUntouchedFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
function getUntouchedFiles(&$untouched, $touched, $parentPath, $rootPath, $directoryDepth = 1) {
|
||||
$parent = opendir($parentPath);
|
||||
while ($file = readdir($parent)) {
|
||||
$path = "$parentPath/$file";
|
||||
if (is_dir($path)) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
if ($this->isDirectoryIncluded($path, $directoryDepth)) {
|
||||
$this->getUntouchedFiles($untouched, $touched, $path, $rootPath, $directoryDepth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($this->isFileIncluded($path)) {
|
||||
$relativePath = CoverageDataHandler::ltrim($rootPath .'/', $path);
|
||||
if (!array_key_exists($relativePath, $touched)) {
|
||||
$untouched[] = $relativePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($parent);
|
||||
}
|
||||
|
||||
function resetLog() {
|
||||
error_log('reseting log');
|
||||
$new_file = fopen($this->log, "w");
|
||||
if (!$new_file) {
|
||||
throw new Exception("Could not create ". $this->log);
|
||||
}
|
||||
fclose($new_file);
|
||||
if (!chmod($this->log, 0666)) {
|
||||
throw new Exception("Could not change ownership on file ". $this->log);
|
||||
}
|
||||
$handler = new CoverageDataHandler($this->log);
|
||||
$handler->createSchema();
|
||||
}
|
||||
|
||||
function startCoverage() {
|
||||
$this->root = getcwd();
|
||||
if(!extension_loaded("xdebug")) {
|
||||
throw new Exception("Could not load xdebug extension");
|
||||
};
|
||||
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
||||
}
|
||||
|
||||
function stopCoverage() {
|
||||
$cov = xdebug_get_code_coverage();
|
||||
$this->filter($cov);
|
||||
$data = new CoverageDataHandler($this->log);
|
||||
chdir($this->root);
|
||||
$data->write($cov);
|
||||
unset($data); // release sqlite connection
|
||||
xdebug_stop_code_coverage();
|
||||
// make sure we wind up on same current working directory, otherwise
|
||||
// coverage handler writer doesn't know what directory to chop off
|
||||
chdir($this->root);
|
||||
}
|
||||
|
||||
function readSettings() {
|
||||
if (file_exists($this->settingsFile)) {
|
||||
$this->setSettings(file_get_contents($this->settingsFile));
|
||||
} else {
|
||||
error_log("could not find file ". $this->settingsFile);
|
||||
}
|
||||
}
|
||||
|
||||
function writeSettings() {
|
||||
file_put_contents($this->settingsFile, $this->getSettings());
|
||||
}
|
||||
|
||||
function getSettings() {
|
||||
$data = array(
|
||||
'log' => realpath($this->log),
|
||||
'includes' => $this->includes,
|
||||
'excludes' => $this->excludes);
|
||||
return serialize($data);
|
||||
}
|
||||
|
||||
function setSettings($settings) {
|
||||
$data = unserialize($settings);
|
||||
$this->log = $data['log'];
|
||||
$this->includes = $data['includes'];
|
||||
$this->excludes = $data['excludes'];
|
||||
}
|
||||
|
||||
function filter(&$coverage) {
|
||||
foreach ($coverage as $file => $line) {
|
||||
if (!$this->isFileIncluded($file)) {
|
||||
unset($coverage[$file]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isFileIncluded($file) {
|
||||
if (!empty($this->excludes)) {
|
||||
foreach ($this->excludes as $path) {
|
||||
if (preg_match('|' . $path . '|', $file)) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->includes)) {
|
||||
foreach ($this->includes as $path) {
|
||||
if (preg_match('|' . $path . '|', $file)) {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
function isDirectoryIncluded($dir, $directoryDepth) {
|
||||
if ($directoryDepth >= $this->maxDirectoryDepth) {
|
||||
return false;
|
||||
}
|
||||
if (isset($this->excludes)) {
|
||||
foreach ($this->excludes as $path) {
|
||||
if (preg_match('|' . $path . '|', $dir)) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static function isCoverageOn() {
|
||||
$coverage = self::getInstance();
|
||||
$coverage->readSettings();
|
||||
if (empty($coverage->log) || !file_exists($coverage->log)) {
|
||||
trigger_error('No coverage log');
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static function getInstance() {
|
||||
if (self::$instance == NULL) {
|
||||
self::$instance = new CodeCoverage();
|
||||
self::$instance->readSettings();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class CoverageCalculator {
|
||||
|
||||
function coverageByFileVariables($file, $coverage) {
|
||||
$hnd = fopen($file, 'r');
|
||||
if ($hnd == null) {
|
||||
throw new Exception("File $file is missing");
|
||||
}
|
||||
$lines = array();
|
||||
for ($i = 1; !feof($hnd); $i++) {
|
||||
$line = fgets($hnd);
|
||||
$lineCoverage = $this->lineCoverageCodeToStyleClass($coverage, $i);
|
||||
$lines[$i] = array('lineCoverage' => $lineCoverage, 'code' => $line);
|
||||
}
|
||||
|
||||
fclose($hnd);
|
||||
|
||||
$var = compact('file', 'lines', 'coverage');
|
||||
return $var;
|
||||
}
|
||||
|
||||
function lineCoverageCodeToStyleClass($coverage, $line) {
|
||||
if (!array_key_exists($line, $coverage)) {
|
||||
return "comment";
|
||||
}
|
||||
$code = $coverage[$line];
|
||||
if (empty($code)) {
|
||||
return "comment";
|
||||
}
|
||||
switch ($code) {
|
||||
case -1:
|
||||
return "missed";
|
||||
case -2:
|
||||
return "dead";
|
||||
}
|
||||
|
||||
return "covered";
|
||||
}
|
||||
|
||||
function totalLoc($total, $coverage) {
|
||||
return $total + sizeof($coverage);
|
||||
}
|
||||
|
||||
function lineCoverage($total, $line) {
|
||||
# NOTE: counting dead code as covered, as it's almost always an executable line
|
||||
# strange artifact of xdebug or underlying system
|
||||
return $total + ($line > 0 || $line == -2 ? 1 : 0);
|
||||
}
|
||||
|
||||
function totalCoverage($total, $coverage) {
|
||||
return $total + array_reduce($coverage, array(&$this, "lineCoverage"));
|
||||
}
|
||||
|
||||
static function reportFilename($filename) {
|
||||
return preg_replace('|[/\\\\]|', '_', $filename) . '.html';
|
||||
}
|
||||
|
||||
function percentCoverageByFile($coverage, $file, &$results) {
|
||||
$byFileReport = self::reportFilename($file);
|
||||
|
||||
$loc = sizeof($coverage);
|
||||
if ($loc == 0)
|
||||
return 0;
|
||||
$lineCoverage = array_reduce($coverage, array(&$this, "lineCoverage"));
|
||||
$percentage = 100 * ($lineCoverage / $loc);
|
||||
$results[0][$file] = array('byFileReport' => $byFileReport, 'percentage' => $percentage);
|
||||
}
|
||||
|
||||
function variables($coverage, $untouched) {
|
||||
$coverageByFile = array();
|
||||
array_walk($coverage, array(&$this, "percentCoverageByFile"), array(&$coverageByFile));
|
||||
|
||||
$totalLoc = array_reduce($coverage, array(&$this, "totalLoc"));
|
||||
|
||||
if ($totalLoc > 0) {
|
||||
$totalLinesOfCoverage = array_reduce($coverage, array(&$this, "totalCoverage"));
|
||||
$totalPercentCoverage = 100 * ($totalLinesOfCoverage / $totalLoc);
|
||||
}
|
||||
|
||||
$untouchedPercentageDenominator = sizeof($coverage) + sizeof($untouched);
|
||||
if ($untouchedPercentageDenominator > 0) {
|
||||
$filesTouchedPercentage = 100 * sizeof($coverage) / $untouchedPercentageDenominator;
|
||||
}
|
||||
|
||||
$var = compact('coverageByFile', 'totalPercentCoverage', 'totalLoc', 'totalLinesOfCoverage', 'filesTouchedPercentage');
|
||||
$var['untouched'] = $untouched;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* @todo which db abstraction layer is this?
|
||||
*/
|
||||
require_once 'DB/sqlite.php';
|
||||
|
||||
/**
|
||||
* Persists code coverage data into SQLite database and aggregate data for convienent
|
||||
* interpretation in report generator. Be sure to not to keep an instance longer
|
||||
* than you have, otherwise you risk overwriting database edits from another process
|
||||
* also trying to make updates.
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class CoverageDataHandler {
|
||||
|
||||
var $db;
|
||||
|
||||
function __construct($filename) {
|
||||
$this->filename = $filename;
|
||||
$this->db = new SQLiteDatabase($filename);
|
||||
if (empty($this->db)) {
|
||||
throw new Exception("Could not create sqlite db ". $filename);
|
||||
}
|
||||
}
|
||||
|
||||
function createSchema() {
|
||||
$this->db->queryExec("create table untouched (filename text)");
|
||||
$this->db->queryExec("create table coverage (name text, coverage text)");
|
||||
}
|
||||
|
||||
function &getFilenames() {
|
||||
$filenames = array();
|
||||
$cursor = $this->db->unbufferedQuery("select distinct name from coverage");
|
||||
while ($row = $cursor->fetch()) {
|
||||
$filenames[] = $row[0];
|
||||
}
|
||||
|
||||
return $filenames;
|
||||
}
|
||||
|
||||
function write($coverage) {
|
||||
foreach ($coverage as $file => $lines) {
|
||||
$coverageStr = serialize($lines);
|
||||
$relativeFilename = self::ltrim(getcwd() . '/', $file);
|
||||
$sql = "insert into coverage (name, coverage) values ('$relativeFilename', '$coverageStr')";
|
||||
# if this fails, check you have write permission
|
||||
$this->db->queryExec($sql);
|
||||
}
|
||||
}
|
||||
|
||||
function read() {
|
||||
$coverage = array_flip($this->getFilenames());
|
||||
foreach($coverage as $file => $garbage) {
|
||||
$coverage[$file] = $this->readFile($file);
|
||||
}
|
||||
return $coverage;
|
||||
}
|
||||
|
||||
function &readFile($file) {
|
||||
$sql = "select coverage from coverage where name = '$file'";
|
||||
$aggregate = array();
|
||||
$result = $this->db->query($sql);
|
||||
while ($result->valid()) {
|
||||
$row = $result->current();
|
||||
$this->aggregateCoverage($aggregate, unserialize($row[0]));
|
||||
$result->next();
|
||||
}
|
||||
|
||||
return $aggregate;
|
||||
}
|
||||
|
||||
function aggregateCoverage(&$total, $next) {
|
||||
foreach ($next as $lineno => $code) {
|
||||
if (!isset($total[$lineno])) {
|
||||
$total[$lineno] = $code;
|
||||
} else {
|
||||
$total[$lineno] = $this->aggregateCoverageCode($total[$lineno], $code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function aggregateCoverageCode($code1, $code2) {
|
||||
switch($code1) {
|
||||
case -2: return -2;
|
||||
case -1: return $code2;
|
||||
default:
|
||||
switch ($code2) {
|
||||
case -2: return -2;
|
||||
case -1: return $code1;
|
||||
}
|
||||
}
|
||||
return $code1 + $code2;
|
||||
}
|
||||
|
||||
static function ltrim($cruft, $pristine) {
|
||||
if(stripos($pristine, $cruft) === 0) {
|
||||
return substr($pristine, strlen($cruft));
|
||||
}
|
||||
return $pristine;
|
||||
}
|
||||
|
||||
function writeUntouchedFile($file) {
|
||||
$relativeFile = CoverageDataHandler::ltrim('./', $file);
|
||||
$sql = "insert into untouched values ('$relativeFile')";
|
||||
$this->db->queryExec($sql);
|
||||
}
|
||||
|
||||
function &readUntouchedFiles() {
|
||||
$untouched = array();
|
||||
$result = $this->db->query("select filename from untouched order by filename");
|
||||
while ($result->valid()) {
|
||||
$row = $result->current();
|
||||
$untouched[] = $row[0];
|
||||
$result->next();
|
||||
}
|
||||
|
||||
return $untouched;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**#@+
|
||||
* include additional coverage files
|
||||
*/
|
||||
require_once dirname(__FILE__) .'/coverage_calculator.php';
|
||||
require_once dirname(__FILE__) .'/coverage_utils.php';
|
||||
require_once dirname(__FILE__) .'/simple_coverage_writer.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Take aggregated coverage data and generate reports from it using smarty
|
||||
* templates
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class CoverageReporter {
|
||||
var $coverage;
|
||||
var $untouched;
|
||||
var $reportDir;
|
||||
var $title = 'Coverage';
|
||||
var $writer;
|
||||
var $calculator;
|
||||
|
||||
function __construct() {
|
||||
$this->writer = new SimpleCoverageWriter();
|
||||
$this->calculator = new CoverageCalculator();
|
||||
}
|
||||
|
||||
function generateSummaryReport($out) {
|
||||
$variables = $this->calculator->variables($this->coverage, $this->untouched);
|
||||
$variables['title'] = $this->title;
|
||||
$report = $this->writer->writeSummary($out, $variables);
|
||||
fwrite($out, $report);
|
||||
}
|
||||
|
||||
function generate() {
|
||||
CoverageUtils::mkdir($this->reportDir);
|
||||
|
||||
$index = $this->reportDir .'/index.html';
|
||||
$hnd = fopen($index, 'w');
|
||||
$this->generateSummaryReport($hnd);
|
||||
fclose($hnd);
|
||||
|
||||
foreach ($this->coverage as $file => $cov) {
|
||||
$byFile = $this->reportDir .'/'. self::reportFilename($file);
|
||||
$byFileHnd = fopen($byFile, 'w');
|
||||
$this->generateCoverageByFile($byFileHnd, $file, $cov);
|
||||
fclose($byFileHnd);
|
||||
}
|
||||
|
||||
echo "generated report $index\n";
|
||||
}
|
||||
|
||||
function generateCoverageByFile($out, $file, $cov) {
|
||||
$variables = $this->calculator->coverageByFileVariables($file, $cov);
|
||||
$variables['title'] = $this->title .' - '. $file;
|
||||
$this->writer->writeByFile($out, $variables);
|
||||
}
|
||||
|
||||
static function reportFilename($filename) {
|
||||
return preg_replace('|[/\\\\]|', '_', $filename) . '.html';
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class CoverageUtils {
|
||||
|
||||
static function mkdir($dir) {
|
||||
if (!file_exists($dir)) {
|
||||
mkdir($dir, 0777, True);
|
||||
} else {
|
||||
if (!is_dir($dir)) {
|
||||
throw new Exception($dir .' exists as a file, not a directory');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function requireSqlite() {
|
||||
if (!self::isPackageClassAvailable('DB/sqlite.php', 'SQLiteDatabase')) {
|
||||
echo "sqlite library is required to be installed and available in include_path";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static function isPackageClassAvailable($includeFile, $class) {
|
||||
@include_once($includeFile);
|
||||
return class_exists($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses simple parameters from CLI.
|
||||
*
|
||||
* Puts trailing parameters into string array in 'extraArguments'
|
||||
*
|
||||
* Example:
|
||||
* $args = CoverageUtil::parseArguments($_SERVER['argv']);
|
||||
* if ($args['verbose']) echo "Verbose Mode On\n";
|
||||
* $files = $args['extraArguments'];
|
||||
*
|
||||
* Example CLI:
|
||||
* --foo=blah -x -h some trailing arguments
|
||||
*
|
||||
* if multiValueMode is true
|
||||
* Example CLI:
|
||||
* --include=a --include=b --exclude=c
|
||||
* Then
|
||||
* $args = CoverageUtil::parseArguments($_SERVER['argv']);
|
||||
* $args['include[]'] will equal array('a', 'b')
|
||||
* $args['exclude[]'] will equal array('c')
|
||||
* $args['exclude'] will equal c
|
||||
* $args['include'] will equal b NOTE: only keeps last value
|
||||
*
|
||||
* @param unknown_type $argv
|
||||
* @param supportMutliValue - will store 2nd copy of value in an array with key "foo[]"
|
||||
* @return unknown
|
||||
*/
|
||||
static public function parseArguments($argv, $mutliValueMode = False) {
|
||||
$args = array();
|
||||
$args['extraArguments'] = array();
|
||||
array_shift($argv); // scriptname
|
||||
foreach ($argv as $arg) {
|
||||
if (ereg('^--([^=]+)=(.*)', $arg, $reg)) {
|
||||
$args[$reg[1]] = $reg[2];
|
||||
if ($mutliValueMode) {
|
||||
self::addItemAsArray($args, $reg[1], $reg[2]);
|
||||
}
|
||||
} elseif (ereg('^[-]{1,2}([^[:blank:]]+)', $arg, $reg)) {
|
||||
$nonnull = '';
|
||||
$args[$reg[1]] = $nonnull;
|
||||
if ($mutliValueMode) {
|
||||
self::addItemAsArray($args, $reg[1], $nonnull);
|
||||
}
|
||||
} else {
|
||||
$args['extraArguments'][] = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value as an array of one, or appends to an existing array elements
|
||||
*
|
||||
* @param unknown_type $array
|
||||
* @param unknown_type $item
|
||||
*/
|
||||
static function addItemAsArray(&$array, $key, $item) {
|
||||
$array_key = $key .'[]';
|
||||
if (array_key_exists($array_key, $array)) {
|
||||
$array[$array_key][] = $item;
|
||||
} else {
|
||||
$array[$array_key] = array($item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* isset function with default value
|
||||
*
|
||||
* Example: $z = CoverageUtils::issetOr($array[$key], 'no value given')
|
||||
*
|
||||
* @param unknown_type $val
|
||||
* @param unknown_type $default
|
||||
* @return first value unless value is not set then returns 2nd arg or null if no 2nd arg
|
||||
*/
|
||||
static public function issetOr(&$val, $default = null)
|
||||
{
|
||||
return isset($val) ? $val : $default;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
interface CoverageWriter {
|
||||
|
||||
function writeSummary($out, $variables);
|
||||
|
||||
function writeByFile($out, $variables);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* SimpleCoverageWriter class file
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: unit_tester.php 1882 2009-07-01 14:30:05Z lastcraft $
|
||||
*/
|
||||
/**
|
||||
* base coverage writer class
|
||||
*/
|
||||
require_once dirname(__FILE__) .'/coverage_writer.php';
|
||||
|
||||
/**
|
||||
* SimpleCoverageWriter class
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCoverageWriter implements CoverageWriter {
|
||||
|
||||
function writeSummary($out, $variables) {
|
||||
extract($variables);
|
||||
$now = date("F j, Y, g:i a");
|
||||
ob_start();
|
||||
include dirname(__FILE__) . '/templates/index.php';
|
||||
$contents = ob_get_contents();
|
||||
fwrite ($out, $contents);
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
function writeByFile($out, $variables) {
|
||||
extract($variables);
|
||||
ob_start();
|
||||
include dirname(__FILE__) . '/templates/file.php';
|
||||
$contents = ob_get_contents();
|
||||
fwrite ($out, $contents);
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,60 @@
|
|||
<html>
|
||||
<head>
|
||||
<title><?php echo $title ?></title>
|
||||
</head>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Gill Sans MT", "Gill Sans", GillSans, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
h1 {
|
||||
font-size: medium;
|
||||
}
|
||||
#code {
|
||||
border-spacing: 0;
|
||||
}
|
||||
.lineNo {
|
||||
color: #ccc;
|
||||
}
|
||||
.code, .lineNo {
|
||||
white-space: pre;
|
||||
font-family: monospace;
|
||||
}
|
||||
.covered {
|
||||
color: #090;
|
||||
}
|
||||
.missed {
|
||||
color: #f00;
|
||||
}
|
||||
.dead {
|
||||
color: #00f;
|
||||
}
|
||||
.comment {
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<h1 id="title"><?php echo $title ?></h1>
|
||||
<table id="code">
|
||||
<tbody>
|
||||
<?php foreach ($lines as $lineNo => $line) { ?>
|
||||
<tr>
|
||||
<td><span class="lineNo"><?php echo $lineNo ?></span></td>
|
||||
<td><span class="<?php echo $line['lineCoverage'] ?> code"><?php echo htmlentities($line['code']) ?></span></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Legend</h2>
|
||||
<dl>
|
||||
<dt><span class="missed">Missed</span></dt>
|
||||
<dd>lines code that <strong>were not</strong> excersized during program execution.</dd>
|
||||
<dt><span class="covered">Covered</span></dt>
|
||||
<dd>lines code <strong>were</strong> excersized during program execution.</dd>
|
||||
<dt><span class="comment">Comment/non executable</span></dt>
|
||||
<dd>Comment or non-executable line of code.</dd>
|
||||
<dt><span class="dead">Dead</span></dt>
|
||||
<dd>lines of code that according to xdebug could not be executed. This is counted as coverage code because
|
||||
in almost all cases it is code that runnable.</dd>
|
||||
</dl>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,106 @@
|
|||
<html>
|
||||
<head>
|
||||
<title><?php echo $title ?></title>
|
||||
</head>
|
||||
<style type="text/css">
|
||||
h1 {
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Gill Sans MT", "Gill Sans", GillSans, Arial, Helvetica,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
td.percentage {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
caption {
|
||||
border-bottom: thin solid;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<h1 id="title"><?php echo $title ?></h1>
|
||||
<table>
|
||||
<caption>Summary</caption>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Total Coverage (<a href="#total-coverage">?</a>) :</td>
|
||||
<td class="percentage"><span class="totalPercentCoverage"><?php echo number_format($totalPercentCoverage, 0) ?>%</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Files Covered (<a href="#total-files-covered">?</a>) :</td>
|
||||
<td class="percentage"><span class="filesTouchedPercentage"><?php echo number_format($filesTouchedPercentage, 0) ?>%</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Report Generation Date :</td>
|
||||
<td><?php echo $now ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table id="covered-files">
|
||||
<caption>Coverage (<a href="#coverage">?</a>)</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File</th>
|
||||
<th>Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($coverageByFile as $file => $coverage) { ?>
|
||||
<tr>
|
||||
<td><a class="byFileReportLink" href="<?php echo $coverage['byFileReport'] ?>"><?php echo $file ?></a></td>
|
||||
<td class="percentage"><span class="percentCoverage"><?php echo number_format($coverage['percentage'], 0) ?>%</span></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
<caption>Files Not Covered (<a href="#untouched">?</a>)</caption>
|
||||
<tbody>
|
||||
<?php foreach ($untouched as $key => $file) { ?>
|
||||
<tr>
|
||||
<td><span class="untouchedFile"><?php echo $file ?></span></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Glossary</h2>
|
||||
<dl>
|
||||
<dt><a name="total-coverage">Total Coverage</a></dt>
|
||||
<dd>Ratio of all the lines of executable code that were executed to the
|
||||
lines of code that were not executed. This does not include the files
|
||||
that were not covered at all.</dd>
|
||||
<dt><a name="total-files-covered">Total Files Covered</a></dt>
|
||||
<dd>This is the ratio of the number of files tested, to the number of
|
||||
files not tested at all.</dd>
|
||||
<dt><a name="coverage">Coverage</a></dt>
|
||||
<dd>These files were parsed and loaded by the php interpreter while
|
||||
running the tests. Percentage is determined by the ratio of number of
|
||||
lines of code executed to the number of possible executable lines of
|
||||
code. "dead" lines of code, or code that could not be executed
|
||||
according to xdebug, are counted as covered because in almost all cases
|
||||
it is the end of a logical loop.</dd>
|
||||
<dt><a name="untouched">Files Not Covered</a></dt>
|
||||
<dd>These files were not loaded by the php interpreter at anytime
|
||||
during a unit test. You could consider these files having 0% coverage,
|
||||
but because it is difficult to determine the total coverage unless you
|
||||
could count the lines for executable code, this is not reflected in the
|
||||
Total Coverage calculation.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Code coverage generated by <a href="http://www.simpletest.org">SimpleTest</a></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
|
||||
class CoverageCalculatorTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../coverage_calculator.php';
|
||||
$this->calc = new CoverageCalculator();
|
||||
}
|
||||
|
||||
function testVariables() {
|
||||
$coverage = array('file' => array(1,1,1,1));
|
||||
$untouched = array('missed-file');
|
||||
$variables = $this->calc->variables($coverage, $untouched);
|
||||
$this->assertEqual(4, $variables['totalLoc']);
|
||||
$this->assertEqual(100, $variables['totalPercentCoverage']);
|
||||
$this->assertEqual(4, $variables['totalLinesOfCoverage']);
|
||||
$expected = array('file' => array('byFileReport' => 'file.html', 'percentage' => 100));
|
||||
$this->assertEqual($expected, $variables['coverageByFile']);
|
||||
$this->assertEqual(50, $variables['filesTouchedPercentage']);
|
||||
$this->assertEqual($untouched, $variables['untouched']);
|
||||
}
|
||||
|
||||
function testPercentageCoverageByFile() {
|
||||
$coverage = array(0,0,0,1,1,1);
|
||||
$results = array();
|
||||
$this->calc->percentCoverageByFile($coverage, 'file', $results);
|
||||
$pct = $results[0];
|
||||
$this->assertEqual(50, $pct['file']['percentage']);
|
||||
$this->assertEqual('file.html', $pct['file']['byFileReport']);
|
||||
}
|
||||
|
||||
function testTotalLoc() {
|
||||
$this->assertEqual(13, $this->calc->totalLoc(10, array(1,2,3)));
|
||||
}
|
||||
|
||||
function testLineCoverage() {
|
||||
$this->assertEqual(10, $this->calc->lineCoverage(10, -1));
|
||||
$this->assertEqual(10, $this->calc->lineCoverage(10, 0));
|
||||
$this->assertEqual(11, $this->calc->lineCoverage(10, 1));
|
||||
}
|
||||
|
||||
function testTotalCoverage() {
|
||||
$this->assertEqual(11, $this->calc->totalCoverage(10, array(-1,1)));
|
||||
}
|
||||
|
||||
static function getAttribute($element, $attribute) {
|
||||
$a = $element->attributes();
|
||||
return $a[$attribute];
|
||||
}
|
||||
|
||||
static function dom($stream) {
|
||||
rewind($stream);
|
||||
$actual = stream_get_contents($stream);
|
||||
$html = DOMDocument::loadHTML($actual);
|
||||
return simplexml_import_dom($html);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
|
||||
class CoverageDataHandlerTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../coverage_data_handler.php';
|
||||
}
|
||||
|
||||
function testAggregateCoverageCode() {
|
||||
$handler = new CoverageDataHandler($this->tempdb());
|
||||
$this->assertEqual(-2, $handler->aggregateCoverageCode(-2, -2));
|
||||
$this->assertEqual(-2, $handler->aggregateCoverageCode(-2, 10));
|
||||
$this->assertEqual(-2, $handler->aggregateCoverageCode(10, -2));
|
||||
$this->assertEqual(-1, $handler->aggregateCoverageCode(-1, -1));
|
||||
$this->assertEqual(10, $handler->aggregateCoverageCode(-1, 10));
|
||||
$this->assertEqual(10, $handler->aggregateCoverageCode(10, -1));
|
||||
$this->assertEqual(20, $handler->aggregateCoverageCode(10, 10));
|
||||
}
|
||||
|
||||
function testSimpleWriteRead() {
|
||||
$handler = new CoverageDataHandler($this->tempdb());
|
||||
$handler->createSchema();
|
||||
$coverage = array(10 => -2, 20 => -1, 30 => 0, 40 => 1);
|
||||
$handler->write(array('file' => $coverage));
|
||||
|
||||
$actual = $handler->readFile('file');
|
||||
$expected = array(10 => -2, 20 => -1, 30 => 0, 40 => 1);
|
||||
$this->assertEqual($expected, $actual);
|
||||
}
|
||||
|
||||
function testMultiFileWriteRead() {
|
||||
$handler = new CoverageDataHandler($this->tempdb());
|
||||
$handler->createSchema();
|
||||
$handler->write(array(
|
||||
'file1' => array(-2, -1, 1),
|
||||
'file2' => array(-2, -1, 1)
|
||||
));
|
||||
$handler->write(array(
|
||||
'file1' => array(-2, -1, 1)
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
'file1' => array(-2, -1, 2),
|
||||
'file2' => array(-2, -1, 1)
|
||||
);
|
||||
$actual = $handler->read();
|
||||
$this->assertEqual($expected, $actual);
|
||||
}
|
||||
|
||||
function testGetfilenames() {
|
||||
$handler = new CoverageDataHandler($this->tempdb());
|
||||
$handler->createSchema();
|
||||
$rawCoverage = array('file0' => array(), 'file1' => array());
|
||||
$handler->write($rawCoverage);
|
||||
$actual = $handler->getFilenames();
|
||||
$this->assertEqual(array('file0', 'file1'), $actual);
|
||||
}
|
||||
|
||||
function testWriteUntouchedFiles() {
|
||||
$handler = new CoverageDataHandler($this->tempdb());
|
||||
$handler->createSchema();
|
||||
$handler->writeUntouchedFile('bluejay');
|
||||
$handler->writeUntouchedFile('robin');
|
||||
$this->assertEqual(array('bluejay', 'robin'), $handler->readUntouchedFiles());
|
||||
}
|
||||
|
||||
function testLtrim() {
|
||||
$this->assertEqual('ber', CoverageDataHandler::ltrim('goo', 'goober'));
|
||||
$this->assertEqual('some/file', CoverageDataHandler::ltrim('./', './some/file'));
|
||||
$this->assertEqual('/x/y/z/a/b/c', CoverageDataHandler::ltrim('/a/b/', '/x/y/z/a/b/c'));
|
||||
}
|
||||
|
||||
function tempdb() {
|
||||
return tempnam(NULL, 'coverage.test.db');
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
|
||||
class CoverageReporterTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../coverage_reporter.php';
|
||||
new CoverageReporter();
|
||||
}
|
||||
|
||||
function testreportFilename() {
|
||||
$this->assertEqual("parula.php.html", CoverageReporter::reportFilename("parula.php"));
|
||||
$this->assertEqual("warbler_parula.php.html", CoverageReporter::reportFilename("warbler/parula.php"));
|
||||
$this->assertEqual("warbler_parula.php.html", CoverageReporter::reportFilename("warbler\\parula.php"));
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../../../mock_objects.php');
|
||||
|
||||
class CodeCoverageTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../coverage.php';
|
||||
}
|
||||
|
||||
function testIsFileIncluded() {
|
||||
$coverage = new CodeCoverage();
|
||||
$this->assertTrue($coverage->isFileIncluded('aaa'));
|
||||
$coverage->includes = array('a');
|
||||
$this->assertTrue($coverage->isFileIncluded('aaa'));
|
||||
$coverage->includes = array('x');
|
||||
$this->assertFalse($coverage->isFileIncluded('aaa'));
|
||||
$coverage->excludes = array('aa');
|
||||
$this->assertFalse($coverage->isFileIncluded('aaa'));
|
||||
}
|
||||
|
||||
function testIsFileIncludedRegexp() {
|
||||
$coverage = new CodeCoverage();
|
||||
$coverage->includes = array('modules/.*\.php$');
|
||||
$coverage->excludes = array('bad-bunny.php');
|
||||
$this->assertFalse($coverage->isFileIncluded('modules/a.test'));
|
||||
$this->assertFalse($coverage->isFileIncluded('modules/bad-bunny.test'));
|
||||
$this->assertTrue($coverage->isFileIncluded('modules/test.php'));
|
||||
$this->assertFalse($coverage->isFileIncluded('module-bad/good-bunny.php'));
|
||||
$this->assertTrue($coverage->isFileIncluded('modules/good-bunny.php'));
|
||||
}
|
||||
|
||||
function testIsDirectoryIncludedPastMaxDepth() {
|
||||
$coverage = new CodeCoverage();
|
||||
$coverage->maxDirectoryDepth = 5;
|
||||
$this->assertTrue($coverage->isDirectoryIncluded('aaa', 1));
|
||||
$this->assertFalse($coverage->isDirectoryIncluded('aaa', 5));
|
||||
}
|
||||
|
||||
function testIsDirectoryIncluded() {
|
||||
$coverage = new CodeCoverage();
|
||||
$this->assertTrue($coverage->isDirectoryIncluded('aaa', 0));
|
||||
$coverage->excludes = array('b$');
|
||||
$this->assertTrue($coverage->isDirectoryIncluded('aaa', 0));
|
||||
$coverage->includes = array('a$'); // includes are ignore, all dirs are included unless excluded
|
||||
$this->assertTrue($coverage->isDirectoryIncluded('aaa', 0));
|
||||
$coverage->excludes = array('.*a$');
|
||||
$this->assertFalse($coverage->isDirectoryIncluded('aaa', 0));
|
||||
}
|
||||
|
||||
function testFilter() {
|
||||
$coverage = new CodeCoverage();
|
||||
$data = array('a' => 0, 'b' => 0, 'c' => 0);
|
||||
$coverage->includes = array('b');
|
||||
$coverage->filter($data);
|
||||
$this->assertEqual(array('b' => 0), $data);
|
||||
}
|
||||
|
||||
function testUntouchedFiles() {
|
||||
$coverage = new CodeCoverage();
|
||||
$touched = array_flip(array("test/coverage_test.php"));
|
||||
$actual = array();
|
||||
$coverage->includes = array('coverage_test\.php$');
|
||||
$parentDir = realpath(dirname(__FILE__));
|
||||
$coverage->getUntouchedFiles($actual, $touched, $parentDir, $parentDir);
|
||||
$this->assertEqual(array("coverage_test.php"), $actual);
|
||||
}
|
||||
|
||||
function testResetLog() {
|
||||
$coverage = new CodeCoverage();
|
||||
$coverage->log = tempnam(NULL, 'php.xdebug.coverage.test.');
|
||||
$coverage->resetLog();
|
||||
$this->assertTrue(file_exists($coverage->log));
|
||||
}
|
||||
|
||||
function testSettingsSerialization() {
|
||||
$coverage = new CodeCoverage();
|
||||
$coverage->log = '/banana/boat';
|
||||
$coverage->includes = array('apple', 'orange');
|
||||
$coverage->excludes = array('tomato', 'pea');
|
||||
$data = $coverage->getSettings();
|
||||
$this->assertNotNull($data);
|
||||
|
||||
$actual = new CodeCoverage();
|
||||
$actual->setSettings($data);
|
||||
$this->assertEqual('/banana/boat', $actual->log);
|
||||
$this->assertEqual(array('apple', 'orange'), $actual->includes);
|
||||
$this->assertEqual(array('tomato', 'pea'), $actual->excludes);
|
||||
}
|
||||
|
||||
function testSettingsCanBeReadWrittenToDisk() {
|
||||
$settings_file = 'banana-boat-coverage-settings-test.dat';
|
||||
$coverage = new CodeCoverage();
|
||||
$coverage->log = '/banana/boat';
|
||||
$coverage->settingsFile = $settings_file;
|
||||
$coverage->writeSettings();
|
||||
|
||||
$actual = new CodeCoverage();
|
||||
$actual->settingsFile = $settings_file;
|
||||
$actual->readSettings();
|
||||
$this->assertEqual('/banana/boat', $actual->log);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
require_once dirname(__FILE__) . '/../../../autorun.php';
|
||||
|
||||
class CoverageUtilsTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../coverage_utils.php';
|
||||
}
|
||||
|
||||
function testMkdir() {
|
||||
CoverageUtils::mkdir(dirname(__FILE__));
|
||||
try {
|
||||
CoverageUtils::mkdir(__FILE__);
|
||||
$this->fail("Should give error about cannot create dir of a file");
|
||||
} catch (Exception $expected) {
|
||||
}
|
||||
}
|
||||
|
||||
function testIsPackageClassAvailable() {
|
||||
$coverageSource = dirname(__FILE__) .'/../coverage_calculator.php';
|
||||
$this->assertTrue(CoverageUtils::isPackageClassAvailable($coverageSource, 'CoverageCalculator'));
|
||||
$this->assertFalse(CoverageUtils::isPackageClassAvailable($coverageSource, 'BogusCoverage'));
|
||||
$this->assertFalse(CoverageUtils::isPackageClassAvailable('bogus-file', 'BogusCoverage'));
|
||||
$this->assertTrue(CoverageUtils::isPackageClassAvailable('bogus-file', 'CoverageUtils'));
|
||||
}
|
||||
|
||||
function testParseArgumentsMultiValue() {
|
||||
$actual = CoverageUtils::parseArguments(array('scriptname', '--a=b', '--a=c'), True);
|
||||
$expected = array('extraArguments' => array(), 'a' => 'c', 'a[]' => array('b', 'c'));
|
||||
$this->assertEqual($expected, $actual);
|
||||
}
|
||||
|
||||
function testParseArguments() {
|
||||
$actual = CoverageUtils::parseArguments(array('scriptname', '--a=b', '-c', 'xxx'));
|
||||
$expected = array('a' => 'b', 'c' => '', 'extraArguments' => array('xxx'));
|
||||
$this->assertEqual($expected, $actual);
|
||||
}
|
||||
|
||||
function testParseDoubleDashNoArguments() {
|
||||
$actual = CoverageUtils::parseArguments(array('scriptname', '--aa'));
|
||||
$this->assertTrue(isset($actual['aa']));
|
||||
}
|
||||
|
||||
function testParseHyphenedExtraArguments() {
|
||||
$actual = CoverageUtils::parseArguments(array('scriptname', '--alpha-beta=b', 'gamma-lambda'));
|
||||
$expected = array('alpha-beta' => 'b', 'extraArguments' => array('gamma-lambda'));
|
||||
$this->assertEqual($expected, $actual);
|
||||
}
|
||||
|
||||
function testAddItemAsArray() {
|
||||
$actual = array();
|
||||
CoverageUtils::addItemAsArray($actual, 'bird', 'duck');
|
||||
$this->assertEqual(array('bird[]' => array('duck')), $actual);
|
||||
|
||||
CoverageUtils::addItemAsArray(&$actual, 'bird', 'pigeon');
|
||||
$this->assertEqual(array('bird[]' => array('duck', 'pigeon')), $actual);
|
||||
}
|
||||
|
||||
function testIssetOr() {
|
||||
$data = array('bird' => 'gull');
|
||||
$this->assertEqual('lab', CoverageUtils::issetOr($data['dog'], 'lab'));
|
||||
$this->assertEqual('gull', CoverageUtils::issetOr($data['bird'], 'sparrow'));
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
// sample code
|
||||
$x = 1 + 2;
|
||||
if (false) echo "dead";
|
69
3rdparty/simpletest/extensions/coverage/test/simple_coverage_writer_test.php
vendored
Normal file
69
3rdparty/simpletest/extensions/coverage/test/simple_coverage_writer_test.php
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
|
||||
class SimpleCoverageWriterTest extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
!file_exists('DB/sqlite.php'),
|
||||
'The Coverage extension needs to have PEAR installed');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
require_once dirname(__FILE__) .'/../simple_coverage_writer.php';
|
||||
require_once dirname(__FILE__) .'/../coverage_calculator.php';
|
||||
|
||||
}
|
||||
|
||||
function testGenerateSummaryReport() {
|
||||
$writer = new SimpleCoverageWriter();
|
||||
$coverage = array('file' => array(0, 1));
|
||||
$untouched = array('missed-file');
|
||||
$calc = new CoverageCalculator();
|
||||
$variables = $calc->variables($coverage, $untouched);
|
||||
$variables['title'] = 'coverage';
|
||||
$out = fopen("php://memory", 'w');
|
||||
$writer->writeSummary($out, $variables);
|
||||
$dom = self::dom($out);
|
||||
$totalPercentCoverage = $dom->elements->xpath("//span[@class='totalPercentCoverage']");
|
||||
$this->assertEqual('50%', (string)$totalPercentCoverage[0]);
|
||||
|
||||
$fileLinks = $dom->elements->xpath("//a[@class='byFileReportLink']");
|
||||
$fileLinkAttr = $fileLinks[0]->attributes();
|
||||
$this->assertEqual('file.html', $fileLinkAttr['href']);
|
||||
$this->assertEqual('file', (string)($fileLinks[0]));
|
||||
|
||||
$untouchedFile = $dom->elements->xpath("//span[@class='untouchedFile']");
|
||||
$this->assertEqual('missed-file', (string)$untouchedFile[0]);
|
||||
}
|
||||
|
||||
function testGenerateCoverageByFile() {
|
||||
$writer = new SimpleCoverageWriter();
|
||||
$cov = array(3 => 1, 4 => -2); // 2 comments, 1 code, 1 dead (1-based indexes)
|
||||
$out = fopen("php://memory", 'w');
|
||||
$file = dirname(__FILE__) .'/sample/code.php';
|
||||
$calc = new CoverageCalculator();
|
||||
$variables = $calc->coverageByFileVariables($file, $cov);
|
||||
$variables['title'] = 'coverage';
|
||||
$writer->writeByFile($out, $variables);
|
||||
$dom = self::dom($out);
|
||||
|
||||
$cells = $dom->elements->xpath("//table[@id='code']/tbody/tr/td/span");
|
||||
$this->assertEqual("comment code", self::getAttribute($cells[1], 'class'));
|
||||
$this->assertEqual("comment code", self::getAttribute($cells[3], 'class'));
|
||||
$this->assertEqual("covered code", self::getAttribute($cells[5], 'class'));
|
||||
$this->assertEqual("dead code", self::getAttribute($cells[7], 'class'));
|
||||
}
|
||||
|
||||
static function getAttribute($element, $attribute) {
|
||||
$a = $element->attributes();
|
||||
return $a[$attribute];
|
||||
}
|
||||
|
||||
static function dom($stream) {
|
||||
rewind($stream);
|
||||
$actual = stream_get_contents($stream);
|
||||
$html = DOMDocument::loadHTML($actual);
|
||||
return simplexml_import_dom($html);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
// $Id: $
|
||||
require_once(dirname(__FILE__) . '/../../../autorun.php');
|
||||
|
||||
class CoverageUnitTests extends TestSuite {
|
||||
function CoverageUnitTests() {
|
||||
$this->TestSuite('Coverage Unit tests');
|
||||
$path = dirname(__FILE__) . '/*_test.php';
|
||||
foreach(glob($path) as $test) {
|
||||
$this->addFile($test);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -166,6 +166,8 @@ class smb {
|
|||
return false;
|
||||
}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_PATH_NOT_FOUND'){
|
||||
return false;
|
||||
}elseif(substr($regs[0],0,29)=='NT_STATUS_FILE_IS_A_DIRECTORY'){
|
||||
return false;
|
||||
}
|
||||
trigger_error($regs[0].' params('.$params.')', E_USER_ERROR);
|
||||
}
|
||||
|
|
3
AUTHORS
3
AUTHORS
|
@ -19,3 +19,6 @@ With help from many libraries and frameworks including:
|
|||
SabreDAV
|
||||
jQuery
|
||||
…
|
||||
|
||||
"Lock” symbol from thenounproject.com collection
|
||||
"Clock” symbol by Brandon Hopkins, from thenounproject.com collection
|
8
README
8
README
|
@ -5,9 +5,9 @@ http://ownCloud.org
|
|||
|
||||
Installation instructions: http://owncloud.org/support
|
||||
|
||||
Source code: http://gitorious.org/owncloud
|
||||
Mailing list: http://mail.kde.org/mailman/listinfo/owncloud
|
||||
IRC channel: http://webchat.freenode.net/?channels=owncloud
|
||||
Source code: https://github.com/owncloud
|
||||
Mailing list: https://mail.kde.org/mailman/listinfo/owncloud
|
||||
IRC channel: https://webchat.freenode.net/?channels=owncloud
|
||||
Diaspora: https://joindiaspora.com/u/owncloud
|
||||
Identi.ca: http://identi.ca/owncloud
|
||||
Identi.ca: https://identi.ca/owncloud
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
OC::$CLASSPATH['OC_Admin_Audit_Hooks_Handlers'] = 'apps/admin_audit/lib/hooks_handlers.php';
|
||||
|
||||
OCP\Util::connectHook('OCP\User', 'pre_login', 'OC_Admin_Audit_Hooks_Handlers', 'pre_login');
|
||||
OCP\Util::connectHook('OCP\User', 'post_login', 'OC_Admin_Audit_Hooks_Handlers', 'post_login');
|
||||
OCP\Util::connectHook('OCP\User', 'logout', 'OC_Admin_Audit_Hooks_Handlers', 'logout');
|
||||
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, 'OC_Admin_Audit_Hooks_Handlers', 'rename');
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, 'OC_Admin_Audit_Hooks_Handlers', 'create');
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, 'OC_Admin_Audit_Hooks_Handlers', 'copy');
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, 'OC_Admin_Audit_Hooks_Handlers', 'write');
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_read, 'OC_Admin_Audit_Hooks_Handlers', 'read');
|
||||
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_delete, 'OC_Admin_Audit_Hooks_Handlers', 'delete');
|
||||
|
||||
OCP\Util::connectHook('OC_Share', 'public', 'OC_Admin_Audit_Hooks_Handlers', 'share_public');
|
||||
OCP\Util::connectHook('OC_Share', 'public-download', 'OC_Admin_Audit_Hooks_Handlers', 'share_public_download');
|
||||
OCP\Util::connectHook('OC_Share', 'user', 'OC_Admin_Audit_Hooks_Handlers', 'share_user');
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>admin_audit</id>
|
||||
<name>Log audit info</name>
|
||||
<version>0.1</version>
|
||||
<licence>AGPL</licence>
|
||||
<author>Bart Visscher</author>
|
||||
<require>2</require>
|
||||
<description>Audit user actions in Owncloud</description>
|
||||
</info>
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
class OC_Admin_Audit_Hooks_Handlers {
|
||||
static public function pre_login($params) {
|
||||
$path = $params['uid'];
|
||||
self::log('Trying login '.$user);
|
||||
}
|
||||
static public function post_login($params) {
|
||||
$path = $params['uid'];
|
||||
self::log('Login '.$user);
|
||||
}
|
||||
static public function logout($params) {
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Logout '.$user);
|
||||
}
|
||||
|
||||
static public function rename($params) {
|
||||
$oldpath = $params[OC_Filesystem::signal_param_oldpath];
|
||||
$newpath = $params[OC_Filesystem::signal_param_newpath];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Rename "'.$oldpath.'" to "'.$newpath.'" by '.$user);
|
||||
}
|
||||
static public function create($params) {
|
||||
$path = $params[OC_Filesystem::signal_param_path];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Create "'.$path.'" by '.$user);
|
||||
}
|
||||
static public function copy($params) {
|
||||
$oldpath = $params[OC_Filesystem::signal_param_oldpath];
|
||||
$newpath = $params[OC_Filesystem::signal_param_newpath];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Copy "'.$oldpath.'" to "'.$newpath.'" by '.$user);
|
||||
}
|
||||
static public function write($params) {
|
||||
$path = $params[OC_Filesystem::signal_param_path];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Write "'.$path.'" by '.$user);
|
||||
}
|
||||
static public function read($params) {
|
||||
$path = $params[OC_Filesystem::signal_param_path];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Read "'.$path.'" by '.$user);
|
||||
}
|
||||
static public function delete($params) {
|
||||
$path = $params[OC_Filesystem::signal_param_path];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Delete "'.$path.'" by '.$user);
|
||||
}
|
||||
static public function share_public($params) {
|
||||
$path = $params['source'];
|
||||
$token = $params['token'];
|
||||
$user = OCP\User::getUser();
|
||||
self::log('Shared "'.$path.'" with public, token="'.$token.'" by '.$user);
|
||||
}
|
||||
static public function share_public_download($params) {
|
||||
$path = $params['source'];
|
||||
$token = $params['token'];
|
||||
$user = $_SERVER['REMOTE_ADDR'];
|
||||
self::log('Download of shared "'.$path.'" token="'.$token.'" by '.$user);
|
||||
}
|
||||
static public function share_user($params) {
|
||||
$path = $params['source'];
|
||||
$permissions = $params['permissions'];
|
||||
$with = $params['with'];
|
||||
$user = OCP\User::getUser();
|
||||
$rw = $permissions & OC_Share::WRITE ? 'w' : 'o';
|
||||
self::log('Shared "'.$path.'" (r'.$rw.') with user "'.$with.'" by '.$user);
|
||||
}
|
||||
static protected function log($msg) {
|
||||
OCP\Util::writeLog('admin_audit', $msg, OCP\Util::INFO);
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?php
|
||||
$l=OC_L10N::get('admin_dependencies_chk');
|
||||
|
||||
OCP\App::registerAdmin('admin_dependencies_chk','settings');
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>admin_dependencies_chk</id>
|
||||
<name>ownCloud dependencies info</name>
|
||||
<licence>AGPL</licence>
|
||||
<author>Brice Maron (eMerzh)</author>
|
||||
<require>4</require>
|
||||
<shipped>true</shipped>
|
||||
<description>Display OwnCloud's dependencies informations (missings modules, ...)</description>
|
||||
</info>
|
|
@ -1 +0,0 @@
|
|||
0.01
|
|
@ -1,9 +0,0 @@
|
|||
#status_list legend { font-weight: bold; color: #888888; }
|
||||
.state > li { margin-bottom: 3px; padding-left: 0.5em; list-style-type: circle; }
|
||||
.state .state_module { font-weight:bold; text-shadow: 0 1px 0 #DDD; cursor:help;}
|
||||
|
||||
.state_used ul, .state_used li { display:inline; }
|
||||
|
||||
.state_ok .state_module { color: #009700; }
|
||||
.state_warning .state_module { color: #FF9B29; }
|
||||
.state_error .state_module { color: #FF3B3B; }
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - user_ldap
|
||||
*
|
||||
* @author Brice Maron
|
||||
* @copyright 2011 Brice Maron brice __from__ bmaron _DOT_ net
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
$l=OC_L10N::get('admin_dependencies_chk');
|
||||
$tmpl = new OCP\Template( 'admin_dependencies_chk', 'settings');
|
||||
|
||||
$modules = array();
|
||||
|
||||
//Possible status are : ok, error, warning
|
||||
$modules[] =array(
|
||||
'status' => function_exists('json_encode') ? 'ok' : 'error',
|
||||
'part'=> 'php-json',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The php-json module is needed by the many applications for inter communications'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => function_exists('curl_init') ? 'ok' : 'error',
|
||||
'part'=> 'php-curl',
|
||||
'modules'=> array('bookmarks'),
|
||||
'message'=> $l->t('The php-curl modude is needed to fetch the page title when adding a bookmarks'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => function_exists('imagepng') ? 'ok' : 'error',
|
||||
'part'=> 'php-gd',
|
||||
'modules'=> array('gallery'),
|
||||
'message'=> $l->t('The php-gd module is needed to create thumbnails of your images'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => function_exists("ldap_bind") ? 'ok' : 'error',
|
||||
'part'=> 'php-ldap',
|
||||
'modules'=> array('user_ldap'),
|
||||
'message'=> $l->t('The php-ldap module is needed connect to your ldap server'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => class_exists('ZipArchive') ? 'ok' : 'warning',
|
||||
'part'=> 'php-zip',
|
||||
'modules'=> array('admin_export','core'),
|
||||
'message'=> $l->t('The php-zip module is needed download multiple files at once'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => function_exists('mb_detect_encoding') ? 'ok' : 'error',
|
||||
'part'=> 'php-mb_multibyte ',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The php-mb_multibyte module is needed to manage correctly the encoding.'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => function_exists('ctype_digit') ? 'ok' : 'error',
|
||||
'part'=> 'php-ctype',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The php-ctype module is needed validate data.'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => class_exists('DOMDocument') ? 'ok' : 'error',
|
||||
'part'=> 'php-xml',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The php-xml module is needed to share files with webdav.'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => ini_get('allow_url_fopen') == '1' ? 'ok' : 'error',
|
||||
'part'=> 'allow_url_fopen',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The allow_url_fopen directive of your php.ini should be set to 1 to retrieve knowledge base from OCS servers'));
|
||||
|
||||
$modules[] =array(
|
||||
'status' => class_exists('PDO') ? 'ok' : 'warning',
|
||||
'part'=> 'php-pdo',
|
||||
'modules'=> array('core'),
|
||||
'message'=> $l->t('The php-pdo module is needed to store owncloud data into a database.'));
|
||||
|
||||
foreach($modules as $key => $module) {
|
||||
$enabled = false ;
|
||||
foreach($module['modules'] as $app) {
|
||||
if(OCP\App::isEnabled($app) || $app=='core'){
|
||||
$enabled = true;
|
||||
}
|
||||
}
|
||||
if($enabled == false) unset($modules[$key]);
|
||||
}
|
||||
|
||||
OCP\UTIL::addStyle('admin_dependencies_chk', 'style');
|
||||
$tmpl->assign( 'items', $modules );
|
||||
|
||||
return $tmpl->fetchPage();
|
|
@ -1,16 +0,0 @@
|
|||
<fieldset id="status_list" class="personalblock">
|
||||
<legend><?php echo $l->t('Dependencies status');?></legend>
|
||||
<ul class="state">
|
||||
<?php foreach($_['items'] as $item):?>
|
||||
<li class="state_<?php echo $item['status'];?>">
|
||||
<span class="state_module" title="<?php echo $item['message'];?>"><?php echo $item['part'];?></span>
|
||||
<div class="state_used"><?php echo $l->t('Used by :');?>
|
||||
<ul>
|
||||
<?php foreach($item['modules'] as $module):?>
|
||||
<li><?php echo $module;?></li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
</fieldset>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>admin_migrate</id>
|
||||
<name>ownCloud Instance Migration</name>
|
||||
<description>Import/Export your owncloud instance</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Thomas Schmidt and Tom Needham</author>
|
||||
<require>4</require>
|
||||
<shipped>true</shipped>
|
||||
<default_enable/>
|
||||
</info>
|
|
@ -1 +0,0 @@
|
|||
0.1
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - admin_migrate
|
||||
*
|
||||
* @author Thomas Schmidt
|
||||
* @copyright 2011 Thomas Schmidt tom@opensuse.org
|
||||
* @author Tom Needham
|
||||
* @copyright 2012 Tom Needham tom@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
OCP\User::checkAdminUser();
|
||||
OCP\App::checkAppEnabled('admin_migrate');
|
||||
|
||||
// Export?
|
||||
if (isset($_POST['admin_export'])) {
|
||||
// Create the export zip
|
||||
$response = json_decode( OC_Migrate::export( null, $_POST['export_type'] ) );
|
||||
if( !$response->success ){
|
||||
// Error
|
||||
die('error');
|
||||
} else {
|
||||
$path = $response->data;
|
||||
// Download it
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Disposition: attachment; filename=" . basename($path));
|
||||
header("Content-Length: " . filesize($path));
|
||||
@ob_end_clean();
|
||||
readfile( $path );
|
||||
unlink( $path );
|
||||
}
|
||||
// Import?
|
||||
} else if( isset($_POST['admin_import']) ){
|
||||
$from = $_FILES['owncloud_import']['tmp_name'];
|
||||
|
||||
if( !OC_Migrate::import( $from, 'instance' ) ){
|
||||
die('failed');
|
||||
}
|
||||
|
||||
} else {
|
||||
// fill template
|
||||
$tmpl = new OCP\Template('admin_migrate', 'settings');
|
||||
return $tmpl->fetchPage();
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<form id="export" action="#" method="post">
|
||||
<fieldset class="personalblock">
|
||||
<legend><strong><?php echo $l->t('Export this ownCloud instance');?></strong></legend>
|
||||
<p><?php echo $l->t('This will create a compressed file that contains the data of this owncloud instance.
|
||||
Please choose the export type:');?>
|
||||
</p>
|
||||
<h3>What would you like to export?</h3>
|
||||
<p>
|
||||
<input type="radio" name="export_type" value="instance" style="width:20px;" /> ownCloud instance (suitable for import )<br />
|
||||
<input type="radio" name="export_type" value="system" style="width:20px;" /> ownCloud system files<br />
|
||||
<input type="radio" name="export_type" value="userfiles" style="width:20px;" /> Just user files<br />
|
||||
<input type="submit" name="admin_export" value="<?php echo $l->t('Export'); ?>" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php
|
||||
/*
|
||||
* EXPERIMENTAL
|
||||
?>
|
||||
<form id="import" action="#" method="post" enctype="multipart/form-data">
|
||||
<fieldset class="personalblock">
|
||||
<legend><strong><?php echo $l->t('Import an ownCloud instance. THIS WILL DELETE ALL CURRENT OWNCLOUD DATA');?></strong></legend>
|
||||
<p><?php echo $l->t('All current ownCloud data will be replaced by the ownCloud instance that is uploaded.');?>
|
||||
</p>
|
||||
<p><input type="file" id="owncloud_import" name="owncloud_import"><label for="owncloud_import"><?php echo $l->t('ownCloud Export Zip File');?></label>
|
||||
</p>
|
||||
<input type="submit" name="admin_import" value="<?php echo $l->t('Import'); ?>" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php
|
||||
*/
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\User::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('bookmarks');
|
||||
|
||||
require_once('bookmarksHelper.php');
|
||||
addBookmark($_GET['url'], '', 'Read-Later');
|
||||
|
||||
include 'templates/addBm.php';
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//no apps or filesystem
|
||||
$RUNTIME_NOSETUPFS=true;
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
require_once(OC_App::getAppPath('bookmarks').'/bookmarksHelper.php');
|
||||
$id = addBookmark($_POST['url'], $_POST['title'], $_POST['tags']);
|
||||
OCP\JSON::success(array('data' => $id));
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//no apps or filesystem
|
||||
$RUNTIME_NOSETUPFS=true;
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
$id = $_POST['id'];
|
||||
if (!OC_Bookmarks_Bookmarks::deleteUrl($id)){
|
||||
OC_JSON::error();
|
||||
exit();
|
||||
}
|
||||
|
||||
OCP\JSON::success();
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin - edit bookmark script
|
||||
*
|
||||
* @author Golnaz Nilieh
|
||||
* @copyright 2011 Golnaz Nilieh <golnaz.nilieh@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//no apps or filesystem
|
||||
$RUNTIME_NOSETUPFS=true;
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
$CONFIG_DBTYPE = OCP\Config::getSystemValue( "dbtype", "sqlite" );
|
||||
if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
|
||||
$_ut = "strftime('%s','now')";
|
||||
} elseif($CONFIG_DBTYPE == 'pgsql') {
|
||||
$_ut = 'date_part(\'epoch\',now())::integer';
|
||||
} else {
|
||||
$_ut = "UNIX_TIMESTAMP()";
|
||||
}
|
||||
|
||||
$bookmark_id = (int)$_POST["id"];
|
||||
$user_id = OCP\USER::getUser();
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
UPDATE *PREFIX*bookmarks
|
||||
SET url = ?, title =?, lastmodified = $_ut
|
||||
WHERE id = ?
|
||||
AND user_id = ?
|
||||
");
|
||||
|
||||
$params=array(
|
||||
htmlspecialchars_decode($_POST["url"]),
|
||||
htmlspecialchars_decode($_POST["title"]),
|
||||
$bookmark_id,
|
||||
$user_id,
|
||||
);
|
||||
|
||||
$result = $query->execute($params);
|
||||
|
||||
# Abort the operation if bookmark couldn't be set (probably because the user is not allowed to edit this bookmark)
|
||||
if ($result->numRows() == 0) exit();
|
||||
|
||||
# Remove old tags and insert new ones.
|
||||
$query = OCP\DB::prepare("
|
||||
DELETE FROM *PREFIX*bookmarks_tags
|
||||
WHERE bookmark_id = $bookmark_id
|
||||
");
|
||||
|
||||
$query->execute();
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
INSERT INTO *PREFIX*bookmarks_tags
|
||||
(bookmark_id, tag)
|
||||
VALUES (?, ?)
|
||||
");
|
||||
|
||||
$tags = explode(' ', urldecode($_POST["tags"]));
|
||||
foreach ($tags as $tag) {
|
||||
if(empty($tag)) {
|
||||
//avoid saving blankspaces
|
||||
continue;
|
||||
}
|
||||
$params = array($bookmark_id, trim($tag));
|
||||
$query->execute($params);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//no apps or filesystem
|
||||
$RUNTIME_NOSETUPFS=true;
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
UPDATE *PREFIX*bookmarks
|
||||
SET clickcount = clickcount + 1
|
||||
WHERE user_id = ?
|
||||
AND url LIKE ?
|
||||
");
|
||||
|
||||
$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_POST["url"]));
|
||||
$bookmarks = $query->execute($params);
|
||||
|
||||
header( "HTTP/1.1 204 No Content" );
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
* @copyright 2012 David Iwanowitsch <david at unclouded dot de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//no apps or filesystem
|
||||
$RUNTIME_NOSETUPFS=true;
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
|
||||
//Filter for tag?
|
||||
$filterTag = isset($_POST['tag']) ? htmlspecialchars_decode($_POST['tag']) : false;
|
||||
|
||||
$offset = isset($_POST['page']) ? intval($_POST['page']) * 10 : 0;
|
||||
|
||||
$sort = isset($_POST['sort']) ? ($_POST['sort']) : 'bookmarks_sorting_recent';
|
||||
if($sort == 'bookmarks_sorting_clicks') {
|
||||
$sqlSortColumn = 'clickcount';
|
||||
} else {
|
||||
$sqlSortColumn = 'id';
|
||||
}
|
||||
|
||||
|
||||
$bookmarks = OC_Bookmarks_Bookmarks::findBookmarks($offset, $sqlSortColumn, $filterTag, true);
|
||||
|
||||
OCP\JSON::success(array('data' => $bookmarks));
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Marvin Thomas Rabe <mrabe@marvinrabe.de>
|
||||
* Copyright (c) 2011 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OC::$CLASSPATH['OC_Bookmarks_Bookmarks'] = 'apps/bookmarks/lib/bookmarks.php';
|
||||
OC::$CLASSPATH['OC_Search_Provider_Bookmarks'] = 'apps/bookmarks/lib/search.php';
|
||||
|
||||
$l = new OC_l10n('bookmarks');
|
||||
OCP\App::addNavigationEntry( array( 'id' => 'bookmarks_index', 'order' => 70, 'href' => OCP\Util::linkTo( 'bookmarks', 'index.php' ), 'icon' => OCP\Util::imagePath( 'bookmarks', 'bookmarks.png' ), 'name' => $l->t('Bookmarks')));
|
||||
|
||||
OCP\App::registerPersonal('bookmarks', 'settings');
|
||||
OCP\Util::addscript('bookmarks','bookmarksearch');
|
||||
|
||||
OC_Search::registerProvider('OC_Search_Provider_Bookmarks');
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<database>
|
||||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
<charset>utf8</charset>
|
||||
<table>
|
||||
<name>*dbprefix*bookmarks</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<autoincrement>1</autoincrement>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>url</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4096</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>title</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>140</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>public</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<length>1</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>added</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>lastmodified</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>clickcount</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>id</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<sorting>descending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<name>*dbprefix*bookmarks_tags</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>bookmark_id</name>
|
||||
<type>integer</type>
|
||||
<length>64</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>tag</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
<index>
|
||||
<name>bookmark_tag</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>bookmark_id</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>tag</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
</database>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>bookmarks</id>
|
||||
<name>Bookmarks</name>
|
||||
<description>Bookmark manager for ownCloud</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Arthur Schiwon, Marvin Thomas Rabe</author>
|
||||
<standalone/>
|
||||
<require>4</require>
|
||||
<shipped>true</shipped>
|
||||
</info>
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{
|
||||
|
||||
// Create the xml for the user supplied
|
||||
function export( ){
|
||||
$options = array(
|
||||
'table'=>'bookmarks',
|
||||
'matchcol'=>'user_id',
|
||||
'matchval'=>$this->uid,
|
||||
'idcol'=>'id'
|
||||
);
|
||||
$ids = $this->content->copyRows( $options );
|
||||
|
||||
$options = array(
|
||||
'table'=>'bookmarks_tags',
|
||||
'matchcol'=>'bookmark_id',
|
||||
'matchval'=>$ids
|
||||
);
|
||||
|
||||
// Export tags
|
||||
$ids2 = $this->content->copyRows( $options );
|
||||
|
||||
// If both returned some ids then they worked
|
||||
if( is_array( $ids ) && is_array( $ids2 ) )
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Import function for bookmarks
|
||||
function import( ){
|
||||
switch( $this->appinfo->version ){
|
||||
default:
|
||||
// All versions of the app have had the same db structure, so all can use the same import function
|
||||
$query = $this->content->prepare( "SELECT * FROM bookmarks WHERE user_id LIKE ?" );
|
||||
$results = $query->execute( array( $this->olduid ) );
|
||||
$idmap = array();
|
||||
while( $row = $results->fetchRow() ){
|
||||
// Import each bookmark, saving its id into the map
|
||||
$bookmarkquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" );
|
||||
$bookmarkquery->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) );
|
||||
// Map the id
|
||||
$idmap[$row['id']] = OCP\DB::insertid();
|
||||
}
|
||||
// Now tags
|
||||
foreach($idmap as $oldid => $newid){
|
||||
$query = $this->content->prepare( "SELECT * FROM bookmarks_tags WHERE bookmark_id LIKE ?" );
|
||||
$results = $query->execute( array( $oldid ) );
|
||||
while( $row = $results->fetchRow() ){
|
||||
// Import the tags for this bookmark, using the new bookmark id
|
||||
$tagquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks_tags(bookmark_id, tag) VALUES (?, ?)" );
|
||||
$tagquery->execute( array( $newid, $row['tag'] ) );
|
||||
}
|
||||
}
|
||||
// All done!
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load the provider
|
||||
new OC_Migration_Provider_Bookmarks( 'bookmarks' );
|
|
@ -1 +0,0 @@
|
|||
0.2
|
|
@ -1,130 +0,0 @@
|
|||
<?php
|
||||
|
||||
// Source: http://www.php.net/manual/de/function.curl-setopt.php#102121
|
||||
// This works around a safe_mode/open_basedir restriction
|
||||
function curl_exec_follow(/*resource*/ $ch, /*int*/ &$maxredirect = null) {
|
||||
$mr = $maxredirect === null ? 5 : intval($maxredirect);
|
||||
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
||||
if ($mr > 0) {
|
||||
$newurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
||||
|
||||
$rch = curl_copy_handle($ch);
|
||||
curl_setopt($rch, CURLOPT_HEADER, true);
|
||||
curl_setopt($rch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
|
||||
curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
|
||||
do {
|
||||
curl_setopt($rch, CURLOPT_URL, $newurl);
|
||||
$header = curl_exec($rch);
|
||||
if (curl_errno($rch)) {
|
||||
$code = 0;
|
||||
} else {
|
||||
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
||||
if ($code == 301 || $code == 302) {
|
||||
preg_match('/Location:(.*?)\n/', $header, $matches);
|
||||
$newurl = trim(array_pop($matches));
|
||||
} else {
|
||||
$code = 0;
|
||||
}
|
||||
}
|
||||
} while ($code && --$mr);
|
||||
curl_close($rch);
|
||||
if (!$mr) {
|
||||
if ($maxredirect === null) {
|
||||
trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
|
||||
} else {
|
||||
$maxredirect = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $newurl);
|
||||
}
|
||||
}
|
||||
return curl_exec($ch);
|
||||
}
|
||||
|
||||
function getURLMetadata($url) {
|
||||
//allow only http(s) and (s)ftp
|
||||
$protocols = '/^[hs]{0,1}[tf]{0,1}tp[s]{0,1}\:\/\//i';
|
||||
//if not (allowed) protocol is given, assume http
|
||||
if(preg_match($protocols, $url) == 0) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
$metadata['url'] = $url;
|
||||
|
||||
if (!function_exists('curl_init')){
|
||||
return $metadata;
|
||||
}
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$page = curl_exec_follow($ch);
|
||||
curl_close($ch);
|
||||
|
||||
@preg_match( "/<title>(.*)<\/title>/si", $page, $match );
|
||||
$metadata['title'] = htmlspecialchars_decode(@$match[1]);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
function addBookmark($url, $title, $tags='') {
|
||||
$CONFIG_DBTYPE = OCP\Config::getSystemValue( "dbtype", "sqlite" );
|
||||
if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
|
||||
$_ut = "strftime('%s','now')";
|
||||
} elseif($CONFIG_DBTYPE == 'pgsql') {
|
||||
$_ut = 'date_part(\'epoch\',now())::integer';
|
||||
} else {
|
||||
$_ut = "UNIX_TIMESTAMP()";
|
||||
}
|
||||
|
||||
//FIXME: Detect when user adds a known URL
|
||||
$query = OCP\DB::prepare("
|
||||
INSERT INTO *PREFIX*bookmarks
|
||||
(url, title, user_id, public, added, lastmodified)
|
||||
VALUES (?, ?, ?, 0, $_ut, $_ut)
|
||||
");
|
||||
|
||||
if(empty($title)) {
|
||||
$metadata = getURLMetadata($url);
|
||||
if(isset($metadata['title'])) // Check for problems fetching the title
|
||||
$title = $metadata['title'];
|
||||
}
|
||||
|
||||
if(empty($title)) {
|
||||
$l = OC_L10N::get('bookmarks');
|
||||
$title = $l->t('unnamed');
|
||||
}
|
||||
|
||||
$params=array(
|
||||
htmlspecialchars_decode($url),
|
||||
htmlspecialchars_decode($title),
|
||||
OCP\USER::getUser()
|
||||
);
|
||||
$query->execute($params);
|
||||
|
||||
$b_id = OCP\DB::insertid('*PREFIX*bookmarks');
|
||||
|
||||
if($b_id !== false) {
|
||||
$query = OCP\DB::prepare("
|
||||
INSERT INTO *PREFIX*bookmarks_tags
|
||||
(bookmark_id, tag)
|
||||
VALUES (?, ?)
|
||||
");
|
||||
|
||||
$tags = explode(' ', urldecode($tags));
|
||||
foreach ($tags as $tag) {
|
||||
if(empty($tag)) {
|
||||
//avoid saving blankspaces
|
||||
continue;
|
||||
}
|
||||
$params = array($b_id, trim($tag));
|
||||
$query->execute($params);
|
||||
}
|
||||
|
||||
return $b_id;
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
#content { overflow: auto; height: 100%; }
|
||||
#firstrun { width: 80%; margin: 5em auto auto auto; text-align: center; font-weight:bold; font-size:1.5em; color:#777; position: relative;}
|
||||
#firstrun small { display: block; font-weight: normal; font-size: 0.5em; margin-bottom: 1.5em; }
|
||||
#firstrun .button { font-size: 0.7em; }
|
||||
#firstrun #selections { font-size:0.8em; font-weight: normal; width: 100%; margin: 2em auto auto auto; clear: both; }
|
||||
|
||||
.bookmarks_headline {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
margin-left: 2em;
|
||||
padding: 2.5ex 0.5ex;
|
||||
}
|
||||
|
||||
.bookmarks_menu {
|
||||
margin-left: 1.5em;
|
||||
padding: 0.5ex;
|
||||
}
|
||||
|
||||
.bookmarks_list {
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
top: 6.5em;
|
||||
}
|
||||
|
||||
.bookmarks_addBml {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.bookmarks_label {
|
||||
width: 7em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.bookmarks_input {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.bookmark_actions {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 0.7em;
|
||||
display: none;
|
||||
}
|
||||
.bookmark_actions span { margin: 0 0.4em; }
|
||||
.bookmark_actions img { opacity: 0.3; }
|
||||
.bookmark_actions img:hover { opacity: 1; cursor: pointer; }
|
||||
|
||||
.bookmark_single {
|
||||
position: relative;
|
||||
padding: 0.5em 1em;
|
||||
border-bottom: 1px solid #DDD;
|
||||
-webkit-transition:background-color 500ms; -moz-transition:background-color 500ms; -o-transition:background-color 500ms; transition:background-color 500ms;
|
||||
}
|
||||
|
||||
.bookmark_single:hover {
|
||||
background-color:#f8f8f8
|
||||
}
|
||||
|
||||
.bookmark_single:hover .bookmark_actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.bookmark_title { font-weight: bold; display: inline-block; margin-right: 0.8em; }
|
||||
.bookmark_url { display: none; color: #999; }
|
||||
.bookmark_single:hover .bookmark_url { display: inline; }
|
||||
.bookmark_tags {
|
||||
position: absolute;
|
||||
top: 0.5em;
|
||||
right: 6em;
|
||||
text-align: right;
|
||||
}
|
||||
.bookmark_tag {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
margin: 0 0.2em;
|
||||
padding: 0 0.4em;
|
||||
background-color: #1D2D44;
|
||||
border-radius: 0.4em;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.bookmark_tag:hover { opacity: 0.5; }
|
||||
|
||||
.loading_meta {
|
||||
display: none;
|
||||
margin-left: 5px;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 496 B |
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\User::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('bookmarks');
|
||||
|
||||
OCP\App::setActiveNavigationEntry( 'bookmarks_index' );
|
||||
|
||||
OCP\Util::addscript('bookmarks','bookmarks');
|
||||
OCP\Util::addStyle('bookmarks', 'bookmarks');
|
||||
|
||||
$tmpl = new OCP\Template( 'bookmarks', 'list', 'user' );
|
||||
|
||||
$tmpl->printPage();
|
|
@ -1,16 +0,0 @@
|
|||
$(document).ready(function() {
|
||||
$('#bookmark_add_submit').click(addBookmark);
|
||||
});
|
||||
|
||||
function addBookmark(event) {
|
||||
var url = $('#bookmark_add_url').val();
|
||||
var tags = $('#bookmark_add_tags').val();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'ajax/addBookmark.php',
|
||||
data: 'url=' + encodeURI(url) + '&tags=' + encodeURI(tags),
|
||||
success: function(data){
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
var bookmarks_page = 0;
|
||||
var bookmarks_loading = false;
|
||||
|
||||
var bookmarks_sorting = 'bookmarks_sorting_recent';
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#bookmark_add_submit').click(addOrEditBookmark);
|
||||
$(window).resize(function () {
|
||||
fillWindow($('.bookmarks_list'));
|
||||
});
|
||||
$(window).resize();
|
||||
$('.bookmarks_list').scroll(updateOnBottom).empty().width($('#content').width());
|
||||
getBookmarks();
|
||||
});
|
||||
|
||||
function getBookmarks() {
|
||||
if(bookmarks_loading) {
|
||||
//have patience :)
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'updateList.php'),
|
||||
data: 'tag=' + encodeURIComponent($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
|
||||
success: function(bookmarks){
|
||||
if (bookmarks.data.length) {
|
||||
bookmarks_page += 1;
|
||||
}
|
||||
$('.bookmark_link').unbind('click', recordClick);
|
||||
$('.bookmark_delete').unbind('click', delBookmark);
|
||||
$('.bookmark_edit').unbind('click', showBookmark);
|
||||
|
||||
for(var i in bookmarks.data) {
|
||||
updateBookmarksList(bookmarks.data[i]);
|
||||
$("#firstrun").hide();
|
||||
}
|
||||
if($('.bookmarks_list').is(':empty')) {
|
||||
$("#firstrun").show();
|
||||
}
|
||||
|
||||
$('.bookmark_link').click(recordClick);
|
||||
$('.bookmark_delete').click(delBookmark);
|
||||
$('.bookmark_edit').click(showBookmark);
|
||||
|
||||
bookmarks_loading = false;
|
||||
if (bookmarks.data.length) {
|
||||
updateOnBottom()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// function addBookmark() {
|
||||
// Instead of creating editBookmark() function, Converted the one above to
|
||||
// addOrEditBookmark() to make .js file more compact.
|
||||
|
||||
function addOrEditBookmark(event) {
|
||||
var id = $('#bookmark_add_id').val();
|
||||
var url = encodeEntities($('#bookmark_add_url').val());
|
||||
var title = encodeEntities($('#bookmark_add_title').val());
|
||||
var tags = encodeEntities($('#bookmark_add_tags').val());
|
||||
$("#firstrun").hide();
|
||||
if($.trim(url) == '') {
|
||||
OC.dialogs.alert('A valid bookmark url must be provided', 'Error creating bookmark');
|
||||
return false;
|
||||
}
|
||||
if($.trim(title) == '') {
|
||||
OC.dialogs.alert('A valid bookmark title must be provided', 'Error creating bookmark');
|
||||
return false;
|
||||
}
|
||||
if (id == 0) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'addBookmark.php'),
|
||||
data: 'url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(response){
|
||||
$('.bookmarks_input').val('');
|
||||
$('.bookmarks_list').empty();
|
||||
bookmarks_page = 0;
|
||||
getBookmarks();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'editBookmark.php'),
|
||||
data: 'id=' + id + '&url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(){
|
||||
$('.bookmarks_input').val('');
|
||||
$('#bookmark_add_id').val('0');
|
||||
$('.bookmarks_list').empty();
|
||||
bookmarks_page = 0;
|
||||
getBookmarks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function delBookmark(event) {
|
||||
var record = $(this).parent().parent();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'delBookmark.php'),
|
||||
data: 'id=' + record.data('id'),
|
||||
success: function(data){
|
||||
if (data.status == 'success') {
|
||||
record.remove();
|
||||
if($('.bookmarks_list').is(':empty')) {
|
||||
$("#firstrun").show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showBookmark(event) {
|
||||
var record = $(this).parent().parent();
|
||||
$('#bookmark_add_id').val(record.attr('data-id'));
|
||||
$('#bookmark_add_url').val(record.children('.bookmark_url:first').text());
|
||||
$('#bookmark_add_title').val(record.children('.bookmark_title:first').text());
|
||||
$('#bookmark_add_tags').val(record.children('.bookmark_tags:first').text());
|
||||
|
||||
if ($('.bookmarks_add').css('display') == 'none') {
|
||||
$('.bookmarks_add').slideToggle();
|
||||
}
|
||||
}
|
||||
|
||||
function replaceQueryString(url,param,value) {
|
||||
var re = new RegExp("([?|&])" + param + "=.*?(&|$)","i");
|
||||
if (url.match(re))
|
||||
return url.replace(re,'$1' + param + "=" + value + '$2');
|
||||
else
|
||||
return url + '&' + param + "=" + value;
|
||||
}
|
||||
|
||||
function updateBookmarksList(bookmark) {
|
||||
var tags = encodeEntities(bookmark.tags).split(' ');
|
||||
var taglist = '';
|
||||
for ( var i=0, len=tags.length; i<len; ++i ){
|
||||
if(tags[i] != '')
|
||||
taglist = taglist + '<a class="bookmark_tag" href="'+replaceQueryString( String(window.location), 'tag', encodeURIComponent(tags[i])) + '">' + tags[i] + '</a> ';
|
||||
}
|
||||
if(!hasProtocol(bookmark.url)) {
|
||||
bookmark.url = 'http://' + bookmark.url;
|
||||
}
|
||||
if(bookmark.title == '') bookmark.title = bookmark.url;
|
||||
$('.bookmarks_list').append(
|
||||
'<div class="bookmark_single" data-id="' + bookmark.id +'" >' +
|
||||
'<p class="bookmark_actions">' +
|
||||
'<span class="bookmark_edit">' +
|
||||
'<img class="svg" src="'+OC.imagePath('core', 'actions/rename')+'" title="Edit">' +
|
||||
'</span>' +
|
||||
'<span class="bookmark_delete">' +
|
||||
'<img class="svg" src="'+OC.imagePath('core', 'actions/delete')+'" title="Delete">' +
|
||||
'</span> ' +
|
||||
'</p>' +
|
||||
'<p class="bookmark_title">'+
|
||||
'<a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.title) + '</a>' +
|
||||
'</p>' +
|
||||
'<p class="bookmark_url"><a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.url) + '</a></p>' +
|
||||
'</div>'
|
||||
);
|
||||
if(taglist != '') {
|
||||
$('div[data-id="'+ bookmark.id +'"]').append('<p class="bookmark_tags">' + taglist + '</p>');
|
||||
}
|
||||
}
|
||||
|
||||
function updateOnBottom() {
|
||||
//check wether user is on bottom of the page
|
||||
var top = $('.bookmarks_list>:last-child').position().top;
|
||||
var height = $('.bookmarks_list').height();
|
||||
// use a bit of margin to begin loading before we are really at the
|
||||
// bottom
|
||||
if (top < height * 1.2) {
|
||||
getBookmarks();
|
||||
}
|
||||
}
|
||||
|
||||
function recordClick(event) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'recordClick.php'),
|
||||
data: 'url=' + encodeURIComponent($(this).attr('href')),
|
||||
});
|
||||
}
|
||||
|
||||
function encodeEntities(s){
|
||||
try {
|
||||
return $('<div/>').text(s).html();
|
||||
} catch (ex) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function hasProtocol(url) {
|
||||
var regexp = /(ftp|http|https|sftp)/;
|
||||
return regexp.test(url);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2012 David Iwanowitsch <david at unclouded dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
$(document).ready(function(){
|
||||
OC.search.customResults['Bookm.'] = function(row,item){
|
||||
var a=row.find('a');
|
||||
a.attr('target','_blank');
|
||||
a.click(recordClick);
|
||||
}
|
||||
});
|
||||
|
||||
function recordClick(event) {
|
||||
var jsFileLocation = $('script[src*=bookmarksearch]').attr('src');
|
||||
jsFileLocation = jsFileLocation.replace('js/bookmarksearch.js', '');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: jsFileLocation + 'ajax/recordClick.php',
|
||||
data: 'url=' + encodeURI($(this).attr('href')),
|
||||
});
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
../appinfo/app.php
|
||||
../lib/search.php
|
||||
../templates/settings.php
|
||||
../templates/addBm.php
|
||||
../templates/list.php
|
|
@ -1,148 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author Arthur Schiwon
|
||||
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.de
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class manages bookmarks
|
||||
*/
|
||||
class OC_Bookmarks_Bookmarks{
|
||||
|
||||
/**
|
||||
* @brief Finds all bookmarks, matching the filter
|
||||
* @param offset result offset
|
||||
* @param sqlSortColumn sort result with this column
|
||||
* @param filter can be: empty -> no filter, a string -> filter this, a string array -> filter for all strings
|
||||
* @param filterTagOnly if true, filter affacts only tags, else filter affects url, title and tags
|
||||
* @return void
|
||||
*/
|
||||
public static function findBookmarks($offset, $sqlSortColumn, $filter, $filterTagOnly){
|
||||
//OCP\Util::writeLog('bookmarks', 'findBookmarks ' .$offset. ' '.$sqlSortColumn.' '. $filter.' '. $filterTagOnly ,OCP\Util::DEBUG);
|
||||
$CONFIG_DBTYPE = OCP\Config::getSystemValue( 'dbtype', 'sqlite' );
|
||||
|
||||
$params=array(OCP\USER::getUser());
|
||||
|
||||
if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
|
||||
$_gc_separator = ', \' \'';
|
||||
} else {
|
||||
$_gc_separator = 'SEPARATOR \' \'';
|
||||
}
|
||||
|
||||
if($filter){
|
||||
if($CONFIG_DBTYPE == 'pgsql' )
|
||||
$tagString = 'array_to_string(array_agg(tag), \' \')';
|
||||
else
|
||||
$tagString = 'tags';
|
||||
|
||||
$sqlFilterTag = 'HAVING ';
|
||||
if(is_array($filter)){
|
||||
$first = true;
|
||||
$filterstring = '';
|
||||
foreach ($filter as $singleFilter){
|
||||
$filterstring = $filterstring . ($first?'':' AND ') . $tagString.' LIKE ? ';
|
||||
$params[] = '%'.$singleFilter.'%';
|
||||
$first=false;
|
||||
}
|
||||
$sqlFilterTag = $sqlFilterTag . $filterstring;
|
||||
} else{
|
||||
$sqlFilterTag = $sqlFilterTag .$tagString.' LIKE ? ';
|
||||
$params[] = '%'.$filter.'%';
|
||||
}
|
||||
} else {
|
||||
$sqlFilterTag = '';
|
||||
}
|
||||
|
||||
if($CONFIG_DBTYPE == 'pgsql' ){
|
||||
$query = OCP\DB::prepare('
|
||||
SELECT id, url, title, '.($filterTagOnly?'':'url || title ||').' array_to_string(array_agg(tag), \' \') as tags
|
||||
FROM *PREFIX*bookmarks
|
||||
LEFT JOIN *PREFIX*bookmarks_tags ON *PREFIX*bookmarks.id = *PREFIX*bookmarks_tags.bookmark_id
|
||||
WHERE
|
||||
*PREFIX*bookmarks.user_id = ?
|
||||
GROUP BY id, url, title
|
||||
'.$sqlFilterTag.'
|
||||
ORDER BY *PREFIX*bookmarks.'.$sqlSortColumn.' DESC
|
||||
LIMIT 10
|
||||
OFFSET '. $offset);
|
||||
} else {
|
||||
if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' )
|
||||
$concatFunction = '(url || title || ';
|
||||
else
|
||||
$concatFunction = 'Concat(Concat( url, title), ';
|
||||
|
||||
$query = OCP\DB::prepare('
|
||||
SELECT id, url, title, '
|
||||
.($filterTagOnly?'':$concatFunction).
|
||||
'CASE WHEN *PREFIX*bookmarks.id = *PREFIX*bookmarks_tags.bookmark_id
|
||||
THEN GROUP_CONCAT( tag ' .$_gc_separator. ' )
|
||||
ELSE \' \'
|
||||
END '
|
||||
.($filterTagOnly?'':')').'
|
||||
AS tags
|
||||
FROM *PREFIX*bookmarks
|
||||
LEFT JOIN *PREFIX*bookmarks_tags ON 1=1
|
||||
WHERE (*PREFIX*bookmarks.id = *PREFIX*bookmarks_tags.bookmark_id
|
||||
OR *PREFIX*bookmarks.id NOT IN (
|
||||
SELECT *PREFIX*bookmarks_tags.bookmark_id FROM *PREFIX*bookmarks_tags
|
||||
)
|
||||
)
|
||||
AND *PREFIX*bookmarks.user_id = ?
|
||||
GROUP BY url
|
||||
'.$sqlFilterTag.'
|
||||
ORDER BY *PREFIX*bookmarks.'.$sqlSortColumn.' DESC
|
||||
LIMIT '.$offset.', 10');
|
||||
}
|
||||
|
||||
$bookmarks = $query->execute($params)->fetchAll();
|
||||
return $bookmarks;
|
||||
}
|
||||
|
||||
public static function deleteUrl($id)
|
||||
{
|
||||
$user = OCP\USER::getUser();
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
SELECT id FROM *PREFIX*bookmarks
|
||||
WHERE id = ?
|
||||
AND user_id = ?
|
||||
");
|
||||
|
||||
$result = $query->execute(array($id, $user));
|
||||
$id = $result->fetchOne();
|
||||
if ($id === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
DELETE FROM *PREFIX*bookmarks
|
||||
WHERE id = $id
|
||||
");
|
||||
|
||||
$result = $query->execute();
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
DELETE FROM *PREFIX*bookmarks_tags
|
||||
WHERE bookmark_id = $id
|
||||
");
|
||||
|
||||
$result = $query->execute();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - bookmarks plugin
|
||||
*
|
||||
* @author David Iwanowitsch
|
||||
* @copyright 2012 David Iwanowitsch <david at unclouded dot de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
class OC_Search_Provider_Bookmarks extends OC_Search_Provider{
|
||||
function search($query){
|
||||
$results=array();
|
||||
|
||||
$offset = 0;
|
||||
$sqlSortColumn = 'id';
|
||||
|
||||
$searchquery=array();
|
||||
if(substr_count($query, ' ') > 0){
|
||||
$searchquery = explode(' ', $query);
|
||||
}else{
|
||||
$searchquery = $query;
|
||||
}
|
||||
|
||||
// OCP\Util::writeLog('bookmarks', 'search ' .$query ,OCP\Util::DEBUG);
|
||||
$bookmarks = OC_Bookmarks_Bookmarks::findBookmarks($offset, $sqlSortColumn, $searchquery, false);
|
||||
// OCP\Util::writeLog('bookmarks', 'found ' .count($bookmarks) ,OCP\Util::DEBUG);
|
||||
//$l = new OC_l10n('bookmarks'); //resulttype can't be localized, javascript relies on that type
|
||||
foreach($bookmarks as $bookmark){
|
||||
$results[]=new OC_Search_Result($bookmark['title'],'', $bookmark['url'],'Bookm.');
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Marvin Thomas Rabe <mrabe@marvinrabe.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$tmpl = new OCP\Template( 'bookmarks', 'settings');
|
||||
|
||||
return $tmpl->fetchPage();
|
|
@ -1,11 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Read later - ownCloud</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message"><h1>Saved!</h1></div>
|
||||
<a href="javascript:self.close()" >Close the window</a>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
function createBookmarklet() {
|
||||
$l = OC_L10N::get('bookmarks');
|
||||
echo '<small>' . $l->t('Drag this to your browser bookmarks and click it, when you want to bookmark a webpage quickly:') . '</small>'
|
||||
. '<a class="button bookmarklet" href="javascript:(function(){var a=window,b=document,c=encodeURIComponent,d=a.open(\'' . OCP\Util::linkToAbsolute('bookmarks', 'addBm.php') . '?output=popup&url=\'+c(b.location),\'bkmk_popup\',\'left=\'+((a.screenX||a.screenLeft)+10)+\',top=\'+((a.screenY||a.screenTop)+10)+\',height=230px,width=230px,resizable=1,alwaysRaised=1\');a.setTimeout(function(){d.focus()},300);})();">'
|
||||
. $l->t('Read later') . '</a>';
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Marvin Thomas Rabe <mrabe@marvinrabe.de>
|
||||
* Copyright (c) 2011 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
?>
|
||||
<input type="hidden" id="bookmarkFilterTag" value="<?php if(isset($_GET['tag'])) echo OCP\Util::sanitizeHTML($_GET['tag']); ?>" />
|
||||
<div id="controls">
|
||||
<input type="hidden" id="bookmark_add_id" value="0" />
|
||||
<input type="text" id="bookmark_add_url" placeholder="<?php echo $l->t('Address'); ?>" class="bookmarks_input" />
|
||||
<input type="text" id="bookmark_add_title" placeholder="<?php echo $l->t('Title'); ?>" class="bookmarks_input" />
|
||||
<input type="text" id="bookmark_add_tags" placeholder="<?php echo $l->t('Tags'); ?>" class="bookmarks_input" />
|
||||
<input type="submit" value="<?php echo $l->t('Save bookmark'); ?>" id="bookmark_add_submit" />
|
||||
</div>
|
||||
<div class="bookmarks_list">
|
||||
</div>
|
||||
<div id="firstrun" style="display: none;">
|
||||
<?php
|
||||
echo $l->t('You have no bookmarks');
|
||||
require_once(OC_App::getAppPath('bookmarks') .'/templates/bookmarklet.php');
|
||||
createBookmarklet();
|
||||
?>
|
||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Marvin Thomas Rabe <mrabe@marvinrabe.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
?>
|
||||
<form id="bookmarks">
|
||||
<fieldset class="personalblock">
|
||||
<span class="bold"><?php echo $l->t('Bookmarklet <br />');?></span>
|
||||
<?php
|
||||
require_once('bookmarklet.php');
|
||||
createBookmarklet();
|
||||
?>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <georg@ownCloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
foreach($calendars as $calendar){
|
||||
OC_Calendar_Repeat::cleancalendar($calendar['id']);
|
||||
OC_Calendar_Repeat::generatecalendar($calendar['id']);
|
||||
}
|
||||
OCP\JSON::success();
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <georg@ownCloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
$allcached = true;
|
||||
foreach($calendars as $calendar){
|
||||
if(!OC_Calendar_Repeat::is_calendar_cached($calendar['id'])){
|
||||
$allcached = false;
|
||||
}
|
||||
}
|
||||
$l = new OC_L10N('calendar');
|
||||
if(!$allcached){
|
||||
OCP\JSON::error(array('message'=>'Not all calendars are completely cached', 'l10n'=>$l->t('Not all calendars are completely cached')));
|
||||
}else{
|
||||
OCP\JSON::success(array('message'=>'Everything seems to be completely cached', 'l10n'=>$l->t('Everything seems to be completely cached')));
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
$calendarid = $_POST['calendarid'];
|
||||
$calendar = OC_Calendar_App::getCalendar($calendarid, true);
|
||||
if(!$calendar){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
OC_Calendar_Calendar::setCalendarActive($calendarid, $_POST['active']);
|
||||
$calendar = OC_Calendar_App::getCalendar($calendarid);
|
||||
OCP\JSON::success(array(
|
||||
'active' => $calendar['active'],
|
||||
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
|
||||
));
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
$cal = $_POST["calendarid"];
|
||||
$calendar = OC_Calendar_App::getCalendar($cal, true);
|
||||
if(!$calendar){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
$del = OC_Calendar_Calendar::deleteCalendar($cal);
|
||||
if($del == true){
|
||||
OCP\JSON::success();
|
||||
}else{
|
||||
OCP\JSON::error(array('error'=>'dberror'));
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
|
||||
$calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
|
||||
$calendar = OC_Calendar_App::getCalendar($_POST['calendarid']);
|
||||
$tmpl = new OCP\Template("calendar", "part.editcalendar");
|
||||
$tmpl->assign('new', false);
|
||||
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
|
||||
$tmpl->assign('calendar', $calendar);
|
||||
$tmpl->printPage();
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
|
||||
$calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
|
||||
$calendar = OC_Calendar_App::getCalendar($_GET['calendarid'], true);
|
||||
if(!$calendar){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
$tmpl = new OCP\Template("calendar", "part.editcalendar");
|
||||
$tmpl->assign('new', false);
|
||||
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
|
||||
$tmpl->assign('calendar', $calendar);
|
||||
$tmpl->printPage();
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
|
||||
$calendar = array(
|
||||
'id' => 'new',
|
||||
'displayname' => '',
|
||||
'calendarcolor' => '',
|
||||
);
|
||||
$tmpl = new OCP\Template('calendar', 'part.editcalendar');
|
||||
$tmpl->assign('new', true);
|
||||
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
|
||||
$tmpl->assign('calendar', $calendar);
|
||||
$tmpl->printPage();
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
if(trim($_POST['name']) == ''){
|
||||
OCP\JSON::error(array('message'=>'empty'));
|
||||
exit;
|
||||
}
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
foreach($calendars as $cal){
|
||||
if($cal['displayname'] == $_POST['name']){
|
||||
OCP\JSON::error(array('message'=>'namenotavailable'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$userid = OCP\USER::getUser();
|
||||
$calendarid = OC_Calendar_Calendar::addCalendar($userid, strip_tags($_POST['name']), 'VEVENT,VTODO,VJOURNAL', null, 0, $_POST['color']);
|
||||
OC_Calendar_Calendar::setCalendarActive($calendarid, 1);
|
||||
|
||||
$calendar = OC_Calendar_Calendar::find($calendarid);
|
||||
$tmpl = new OCP\Template('calendar', 'part.choosecalendar.rowfields');
|
||||
$tmpl->assign('calendar', $calendar);
|
||||
if(OC_Calendar_Share::allUsersSharedwith($calendarid, OC_Calendar_Share::CALENDAR) == array()){
|
||||
$shared = false;
|
||||
}else{
|
||||
$shared = true;
|
||||
}
|
||||
$tmpl->assign('shared', $shared);
|
||||
OCP\JSON::success(array(
|
||||
'page' => $tmpl->fetchPage(),
|
||||
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
|
||||
));
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
$l10n = OC_L10N::get('calendar');
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$output = new OCP\Template("calendar", "part.choosecalendar");
|
||||
$output -> printpage();
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
if(trim($_POST['name']) == ''){
|
||||
OCP\JSON::error(array('message'=>'empty'));
|
||||
exit;
|
||||
}
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
foreach($calendars as $cal){
|
||||
if($cal['displayname'] == $_POST['name'] && $cal['id'] != $_POST['id']){
|
||||
OCP\JSON::error(array('message'=>'namenotavailable'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$calendarid = $_POST['id'];
|
||||
$calendar = OC_Calendar_App::getCalendar($calendarid, true);
|
||||
if(!$calendar){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
OC_Calendar_Calendar::editCalendar($calendarid, strip_tags($_POST['name']), null, null, null, $_POST['color']);
|
||||
OC_Calendar_Calendar::setCalendarActive($calendarid, $_POST['active']);
|
||||
|
||||
$calendar = OC_Calendar_App::getCalendar($calendarid);
|
||||
$tmpl = new OCP\Template('calendar', 'part.choosecalendar.rowfields');
|
||||
$tmpl->assign('calendar', $calendar);
|
||||
if(OC_Calendar_Share::allUsersSharedwith($calendarid, OC_Calendar_Share::CALENDAR) == array()){
|
||||
$shared = false;
|
||||
}else{
|
||||
$shared = true;
|
||||
}
|
||||
$tmpl->assign('shared', $shared);
|
||||
OCP\JSON::success(array(
|
||||
'page' => $tmpl->fetchPage(),
|
||||
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
|
||||
));
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
foreach ($_POST as $key=>$element) {
|
||||
debug('_POST: '.$key.'=>'.print_r($element, true));
|
||||
}
|
||||
|
||||
function bailOut($msg) {
|
||||
OCP\JSON::error(array('data' => array('message' => $msg)));
|
||||
OCP\Util::writeLog('calendar','ajax/categories/rescan.php: '.$msg, OCP\Util::DEBUG);
|
||||
exit();
|
||||
}
|
||||
function debug($msg) {
|
||||
OCP\Util::writeLog('calendar','ajax/categories/rescan.php: '.$msg, OCP\Util::DEBUG);
|
||||
}
|
||||
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
if(count($calendars) == 0) {
|
||||
bailOut(OC_Calendar_App::$l10n->t('No calendars found.'));
|
||||
}
|
||||
$events = array();
|
||||
foreach($calendars as $calendar) {
|
||||
$calendar_events = OC_Calendar_Object::all($calendar['id']);
|
||||
$events = $events + $calendar_events;
|
||||
}
|
||||
if(count($events) == 0) {
|
||||
bailOut(OC_Calendar_App::$l10n->t('No events found.'));
|
||||
}
|
||||
|
||||
OC_Calendar_App::scanCategories($events);
|
||||
$categories = OC_Calendar_App::getCategoryOptions();
|
||||
|
||||
OCP\JSON::success(array('data' => array('categories'=>$categories)));
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$view = $_POST['v'];
|
||||
switch($view){
|
||||
case 'agendaWeek':
|
||||
case 'month';
|
||||
case 'list':
|
||||
break;
|
||||
default:
|
||||
OCP\JSON::error(array('message'=>'unexspected parameter: ' . $view));
|
||||
exit;
|
||||
}
|
||||
OCP\Config::setUserValue(OCP\USER::getUser(), 'calendar', 'currentview', $view);
|
||||
OCP\JSON::success();
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
$id = $_POST['id'];
|
||||
$access = OC_Calendar_App::getaccess($id, OC_Calendar_App::EVENT);
|
||||
if($access != 'owner' && $access != 'rw'){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
$result = OC_Calendar_Object::delete($id);
|
||||
OCP\JSON::success();
|
|
@ -1,272 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
if(!OCP\User::isLoggedIn()) {
|
||||
die('<script type="text/javascript">document.location = oc_webroot;</script>');
|
||||
}
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
|
||||
$id = $_POST['id'];
|
||||
$data = OC_Calendar_App::getEventObject($id, true, true);
|
||||
|
||||
if(!$data){
|
||||
OCP\JSON::error(array('data' => array('message' => self::$l10n->t('Wrong calendar'))));
|
||||
exit;
|
||||
}
|
||||
$access = OC_Calendar_App::getaccess($id, OC_Calendar_Share::EVENT);
|
||||
$object = OC_VObject::parse($data['calendardata']);
|
||||
$vevent = $object->VEVENT;
|
||||
|
||||
$dtstart = $vevent->DTSTART;
|
||||
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
|
||||
switch($dtstart->getDateType()) {
|
||||
case Sabre_VObject_Property_DateTime::UTC:
|
||||
$timeOffset = $_SESSION['timezone']*60;
|
||||
$newDT = $dtstart->getDateTime();
|
||||
$newDT->add(new DateInterval("PT" . $timeOffset . "M"));
|
||||
$dtstart->setDateTime($newDT);
|
||||
$newDT = $dtend->getDateTime();
|
||||
$newDT->add(new DateInterval("PT" . $timeOffset . "M"));
|
||||
$dtend->setDateTime($newDT);
|
||||
case Sabre_VObject_Property_DateTime::LOCALTZ:
|
||||
case Sabre_VObject_Property_DateTime::LOCAL:
|
||||
$startdate = $dtstart->getDateTime()->format('d-m-Y');
|
||||
$starttime = $dtstart->getDateTime()->format('H:i');
|
||||
$enddate = $dtend->getDateTime()->format('d-m-Y');
|
||||
$endtime = $dtend->getDateTime()->format('H:i');
|
||||
$allday = false;
|
||||
break;
|
||||
case Sabre_VObject_Property_DateTime::DATE:
|
||||
$startdate = $dtstart->getDateTime()->format('d-m-Y');
|
||||
$starttime = '';
|
||||
$dtend->getDateTime()->modify('-1 day');
|
||||
$enddate = $dtend->getDateTime()->format('d-m-Y');
|
||||
$endtime = '';
|
||||
$allday = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$summary = $vevent->getAsString('SUMMARY');
|
||||
$location = $vevent->getAsString('LOCATION');
|
||||
$categories = $vevent->getAsString('CATEGORIES');
|
||||
$description = $vevent->getAsString('DESCRIPTION');
|
||||
$last_modified = $vevent->__get('LAST-MODIFIED');
|
||||
if ($last_modified){
|
||||
$lastmodified = $last_modified->getDateTime()->format('U');
|
||||
}else{
|
||||
$lastmodified = 0;
|
||||
}
|
||||
if($data['repeating'] == 1){
|
||||
$rrule = explode(';', $vevent->getAsString('RRULE'));
|
||||
$rrulearr = array();
|
||||
foreach($rrule as $rule){
|
||||
list($attr, $val) = explode('=', $rule);
|
||||
$rrulearr[$attr] = $val;
|
||||
}
|
||||
if(!isset($rrulearr['INTERVAL']) || $rrulearr['INTERVAL'] == ''){
|
||||
$rrulearr['INTERVAL'] = 1;
|
||||
}
|
||||
if(array_key_exists('BYDAY', $rrulearr)){
|
||||
if(substr_count($rrulearr['BYDAY'], ',') == 0){
|
||||
if(strlen($rrulearr['BYDAY']) == 2){
|
||||
$repeat['weekdays'] = array($rrulearr['BYDAY']);
|
||||
}elseif(strlen($rrulearr['BYDAY']) == 3){
|
||||
$repeat['weekofmonth'] = substr($rrulearr['BYDAY'], 0, 1);
|
||||
$repeat['weekdays'] = array(substr($rrulearr['BYDAY'], 1, 2));
|
||||
}elseif(strlen($rrulearr['BYDAY']) == 4){
|
||||
$repeat['weekofmonth'] = substr($rrulearr['BYDAY'], 0, 2);
|
||||
$repeat['weekdays'] = array(substr($rrulearr['BYDAY'], 2, 2));
|
||||
}
|
||||
}else{
|
||||
$byday_days = explode(',', $rrulearr['BYDAY']);
|
||||
foreach($byday_days as $byday_day){
|
||||
if(strlen($byday_day) == 2){
|
||||
$repeat['weekdays'][] = $byday_day;
|
||||
}elseif(strlen($byday_day) == 3){
|
||||
$repeat['weekofmonth'] = substr($byday_day , 0, 1);
|
||||
$repeat['weekdays'][] = substr($byday_day , 1, 2);
|
||||
}elseif(strlen($byday_day) == 4){
|
||||
$repeat['weekofmonth'] = substr($byday_day , 0, 2);
|
||||
$repeat['weekdays'][] = substr($byday_day , 2, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(array_key_exists('BYMONTHDAY', $rrulearr)){
|
||||
if(substr_count($rrulearr['BYMONTHDAY'], ',') == 0){
|
||||
$repeat['bymonthday'][] = $rrulearr['BYMONTHDAY'];
|
||||
}else{
|
||||
$bymonthdays = explode(',', $rrulearr['BYMONTHDAY']);
|
||||
foreach($bymonthdays as $bymonthday){
|
||||
$repeat['bymonthday'][] = $bymonthday;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(array_key_exists('BYYEARDAY', $rrulearr)){
|
||||
if(substr_count($rrulearr['BYYEARDAY'], ',') == 0){
|
||||
$repeat['byyearday'][] = $rrulearr['BYYEARDAY'];
|
||||
}else{
|
||||
$byyeardays = explode(',', $rrulearr['BYYEARDAY']);
|
||||
foreach($byyeardays as $yearday){
|
||||
$repeat['byyearday'][] = $yearday;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(array_key_exists('BYWEEKNO', $rrulearr)){
|
||||
if(substr_count($rrulearr['BYWEEKNO'], ',') == 0){
|
||||
$repeat['byweekno'][] = (string) $rrulearr['BYWEEKNO'];
|
||||
}else{
|
||||
$byweekno = explode(',', $rrulearr['BYWEEKNO']);
|
||||
foreach($byweekno as $weekno){
|
||||
$repeat['byweekno'][] = (string) $weekno;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(array_key_exists('BYMONTH', $rrulearr)){
|
||||
$months = OC_Calendar_App::getByMonthOptions();
|
||||
if(substr_count($rrulearr['BYMONTH'], ',') == 0){
|
||||
$repeat['bymonth'][] = $months[$month];
|
||||
}else{
|
||||
$bymonth = explode(',', $rrulearr['BYMONTH']);
|
||||
foreach($bymonth as $month){
|
||||
$repeat['bymonth'][] = $months[$month];
|
||||
}
|
||||
}
|
||||
}
|
||||
switch($rrulearr['FREQ']){
|
||||
case 'DAILY':
|
||||
$repeat['repeat'] = 'daily';
|
||||
break;
|
||||
case 'WEEKLY':
|
||||
if($rrulearr['INTERVAL'] % 2 == 0){
|
||||
$repeat['repeat'] = 'biweekly';
|
||||
$rrulearr['INTERVAL'] = $rrulearr['INTERVAL'] / 2;
|
||||
}elseif($rrulearr['BYDAY'] == 'MO,TU,WE,TH,FR'){
|
||||
$repeat['repeat'] = 'weekday';
|
||||
}else{
|
||||
$repeat['repeat'] = 'weekly';
|
||||
}
|
||||
break;
|
||||
case 'MONTHLY':
|
||||
$repeat['repeat'] = 'monthly';
|
||||
if(array_key_exists('BYDAY', $rrulearr)){
|
||||
$repeat['month'] = 'weekday';
|
||||
}else{
|
||||
$repeat['month'] = 'monthday';
|
||||
}
|
||||
break;
|
||||
case 'YEARLY':
|
||||
$repeat['repeat'] = 'yearly';
|
||||
if(array_key_exists('BYMONTH', $rrulearr)){
|
||||
$repeat['year'] = 'bydaymonth';
|
||||
}elseif(array_key_exists('BYWEEKNO', $rrulearr)){
|
||||
$repeat['year'] = 'byweekno';
|
||||
}else{
|
||||
$repeat['year'] = 'byyearday';
|
||||
}
|
||||
}
|
||||
$repeat['interval'] = $rrulearr['INTERVAL'];
|
||||
if(array_key_exists('COUNT', $rrulearr)){
|
||||
$repeat['end'] = 'count';
|
||||
$repeat['count'] = $rrulearr['COUNT'];
|
||||
}elseif(array_key_exists('UNTIL', $rrulearr)){
|
||||
$repeat['end'] = 'date';
|
||||
$endbydate_day = substr($rrulearr['UNTIL'], 6, 2);
|
||||
$endbydate_month = substr($rrulearr['UNTIL'], 4, 2);
|
||||
$endbydate_year = substr($rrulearr['UNTIL'], 0, 4);
|
||||
$repeat['date'] = $endbydate_day . '-' . $endbydate_month . '-' . $endbydate_year;
|
||||
}else{
|
||||
$repeat['end'] = 'never';
|
||||
}
|
||||
if(array_key_exists('weekdays', $repeat)){
|
||||
$repeat_weekdays_ = array();
|
||||
$days = OC_Calendar_App::getWeeklyOptions();
|
||||
foreach($repeat['weekdays'] as $weekday){
|
||||
$repeat_weekdays_[] = $days[$weekday];
|
||||
}
|
||||
$repeat['weekdays'] = $repeat_weekdays_;
|
||||
}
|
||||
}else{
|
||||
$repeat['repeat'] = 'doesnotrepeat';
|
||||
}
|
||||
if($access == 'owner'){
|
||||
$calendar_options = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
}else{
|
||||
$calendar_options = array(OC_Calendar_App::getCalendar($data['calendarid'], false));
|
||||
}
|
||||
$category_options = OC_Calendar_App::getCategoryOptions();
|
||||
$repeat_options = OC_Calendar_App::getRepeatOptions();
|
||||
$repeat_end_options = OC_Calendar_App::getEndOptions();
|
||||
$repeat_month_options = OC_Calendar_App::getMonthOptions();
|
||||
$repeat_year_options = OC_Calendar_App::getYearOptions();
|
||||
$repeat_weekly_options = OC_Calendar_App::getWeeklyOptions();
|
||||
$repeat_weekofmonth_options = OC_Calendar_App::getWeekofMonth();
|
||||
$repeat_byyearday_options = OC_Calendar_App::getByYearDayOptions();
|
||||
$repeat_bymonth_options = OC_Calendar_App::getByMonthOptions();
|
||||
$repeat_byweekno_options = OC_Calendar_App::getByWeekNoOptions();
|
||||
$repeat_bymonthday_options = OC_Calendar_App::getByMonthDayOptions();
|
||||
|
||||
if($access == 'owner' || $access == 'rw'){
|
||||
$tmpl = new OCP\Template('calendar', 'part.editevent');
|
||||
}elseif($access == 'r'){
|
||||
$tmpl = new OCP\Template('calendar', 'part.showevent');
|
||||
}
|
||||
|
||||
$tmpl->assign('eventid', $id);
|
||||
$tmpl->assign('access', $access);
|
||||
$tmpl->assign('lastmodified', $lastmodified);
|
||||
$tmpl->assign('calendar_options', $calendar_options);
|
||||
$tmpl->assign('repeat_options', $repeat_options);
|
||||
$tmpl->assign('repeat_month_options', $repeat_month_options);
|
||||
$tmpl->assign('repeat_weekly_options', $repeat_weekly_options);
|
||||
$tmpl->assign('repeat_end_options', $repeat_end_options);
|
||||
$tmpl->assign('repeat_year_options', $repeat_year_options);
|
||||
$tmpl->assign('repeat_byyearday_options', $repeat_byyearday_options);
|
||||
$tmpl->assign('repeat_bymonth_options', $repeat_bymonth_options);
|
||||
$tmpl->assign('repeat_byweekno_options', $repeat_byweekno_options);
|
||||
$tmpl->assign('repeat_bymonthday_options', $repeat_bymonthday_options);
|
||||
$tmpl->assign('repeat_weekofmonth_options', $repeat_weekofmonth_options);
|
||||
|
||||
$tmpl->assign('title', $summary);
|
||||
$tmpl->assign('location', $location);
|
||||
$tmpl->assign('categories', $categories);
|
||||
$tmpl->assign('calendar', $data['calendarid']);
|
||||
$tmpl->assign('allday', $allday);
|
||||
$tmpl->assign('startdate', $startdate);
|
||||
$tmpl->assign('starttime', $starttime);
|
||||
$tmpl->assign('enddate', $enddate);
|
||||
$tmpl->assign('endtime', $endtime);
|
||||
$tmpl->assign('description', $description);
|
||||
|
||||
$tmpl->assign('repeat', $repeat['repeat']);
|
||||
if($repeat['repeat'] != 'doesnotrepeat'){
|
||||
$tmpl->assign('repeat_month', $repeat['month']);
|
||||
$tmpl->assign('repeat_weekdays', $repeat['weekdays']);
|
||||
$tmpl->assign('repeat_interval', $repeat['interval']);
|
||||
$tmpl->assign('repeat_end', $repeat['end']);
|
||||
$tmpl->assign('repeat_count', $repeat['count']);
|
||||
$tmpl->assign('repeat_weekofmonth', $repeat['weekofmonth']);
|
||||
$tmpl->assign('repeat_date', $repeat['date']);
|
||||
$tmpl->assign('repeat_year', $repeat['year']);
|
||||
$tmpl->assign('repeat_byyearday', $repeat['byyearday']);
|
||||
$tmpl->assign('repeat_bymonthday', $repeat['bymonthday']);
|
||||
$tmpl->assign('repeat_bymonth', $repeat['bymonth']);
|
||||
$tmpl->assign('repeat_byweekno', $repeat['byweekno']);
|
||||
} else {
|
||||
$tmpl->assign('repeat_month', 'monthday');
|
||||
$tmpl->assign('repeat_weekdays', array());
|
||||
$tmpl->assign('repeat_interval', 1);
|
||||
$tmpl->assign('repeat_end', 'never');
|
||||
$tmpl->assign('repeat_count', '10');
|
||||
$tmpl->assign('repeat_weekofmonth', 'auto');
|
||||
$tmpl->assign('repeat_date', '');
|
||||
$tmpl->assign('repeat_year', 'bydate');
|
||||
}
|
||||
$tmpl->printpage();
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
$id = $_POST['id'];
|
||||
|
||||
if(!array_key_exists('calendar', $_POST)){
|
||||
$cal = OC_Calendar_Object::getCalendarid($id);
|
||||
$_POST['calendar'] = $cal;
|
||||
}else{
|
||||
$cal = $_POST['calendar'];
|
||||
}
|
||||
|
||||
$access = OC_Calendar_App::getaccess($id, OC_Calendar_App::EVENT);
|
||||
if($access != 'owner' && $access != 'rw'){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$errarr = OC_Calendar_Object::validateRequest($_POST);
|
||||
if($errarr){
|
||||
//show validate errors
|
||||
OCP\JSON::error($errarr);
|
||||
exit;
|
||||
}else{
|
||||
$data = OC_Calendar_App::getEventObject($id, false, false);
|
||||
$vcalendar = OC_VObject::parse($data['calendardata']);
|
||||
|
||||
OC_Calendar_App::isNotModified($vcalendar->VEVENT, $_POST['lastmodified']);
|
||||
OC_Calendar_Object::updateVCalendarFromRequest($_POST, $vcalendar);
|
||||
|
||||
OC_Calendar_Object::edit($id, $vcalendar->serialize());
|
||||
if ($data['calendarid'] != $cal) {
|
||||
OC_Calendar_Object::moveToCalendar($id, $cal);
|
||||
}
|
||||
OCP\JSON::success();
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
|
||||
$id = $_POST['id'];
|
||||
$access = OC_Calendar_App::getaccess($id, OC_Calendar_App::EVENT);
|
||||
if($access != 'owner' && $access != 'rw'){
|
||||
OCP\JSON::error(array('message'=>'permission denied'));
|
||||
exit;
|
||||
}
|
||||
$vcalendar = OC_Calendar_App::getVCalendar($id, false, false);
|
||||
$vevent = $vcalendar->VEVENT;
|
||||
|
||||
$allday = $_POST['allDay'];
|
||||
$delta = new DateInterval('P0D');
|
||||
$delta->d = $_POST['dayDelta'];
|
||||
$delta->i = $_POST['minuteDelta'];
|
||||
OC_Calendar_App::isNotModified($vevent, $_POST['lastmodified']);
|
||||
|
||||
$dtstart = $vevent->DTSTART;
|
||||
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
|
||||
$start_type = $dtstart->getDateType();
|
||||
$end_type = $dtend->getDateType();
|
||||
if ($allday && $start_type != Sabre_VObject_Property_DateTime::DATE){
|
||||
$start_type = $end_type = Sabre_VObject_Property_DateTime::DATE;
|
||||
$dtend->setDateTime($dtend->getDateTime()->modify('+1 day'), $end_type);
|
||||
}
|
||||
if (!$allday && $start_type == Sabre_VObject_Property_DateTime::DATE){
|
||||
$start_type = $end_type = Sabre_VObject_Property_DateTime::LOCALTZ;
|
||||
}
|
||||
$dtstart->setDateTime($dtstart->getDateTime()->add($delta), $start_type);
|
||||
$dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
|
||||
unset($vevent->DURATION);
|
||||
|
||||
$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
|
||||
$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
|
||||
|
||||
$result = OC_Calendar_Object::edit($id, $vcalendar->serialize());
|
||||
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
|
||||
OCP\JSON::success(array('lastmodified'=>(int)$lastmodified->format('U')));
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue