diff options
Diffstat (limited to 'lib')
56 files changed, 855 insertions, 210 deletions
diff --git a/lib/base.php b/lib/base.php index 2d6601f306a..a9ddce98eae 100644 --- a/lib/base.php +++ b/lib/base.php @@ -20,6 +20,8 @@ * */ +require_once 'public/constants.php'; + /** * Class that is a namespace for all global OC variables * No, we can not put this class in its own file because it is used by @@ -231,12 +233,10 @@ class OC{ if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { if(!OC_Util::ishtaccessworking()) { if(!file_exists(OC::$SERVERROOT.'/data/.htaccess')) { - $content = "deny from all\n"; - $content.= "IndexIgnore *"; - file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.htaccess', $content); + OC_Setup::protectDataDirectory(); } } - } + } OC_Log::write('core', 'starting upgrade from '.$installedVersion.' to '.$currentVersion, OC_Log::DEBUG); $result=OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml'); if(!$result) { @@ -294,7 +294,7 @@ class OC{ // (re)-initialize session session_start(); - + // regenerate session id periodically to avoid session fixation if (!isset($_SESSION['SID_CREATED'])) { $_SESSION['SID_CREATED'] = time(); @@ -362,6 +362,10 @@ class OC{ //try to set the session lifetime to 60min @ini_set('gc_maxlifetime', '3600'); + //copy http auth headers for apache+php-fcgid work around + if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) { + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION']; + } //set http auth headers for apache+php-cgi work around if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) { @@ -481,17 +485,7 @@ class OC{ */ public static function handleRequest() { if (!OC_Config::getValue('installed', false)) { - // Check for autosetup: - $autosetup_file = OC::$SERVERROOT."/config/autoconfig.php"; - if( file_exists( $autosetup_file )) { - OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', OC_Log::INFO); - include $autosetup_file; - $_POST['install'] = 'true'; - $_POST = array_merge ($_POST, $AUTOCONFIG); - unlink($autosetup_file); - } - OC_Util::addScript('setup'); - require_once 'setup.php'; + require_once 'core/setup.php'; exit(); } // Handle WebDAV diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index d4f58527d21..8d4dd92a3d4 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -124,15 +124,22 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } $properties = array_fill_keys($paths, array()); if(count($paths)>0) { - $placeholders = join(',', array_fill(0, count($paths), '?')); - $query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ?' . ' AND `propertypath` IN ('.$placeholders.')' ); - array_unshift($paths, OC_User::getUser()); // prepend userid - $result = $query->execute( $paths ); - while($row = $result->fetchRow()) { - $propertypath = $row['propertypath']; - $propertyname = $row['propertyname']; - $propertyvalue = $row['propertyvalue']; - $properties[$propertypath][$propertyname] = $propertyvalue; + // + // the number of arguments within IN conditions are limited in most databases + // we chunk $paths into arrays of 200 items each to meet this criteria + // + $chunks = array_chunk($paths, 200, false); + foreach ($chunks as $pack) { + $placeholders = join(',', array_fill(0, count($pack), '?')); + $query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ?' . ' AND `propertypath` IN ('.$placeholders.')' ); + array_unshift($pack, OC_User::getUser()); // prepend userid + $result = $query->execute( $pack ); + while($row = $result->fetchRow()) { + $propertypath = $row['propertypath']; + $propertyname = $row['propertyname']; + $propertyvalue = $row['propertyvalue']; + $properties[$propertypath][$propertyname] = $propertyvalue; + } } } diff --git a/lib/db.php b/lib/db.php index fba2687967f..de42626563d 100644 --- a/lib/db.php +++ b/lib/db.php @@ -542,6 +542,78 @@ class OC_DB { } /** + * @brief Insert a row if a matching row doesn't exists. + * @param string $table. The table to insert into in the form '*PREFIX*tableName' + * @param array $input. An array of fieldname/value pairs + * @returns The return value from PDOStatementWrapper->execute() + */ + public static function insertIfNotExist($table, $input) { + self::connect(); + $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); + $table = str_replace( '*PREFIX*', $prefix, $table ); + + if(is_null(self::$type)) { + self::$type=OC_Config::getValue( "dbtype", "sqlite" ); + } + $type = self::$type; + + $query = ''; + // differences in escaping of table names ('`' for mysql) and getting the current timestamp + if( $type == 'sqlite' || $type == 'sqlite3' ) { + // NOTE: For SQLite we have to use this clumsy approach + // otherwise all fieldnames used must have a unique key. + $query = 'SELECT * FROM "' . $table . '" WHERE '; + foreach($input as $key => $value) { + $query .= $key . " = '" . $value . '\' AND '; + } + $query = substr($query, 0, strlen($query) - 5); + try { + $stmt = self::prepare($query); + $result = $stmt->execute(); + } catch(PDOException $e) { + $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; + $entry .= 'Offending command was: ' . $query . '<br />'; + OC_Log::write('core', $entry, OC_Log::FATAL); + error_log('DB error: '.$entry); + die( $entry ); + } + + if($result->numRows() == 0) { + $query = 'INSERT INTO "' . $table . '" ("' + . implode('","', array_keys($input)) . '") VALUES("' + . implode('","', array_values($input)) . '")'; + } else { + return true; + } + } elseif( $type == 'pgsql' || $type == 'oci' || $type == 'mysql') { + $query = 'INSERT INTO `' .$table . '` (' + . implode(',', array_keys($input)) . ') SELECT \'' + . implode('\',\'', array_values($input)) . '\' FROM ' . $table . ' WHERE '; + + foreach($input as $key => $value) { + $query .= $key . " = '" . $value . '\' AND '; + } + $query = substr($query, 0, strlen($query) - 5); + $query .= ' HAVING COUNT(*) = 0'; + } + + // TODO: oci should be use " (quote) instead of ` (backtick). + //OC_Log::write('core', __METHOD__ . ', type: ' . $type . ', query: ' . $query, OC_Log::DEBUG); + + try { + $result = self::prepare($query); + } catch(PDOException $e) { + $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; + $entry .= 'Offending command was: ' . $query.'<br />'; + OC_Log::write('core', $entry, OC_Log::FATAL); + error_log('DB error: ' . $entry); + die( $entry ); + } + + return $result->execute(); + } + + /** * @brief does minor changes to query * @param string $query Query string * @return string corrected query string diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index a8219191bf3..80270728aba 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -43,7 +43,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ $userQuota=OC_AppConfig::getValue('files', 'default_quota', 'none'); } if($userQuota=='none') { - $this->userQuota[$user]=0; + $this->userQuota[$user]=-1; }else{ $this->userQuota[$user]=OC_Helper::computerFileSize($userQuota); } @@ -65,8 +65,8 @@ class OC_FileProxy_Quota extends OC_FileProxy{ $owner=$storage->getOwner($internalPath); $totalSpace=$this->getQuota($owner); - if($totalSpace==0) { - return 0; + if($totalSpace==-1) { + return -1; } $view = new \OC\Files\View("/".$owner."/files"); @@ -79,7 +79,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ public function postFree_space($path, $space) { $free=$this->getFreeSpace($path); - if($free==0) { + if($free==-1) { return $space; } return min($free, $space); @@ -89,21 +89,21 @@ class OC_FileProxy_Quota extends OC_FileProxy{ if (is_resource($data)) { $data = '';//TODO: find a way to get the length of the stream without emptying it } - return (strlen($data)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==0); + return (strlen($data)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==-1); } public function preCopy($path1, $path2) { if(!self::$rootView){ self::$rootView = new \OC\Files\View(''); } - return (self::$rootView->filesize($path1)<$this->getFreeSpace($path2) or $this->getFreeSpace($path2)==0); + return (self::$rootView->filesize($path1)<$this->getFreeSpace($path2) or $this->getFreeSpace($path2)==-1); } public function preFromTmpFile($tmpfile, $path) { - return (filesize($tmpfile)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==0); + return (filesize($tmpfile)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==-1); } public function preFromUploadedFile($tmpfile, $path) { - return (filesize($tmpfile)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==0); + return (filesize($tmpfile)<$this->getFreeSpace($path) or $this->getFreeSpace($path)==-1); } } diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php index fa7c27af5a5..34ce1c4fe74 100644 --- a/lib/l10n/ca.php +++ b/lib/l10n/ca.php @@ -22,7 +22,6 @@ "yesterday" => "ahir", "%d days ago" => "fa %d dies", "last month" => "el mes passat", -"months ago" => "mesos enrere", "last year" => "l'any passat", "years ago" => "fa anys", "%s is available. Get <a href=\"%s\">more information</a>" => "%s està disponible. Obtén <a href=\"%s\">més informació</a>", diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php index 72d9b955a41..095c4c4dfd0 100644 --- a/lib/l10n/cs_CZ.php +++ b/lib/l10n/cs_CZ.php @@ -22,7 +22,6 @@ "yesterday" => "včera", "%d days ago" => "před %d dny", "last month" => "minulý měsíc", -"months ago" => "před měsíci", "last year" => "loni", "years ago" => "před lety", "%s is available. Get <a href=\"%s\">more information</a>" => "%s je dostupná. Získat <a href=\"%s\">více informací</a>", diff --git a/lib/l10n/da.php b/lib/l10n/da.php index ca4a6c6eca6..7458b329782 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -21,7 +21,6 @@ "yesterday" => "I går", "%d days ago" => "%d dage siden", "last month" => "Sidste måned", -"months ago" => "måneder siden", "last year" => "Sidste år", "years ago" => "år siden", "%s is available. Get <a href=\"%s\">more information</a>" => "%s er tilgængelig. Få <a href=\"%s\">mere information</a>", diff --git a/lib/l10n/de.php b/lib/l10n/de.php index 28a35b39fbc..9398abd7b73 100644 --- a/lib/l10n/de.php +++ b/lib/l10n/de.php @@ -22,7 +22,6 @@ "yesterday" => "Gestern", "%d days ago" => "Vor %d Tag(en)", "last month" => "Letzten Monat", -"months ago" => "Vor wenigen Monaten", "last year" => "Letztes Jahr", "years ago" => "Vor wenigen Jahren", "%s is available. Get <a href=\"%s\">more information</a>" => "%s ist verfügbar. <a href=\"%s\">Weitere Informationen</a>", diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php index 032a3e932af..c2ff42d8570 100644 --- a/lib/l10n/de_DE.php +++ b/lib/l10n/de_DE.php @@ -22,7 +22,6 @@ "yesterday" => "Gestern", "%d days ago" => "Vor %d Tag(en)", "last month" => "Letzten Monat", -"months ago" => "Vor wenigen Monaten", "last year" => "Letztes Jahr", "years ago" => "Vor wenigen Jahren", "%s is available. Get <a href=\"%s\">more information</a>" => "%s ist verfügbar. <a href=\"%s\">Weitere Informationen</a>", diff --git a/lib/l10n/el.php b/lib/l10n/el.php index e6475ec08aa..71650ae24ae 100644 --- a/lib/l10n/el.php +++ b/lib/l10n/el.php @@ -21,7 +21,6 @@ "yesterday" => "χθές", "%d days ago" => "%d ημέρες πριν", "last month" => "τον προηγούμενο μήνα", -"months ago" => "μήνες πριν", "last year" => "τον προηγούμενο χρόνο", "years ago" => "χρόνια πριν", "%s is available. Get <a href=\"%s\">more information</a>" => "%s είναι διαθέσιμα. Δείτε <a href=\"%s\">περισσότερες πληροφορίες</a>", diff --git a/lib/l10n/eo.php b/lib/l10n/eo.php index e569101fc6b..f660c5743b5 100644 --- a/lib/l10n/eo.php +++ b/lib/l10n/eo.php @@ -21,7 +21,6 @@ "yesterday" => "hieraŭ", "%d days ago" => "antaŭ %d tagoj", "last month" => "lasta monato", -"months ago" => "monatojn antaŭe", "last year" => "lasta jaro", "years ago" => "jarojn antaŭe", "%s is available. Get <a href=\"%s\">more information</a>" => "%s haveblas. Ekhavu <a href=\"%s\">pli da informo</a>", diff --git a/lib/l10n/es.php b/lib/l10n/es.php index 6648c1ccd56..0019ba02b7f 100644 --- a/lib/l10n/es.php +++ b/lib/l10n/es.php @@ -22,7 +22,6 @@ "yesterday" => "ayer", "%d days ago" => "hace %d días", "last month" => "este mes", -"months ago" => "hace meses", "last year" => "este año", "years ago" => "hace años", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está disponible. Obtén <a href=\"%s\">más información</a>", diff --git a/lib/l10n/es_AR.php b/lib/l10n/es_AR.php index a9d9b35b265..93637a69d42 100644 --- a/lib/l10n/es_AR.php +++ b/lib/l10n/es_AR.php @@ -22,7 +22,6 @@ "yesterday" => "ayer", "%d days ago" => "hace %d días", "last month" => "este mes", -"months ago" => "hace meses", "last year" => "este año", "years ago" => "hace años", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está disponible. Conseguí <a href=\"%s\">más información</a>", diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php index 041c66caed0..906abf9430a 100644 --- a/lib/l10n/et_EE.php +++ b/lib/l10n/et_EE.php @@ -22,7 +22,6 @@ "yesterday" => "eile", "%d days ago" => "%d päeva tagasi", "last month" => "eelmisel kuul", -"months ago" => "kuud tagasi", "last year" => "eelmisel aastal", "years ago" => "aastat tagasi", "%s is available. Get <a href=\"%s\">more information</a>" => "%s on saadaval. Vaata <a href=\"%s\">lisainfot</a>", diff --git a/lib/l10n/eu.php b/lib/l10n/eu.php index c6c0e18ea99..ae1a89eb854 100644 --- a/lib/l10n/eu.php +++ b/lib/l10n/eu.php @@ -21,7 +21,6 @@ "yesterday" => "atzo", "%d days ago" => "orain dela %d egun", "last month" => "joan den hilabetea", -"months ago" => "orain dela hilabete batzuk", "last year" => "joan den urtea", "years ago" => "orain dela urte batzuk", "%s is available. Get <a href=\"%s\">more information</a>" => "%s eskuragarri dago. Lortu <a href=\"%s\">informazio gehiago</a>", diff --git a/lib/l10n/fa.php b/lib/l10n/fa.php index 31f936b8c98..a10e9b05673 100644 --- a/lib/l10n/fa.php +++ b/lib/l10n/fa.php @@ -12,7 +12,6 @@ "today" => "امروز", "yesterday" => "دیروز", "last month" => "ماه قبل", -"months ago" => "ماههای قبل", "last year" => "سال قبل", "years ago" => "سالهای قبل" ); diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php index dc78b03c449..5a703a04b22 100644 --- a/lib/l10n/fi_FI.php +++ b/lib/l10n/fi_FI.php @@ -22,7 +22,6 @@ "yesterday" => "eilen", "%d days ago" => "%d päivää sitten", "last month" => "viime kuussa", -"months ago" => "kuukautta sitten", "last year" => "viime vuonna", "years ago" => "vuotta sitten", "%s is available. Get <a href=\"%s\">more information</a>" => "%s on saatavilla. Lue <a href=\"%s\">lisätietoja</a>", diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php index ff2356464a2..ad5a034f5b6 100644 --- a/lib/l10n/fr.php +++ b/lib/l10n/fr.php @@ -22,7 +22,6 @@ "yesterday" => "hier", "%d days ago" => "il y a %d jours", "last month" => "le mois dernier", -"months ago" => "il y a plusieurs mois", "last year" => "l'année dernière", "years ago" => "il y a plusieurs années", "%s is available. Get <a href=\"%s\">more information</a>" => "%s est disponible. Obtenez <a href=\"%s\">plus d'informations</a>", diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index 96368ef03db..049ba0f3dbb 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -20,7 +20,6 @@ "yesterday" => "onte", "%d days ago" => "hai %d días", "last month" => "último mes", -"months ago" => "meses atrás", "last year" => "último ano", "years ago" => "anos atrás", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está dispoñible. Obteña <a href=\"%s\">máis información</a>", diff --git a/lib/l10n/he.php b/lib/l10n/he.php index 27bcf7655d5..2f14dbeb246 100644 --- a/lib/l10n/he.php +++ b/lib/l10n/he.php @@ -20,7 +20,6 @@ "yesterday" => "אתמול", "%d days ago" => "לפני %d ימים", "last month" => "חודש שעבר", -"months ago" => "חודשים", "last year" => "שנה שעברה", "years ago" => "שנים", "%s is available. Get <a href=\"%s\">more information</a>" => "%s זמין. קבלת <a href=\"%s\">מידע נוסף</a>", diff --git a/lib/l10n/hr.php b/lib/l10n/hr.php index 0d2a0f46248..62305c15711 100644 --- a/lib/l10n/hr.php +++ b/lib/l10n/hr.php @@ -10,7 +10,6 @@ "today" => "danas", "yesterday" => "jučer", "last month" => "prošli mjesec", -"months ago" => "mjeseci", "last year" => "prošlu godinu", "years ago" => "godina" ); diff --git a/lib/l10n/hu_HU.php b/lib/l10n/hu_HU.php index 3abf96e85a8..63704a978c5 100644 --- a/lib/l10n/hu_HU.php +++ b/lib/l10n/hu_HU.php @@ -21,7 +21,6 @@ "yesterday" => "tegnap", "%d days ago" => "%d évvel ezelőtt", "last month" => "múlt hónapban", -"months ago" => "hónappal ezelőtt", "last year" => "tavaly", "years ago" => "évvel ezelőtt" ); diff --git a/lib/l10n/id.php b/lib/l10n/id.php index 40c4532bdd0..e31b4caf4f5 100644 --- a/lib/l10n/id.php +++ b/lib/l10n/id.php @@ -20,7 +20,6 @@ "yesterday" => "kemarin", "%d days ago" => "%d hari lalu", "last month" => "bulan kemarin", -"months ago" => "beberapa bulan lalu", "last year" => "tahun kemarin", "years ago" => "beberapa tahun lalu", "%s is available. Get <a href=\"%s\">more information</a>" => "%s tersedia. dapatkan <a href=\"%s\"> info lebih lanjut</a>", diff --git a/lib/l10n/it.php b/lib/l10n/it.php index 98ba5973a4a..89e2b05a22f 100644 --- a/lib/l10n/it.php +++ b/lib/l10n/it.php @@ -22,7 +22,6 @@ "yesterday" => "ieri", "%d days ago" => "%d giorni fa", "last month" => "il mese scorso", -"months ago" => "mesi fa", "last year" => "l'anno scorso", "years ago" => "anni fa", "%s is available. Get <a href=\"%s\">more information</a>" => "%s è disponibile. Ottieni <a href=\"%s\">ulteriori informazioni</a>", diff --git a/lib/l10n/ja_JP.php b/lib/l10n/ja_JP.php index eb3316b4ab1..cd619e65004 100644 --- a/lib/l10n/ja_JP.php +++ b/lib/l10n/ja_JP.php @@ -22,7 +22,6 @@ "yesterday" => "昨日", "%d days ago" => "%d 日前", "last month" => "先月", -"months ago" => "月前", "last year" => "昨年", "years ago" => "年前", "%s is available. Get <a href=\"%s\">more information</a>" => "%s が利用可能です。<a href=\"%s\">詳細情報</a> を確認ください", diff --git a/lib/l10n/ka_GE.php b/lib/l10n/ka_GE.php index 69b72e04130..79d7c1c0617 100644 --- a/lib/l10n/ka_GE.php +++ b/lib/l10n/ka_GE.php @@ -12,7 +12,6 @@ "today" => "დღეს", "yesterday" => "გუშინ", "last month" => "გასულ თვეში", -"months ago" => "თვის წინ", "last year" => "ბოლო წელს", "years ago" => "წლის წინ", "up to date" => "განახლებულია", diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php index b34c602af2a..b84c155633b 100644 --- a/lib/l10n/lt_LT.php +++ b/lib/l10n/lt_LT.php @@ -21,7 +21,6 @@ "yesterday" => "vakar", "%d days ago" => "prieš %d dienų", "last month" => "praėjusį mėnesį", -"months ago" => "prieš mėnesį", "last year" => "pereitais metais", "years ago" => "prieš metus", "%s is available. Get <a href=\"%s\">more information</a>" => "%s yra galimas. Platesnė <a href=\"%s\">informacija čia</a>", diff --git a/lib/l10n/nb_NO.php b/lib/l10n/nb_NO.php index ece05b389ca..b01e0979889 100644 --- a/lib/l10n/nb_NO.php +++ b/lib/l10n/nb_NO.php @@ -22,7 +22,6 @@ "yesterday" => "i går", "%d days ago" => "%d dager siden", "last month" => "forrige måned", -"months ago" => "måneder siden", "last year" => "i fjor", "years ago" => "år siden", "%s is available. Get <a href=\"%s\">more information</a>" => "%s er tilgjengelig. Få <a href=\"%s\">mer informasjon</a>", diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php index e209592d96d..f8259f5f344 100644 --- a/lib/l10n/nl.php +++ b/lib/l10n/nl.php @@ -22,7 +22,6 @@ "yesterday" => "gisteren", "%d days ago" => "%d dagen geleden", "last month" => "vorige maand", -"months ago" => "maanden geleden", "last year" => "vorig jaar", "years ago" => "jaar geleden", "%s is available. Get <a href=\"%s\">more information</a>" => "%s is beschikbaar. Verkrijg <a href=\"%s\">meer informatie</a>", diff --git a/lib/l10n/oc.php b/lib/l10n/oc.php index 2ac89fc74c1..89161393380 100644 --- a/lib/l10n/oc.php +++ b/lib/l10n/oc.php @@ -17,7 +17,6 @@ "yesterday" => "ièr", "%d days ago" => "%d jorns a", "last month" => "mes passat", -"months ago" => "meses a", "last year" => "an passat", "years ago" => "ans a", "up to date" => "a jorn", diff --git a/lib/l10n/pl.php b/lib/l10n/pl.php index 0fb29cbedbf..f6397936d6c 100644 --- a/lib/l10n/pl.php +++ b/lib/l10n/pl.php @@ -22,7 +22,6 @@ "yesterday" => "wczoraj", "%d days ago" => "%d dni temu", "last month" => "ostatni miesiąc", -"months ago" => "miesięcy temu", "last year" => "ostatni rok", "years ago" => "lat temu", "%s is available. Get <a href=\"%s\">more information</a>" => "%s jest dostępna. Uzyskaj <a href=\"%s\">więcej informacji</a>", diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php index 161a5bc0a68..b46de858e24 100644 --- a/lib/l10n/pt_BR.php +++ b/lib/l10n/pt_BR.php @@ -22,7 +22,6 @@ "yesterday" => "ontem", "%d days ago" => "%d dias atrás", "last month" => "último mês", -"months ago" => "meses atrás", "last year" => "último ano", "years ago" => "anos atrás", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está disponível. Obtenha <a href=\"%s\">mais informações</a>", diff --git a/lib/l10n/pt_PT.php b/lib/l10n/pt_PT.php index 3809e4bdbcc..a54cb57578a 100644 --- a/lib/l10n/pt_PT.php +++ b/lib/l10n/pt_PT.php @@ -22,7 +22,6 @@ "yesterday" => "ontem", "%d days ago" => "há %d dias", "last month" => "mês passado", -"months ago" => "há meses", "last year" => "ano passado", "years ago" => "há anos", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está disponível. Obtenha <a href=\"%s\">mais informação</a>", diff --git a/lib/l10n/ro.php b/lib/l10n/ro.php index 818b3f3eeed..27912550e17 100644 --- a/lib/l10n/ro.php +++ b/lib/l10n/ro.php @@ -21,7 +21,6 @@ "yesterday" => "ieri", "%d days ago" => "%d zile în urmă", "last month" => "ultima lună", -"months ago" => "luni în urmă", "last year" => "ultimul an", "years ago" => "ani în urmă", "%s is available. Get <a href=\"%s\">more information</a>" => "%s este disponibil. Vezi <a href=\"%s\">mai multe informații</a>", diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php index 1a7319eb168..039158545d2 100644 --- a/lib/l10n/ru.php +++ b/lib/l10n/ru.php @@ -22,7 +22,6 @@ "yesterday" => "вчера", "%d days ago" => "%d дней назад", "last month" => "в прошлом месяце", -"months ago" => "месяцы назад", "last year" => "в прошлом году", "years ago" => "годы назад", "%s is available. Get <a href=\"%s\">more information</a>" => "Возможно обновление до %s. <a href=\"%s\">Подробнее</a>", diff --git a/lib/l10n/ru_RU.php b/lib/l10n/ru_RU.php index 85bb278be5f..269b2569312 100644 --- a/lib/l10n/ru_RU.php +++ b/lib/l10n/ru_RU.php @@ -22,7 +22,6 @@ "yesterday" => "вчера", "%d days ago" => "%d дней назад", "last month" => "в прошлом месяце", -"months ago" => "месяц назад", "last year" => "в прошлом году", "years ago" => "год назад", "%s is available. Get <a href=\"%s\">more information</a>" => "%s доступно. Получите <a href=\"%s\">more information</a>", diff --git a/lib/l10n/si_LK.php b/lib/l10n/si_LK.php index 040c6d2d171..25624acf705 100644 --- a/lib/l10n/si_LK.php +++ b/lib/l10n/si_LK.php @@ -22,7 +22,6 @@ "yesterday" => "ඊයේ", "%d days ago" => "%d දිනකට පෙර", "last month" => "පෙර මාසයේ", -"months ago" => "මාස කීපයකට පෙර", "last year" => "පෙර අවුරුද්දේ", "years ago" => "අවුරුදු කීපයකට පෙර", "%s is available. Get <a href=\"%s\">more information</a>" => "%s යොදාගත හැක. <a href=\"%s\">තව විස්තර</a> ලබාගන්න", diff --git a/lib/l10n/sk_SK.php b/lib/l10n/sk_SK.php index 9d5e4b9013b..588933a4375 100644 --- a/lib/l10n/sk_SK.php +++ b/lib/l10n/sk_SK.php @@ -22,7 +22,6 @@ "yesterday" => "včera", "%d days ago" => "pred %d dňami", "last month" => "minulý mesiac", -"months ago" => "pred mesiacmi", "last year" => "minulý rok", "years ago" => "pred rokmi", "%s is available. Get <a href=\"%s\">more information</a>" => "%s je dostupné. Získať <a href=\"%s\">viac informácií</a>", diff --git a/lib/l10n/sl.php b/lib/l10n/sl.php index 3dc8753a436..5787d2b7f30 100644 --- a/lib/l10n/sl.php +++ b/lib/l10n/sl.php @@ -21,7 +21,6 @@ "yesterday" => "včeraj", "%d days ago" => "pred %d dnevi", "last month" => "prejšnji mesec", -"months ago" => "pred nekaj meseci", "last year" => "lani", "years ago" => "pred nekaj leti", "%s is available. Get <a href=\"%s\">more information</a>" => "%s je na voljo. <a href=\"%s\">Več podrobnosti.</a>", diff --git a/lib/l10n/sr.php b/lib/l10n/sr.php index cec7ea703fb..8c15082e379 100644 --- a/lib/l10n/sr.php +++ b/lib/l10n/sr.php @@ -3,6 +3,28 @@ "Personal" => "Лично", "Settings" => "Подешавања", "Users" => "Корисници", +"Apps" => "Апликације", +"Admin" => "Администрација", +"ZIP download is turned off." => "Преузимање ЗИПа је искључено.", +"Files need to be downloaded one by one." => "Преузимање морате радити једану по једану.", +"Back to Files" => "Назад на датотеке", +"Selected files too large to generate zip file." => "Изабране датотеке су превелике да бисте правили зип датотеку.", +"Application is not enabled" => "Апликација није укључена", "Authentication error" => "Грешка при аутентификацији", -"Text" => "Текст" +"Token expired. Please reload page." => "Токен је истекао. Поново учитајте страну.", +"Files" => "Датотеке", +"Text" => "Текст", +"Images" => "Слике", +"seconds ago" => "пре неколико секунди", +"1 minute ago" => "пре 1 минута", +"%d minutes ago" => "%d минута раније", +"today" => "данас", +"yesterday" => "јуче", +"%d days ago" => "%d дана раније", +"last month" => "прошлог месеца", +"last year" => "прошле године", +"years ago" => "година раније", +"%s is available. Get <a href=\"%s\">more information</a>" => "%s је доступна. Погледајте <a href=\"%s\">више информација</a>", +"up to date" => "је ажурна", +"updates check is disabled" => "провера ажурирања је искључена" ); diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php index cc1e09ea76a..4ce0b7068af 100644 --- a/lib/l10n/sv.php +++ b/lib/l10n/sv.php @@ -22,7 +22,6 @@ "yesterday" => "igår", "%d days ago" => "%d dagar sedan", "last month" => "förra månaden", -"months ago" => "månader sedan", "last year" => "förra året", "years ago" => "år sedan", "%s is available. Get <a href=\"%s\">more information</a>" => "%s finns. Få <a href=\"%s\">mer information</a>", diff --git a/lib/l10n/ta_LK.php b/lib/l10n/ta_LK.php index 3c82233cb69..51572e11ba7 100644 --- a/lib/l10n/ta_LK.php +++ b/lib/l10n/ta_LK.php @@ -22,7 +22,6 @@ "yesterday" => "நேற்று", "%d days ago" => "%d நாட்களுக்கு முன்", "last month" => "கடந்த மாதம்", -"months ago" => "மாதங்களுக்கு முன்", "last year" => "கடந்த வருடம்", "years ago" => "வருடங்களுக்கு முன்", "%s is available. Get <a href=\"%s\">more information</a>" => "%s இன்னும் இருக்கின்றன. <a href=\"%s\">மேலதிக தகவல்களுக்கு</a> எடுக்க", diff --git a/lib/l10n/th_TH.php b/lib/l10n/th_TH.php index 49034cd4990..acb56a4cb09 100644 --- a/lib/l10n/th_TH.php +++ b/lib/l10n/th_TH.php @@ -22,7 +22,6 @@ "yesterday" => "เมื่อวานนี้", "%d days ago" => "%d วันที่ผ่านมา", "last month" => "เดือนที่แล้ว", -"months ago" => "เดือนมาแล้ว", "last year" => "ปีที่แล้ว", "years ago" => "ปีที่ผ่านมา", "%s is available. Get <a href=\"%s\">more information</a>" => "%s พร้อมให้ใช้งานได้แล้ว. <a href=\"%s\">ดูรายละเอียดเพิ่มเติม</a>", diff --git a/lib/l10n/uk.php b/lib/l10n/uk.php index b08f559595b..f606c4aca48 100644 --- a/lib/l10n/uk.php +++ b/lib/l10n/uk.php @@ -20,7 +20,6 @@ "yesterday" => "вчора", "%d days ago" => "%d днів тому", "last month" => "минулого місяця", -"months ago" => "місяці тому", "last year" => "минулого року", "years ago" => "роки тому", "updates check is disabled" => "перевірка оновлень відключена" diff --git a/lib/l10n/vi.php b/lib/l10n/vi.php index cfc39e5b7a8..4efb4760580 100644 --- a/lib/l10n/vi.php +++ b/lib/l10n/vi.php @@ -22,7 +22,6 @@ "yesterday" => "hôm qua", "%d days ago" => "%d ngày trước", "last month" => "tháng trước", -"months ago" => "tháng trước", "last year" => "năm trước", "years ago" => "năm trước", "%s is available. Get <a href=\"%s\">more information</a>" => "%s có sẵn. <a href=\"%s\">xem thêm ở đây</a>", diff --git a/lib/l10n/zh_CN.GB2312.php b/lib/l10n/zh_CN.GB2312.php index adc5c3bc6a9..08975e44598 100644 --- a/lib/l10n/zh_CN.GB2312.php +++ b/lib/l10n/zh_CN.GB2312.php @@ -14,6 +14,7 @@ "Token expired. Please reload page." => "会话过期。请刷新页面。", "Files" => "文件", "Text" => "文本", +"Images" => "图片", "seconds ago" => "秒前", "1 minute ago" => "1 分钟前", "%d minutes ago" => "%d 分钟前", @@ -21,7 +22,6 @@ "yesterday" => "昨天", "%d days ago" => "%d 天前", "last month" => "上个月", -"months ago" => "月前", "last year" => "去年", "years ago" => "年前", "%s is available. Get <a href=\"%s\">more information</a>" => "%s 不可用。获知 <a href=\"%s\">详情</a>", diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php index 6cdfd472510..270f69594e9 100644 --- a/lib/l10n/zh_CN.php +++ b/lib/l10n/zh_CN.php @@ -22,7 +22,6 @@ "yesterday" => "昨天", "%d days ago" => "%d 天前", "last month" => "上月", -"months ago" => "几月前", "last year" => "上年", "years ago" => "几年前", "%s is available. Get <a href=\"%s\">more information</a>" => "%s 已存在. 点此 <a href=\"%s\">获取更多信息</a>", diff --git a/lib/l10n/zh_TW.php b/lib/l10n/zh_TW.php index 3122695033a..16229fe03d8 100644 --- a/lib/l10n/zh_TW.php +++ b/lib/l10n/zh_TW.php @@ -21,7 +21,6 @@ "yesterday" => "昨天", "%d days ago" => "%d 天前", "last month" => "上個月", -"months ago" => "幾個月前", "last year" => "去年", "years ago" => "幾年前", "%s is available. Get <a href=\"%s\">more information</a>" => "%s 已經可用. 取得 <a href=\"%s\">更多資訊</a>", diff --git a/lib/migrate.php b/lib/migrate.php index ca74edcdc57..2cc0a3067b8 100644 --- a/lib/migrate.php +++ b/lib/migrate.php @@ -238,13 +238,13 @@ class OC_Migrate{ $userfolder = $extractpath . $json->exporteduser; $newuserfolder = $datadir . '/' . self::$uid; foreach(scandir($userfolder) as $file){ - if($file !== '.' && $file !== '..' && is_dir($file)){ + if($file !== '.' && $file !== '..' && is_dir($file)) { // Then copy the folder over OC_Helper::copyr($userfolder.'/'.$file, $newuserfolder.'/'.$file); } } // Import user app data - if(file_exists($extractpath . $json->exporteduser . '/migration.db')){ + if(file_exists($extractpath . $json->exporteduser . '/migration.db')) { if( !$appsimported = self::importAppData( $extractpath . $json->exporteduser . '/migration.db', $json, self::$uid ) ) { return json_encode( array( 'success' => false ) ); } diff --git a/lib/public/constants.php b/lib/public/constants.php new file mode 100644 index 00000000000..bc979c9031f --- /dev/null +++ b/lib/public/constants.php @@ -0,0 +1,38 @@ +<?php +/** + * ownCloud + * + * @author Thomas Tanghus + * @copyright 2012 Thomas Tanghus (thomas@tanghus.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/>. + * + */ + +/** + * This file defines common constants used in ownCloud + */ + +namespace OCP; + +/** + * CRUDS permissions. + */ +const PERMISSION_CREATE = 4; +const PERMISSION_READ = 1; +const PERMISSION_UPDATE = 2; +const PERMISSION_DELETE = 8; +const PERMISSION_SHARE = 16; +const PERMISSION_ALL = 31; + diff --git a/lib/public/db.php b/lib/public/db.php index d2484b6eb83..92ff8f93a22 100644 --- a/lib/public/db.php +++ b/lib/public/db.php @@ -46,6 +46,27 @@ class DB { } /** + * @brief Insert a row if a matching row doesn't exists. + * @param $table string The table name (will replace *PREFIX*) to perform the replace on. + * @param $input array + * + * The input array if in the form: + * + * array ( 'id' => array ( 'value' => 6, + * 'key' => true + * ), + * 'name' => array ('value' => 'Stoyan'), + * 'family' => array ('value' => 'Stefanov'), + * 'birth_date' => array ('value' => '1975-06-20') + * ); + * @returns true/false + * + */ + public static function insertIfNotExist($table, $input) { + return(\OC_DB::insertIfNotExist($table, $input)); + } + + /** * @brief gets last value of autoincrement * @param $table string The optional table name (will replace *PREFIX*) and add sequence suffix * @returns id diff --git a/lib/public/share.php b/lib/public/share.php index dd1aac609a5..83c0bcd5e53 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -46,12 +46,8 @@ class Share { * Check if permission is granted with And (&) e.g. Check if delete is granted: if ($permissions & PERMISSION_DELETE) * Remove permissions with And (&) and Not (~) e.g. Remove the update permission: $permissions &= ~PERMISSION_UPDATE * Apps are required to handle permissions on their own, this class only stores and manages the permissions of shares + * @see lib/public/constants.php */ - const PERMISSION_CREATE = 4; - const PERMISSION_READ = 1; - const PERMISSION_UPDATE = 2; - const PERMISSION_DELETE = 8; - const PERMISSION_SHARE = 16; const FORMAT_NONE = -1; const FORMAT_STATUSES = -2; @@ -402,7 +398,7 @@ class Share { // Check if permissions were removed if ($item['permissions'] & ~$permissions) { // If share permission is removed all reshares must be deleted - if (($item['permissions'] & self::PERMISSION_SHARE) && (~$permissions & self::PERMISSION_SHARE)) { + if (($item['permissions'] & PERMISSION_SHARE) && (~$permissions & PERMISSION_SHARE)) { self::delete($item['id'], true); } else { $ids = array(); @@ -552,7 +548,7 @@ class Share { $itemTypes = $collectionTypes; } $placeholders = join(',', array_fill(0, count($itemTypes), '?')); - $where .= ' WHERE item_type IN ('.$placeholders.'))'; + $where .= ' WHERE `item_type` IN ('.$placeholders.'))'; $queryArgs = $itemTypes; } else { $where = ' WHERE `item_type` = ?'; @@ -629,7 +625,7 @@ class Share { $queryArgs[] = $item; if ($includeCollections && $collectionTypes) { $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); - $where .= ' OR item_type IN ('.$placeholders.'))'; + $where .= ' OR `item_type` IN ('.$placeholders.'))'; $queryArgs = array_merge($queryArgs, $collectionTypes); } } @@ -677,6 +673,9 @@ class Share { $root = strlen($root); $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit); $result = $query->execute($queryArgs); + if (\OC_DB::isError($result)) { + \OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR); + } $items = array(); $targets = array(); while ($row = $result->fetchRow()) { @@ -701,7 +700,7 @@ class Share { $items[$id]['share_with'] = $row['share_with']; } // Switch ids if sharing permission is granted on only one share to ensure correct parent is used if resharing - if (~(int)$items[$id]['permissions'] & self::PERMISSION_SHARE && (int)$row['permissions'] & self::PERMISSION_SHARE) { + if (~(int)$items[$id]['permissions'] & PERMISSION_SHARE && (int)$row['permissions'] & PERMISSION_SHARE) { $items[$row['id']] = $items[$id]; unset($items[$id]); $id = $row['id']; @@ -848,7 +847,7 @@ class Share { throw new \Exception($message); } // Check if share permissions is granted - if ((int)$checkReshare['permissions'] & self::PERMISSION_SHARE) { + if ((int)$checkReshare['permissions'] & PERMISSION_SHARE) { if (~(int)$checkReshare['permissions'] & $permissions) { $message = 'Sharing '.$itemSource.' failed, because the permissions exceed permissions granted to '.$uidOwner; \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); @@ -1136,7 +1135,7 @@ class Share { $duplicateParent = $query->execute(array($item['item_type'], $item['item_target'], self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique, $item['uid_owner'], $item['parent']))->fetchRow(); if ($duplicateParent) { // Change the parent to the other item id if share permission is granted - if ($duplicateParent['permissions'] & self::PERMISSION_SHARE) { + if ($duplicateParent['permissions'] & PERMISSION_SHARE) { $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` = ?'); $query->execute(array($duplicateParent['id'], $item['id'])); continue; diff --git a/lib/setup.php b/lib/setup.php index 726b3352d50..264cd55795e 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -1,45 +1,5 @@ <?php -$hasSQLite = (is_callable('sqlite_open') or class_exists('SQLite3')); -$hasMySQL = is_callable('mysql_connect'); -$hasPostgreSQL = is_callable('pg_connect'); -$hasOracle = is_callable('oci_connect'); -$datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data'); - -// Test if .htaccess is working -$content = "deny from all"; -file_put_contents(OC::$SERVERROOT.'/data/.htaccess', $content); - -$opts = array( - 'hasSQLite' => $hasSQLite, - 'hasMySQL' => $hasMySQL, - 'hasPostgreSQL' => $hasPostgreSQL, - 'hasOracle' => $hasOracle, - 'directory' => $datadir, - 'secureRNG' => OC_Util::secureRNG_available(), - 'htaccessWorking' => OC_Util::ishtaccessworking(), - 'errors' => array(), -); - -if(isset($_POST['install']) AND $_POST['install']=='true') { - // We have to launch the installation process : - $e = OC_Setup::install($_POST); - $errors = array('errors' => $e); - - if(count($e) > 0) { - //OC_Template::printGuestPage("", "error", array("errors" => $errors)); - $options = array_merge($_POST, $opts, $errors); - OC_Template::printGuestPage("", "installation", $options); - } - else { - header("Location: ".OC::$WEBROOT.'/'); - exit(); - } -} -else { - OC_Template::printGuestPage("", "installation", $opts); -} - class OC_Setup { public static function install($options) { $error = array(); @@ -573,7 +533,15 @@ class OC_Setup { * create .htaccess files for apache hosts */ private static function createHtaccess() { - $content = "ErrorDocument 403 ".OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page + $content = "<IfModule mod_fcgid.c>\n"; + $content.= "<IfModule mod_setenvif.c>\n"; + $content.= "<IfModule mod_headers.c>\n"; + $content.= "SetEnvIfNoCase ^Authorization$ \"(.+)\" XAUTHORIZATION=$1\n"; + $content.= "RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION\n"; + $content.= "</IfModule>\n"; + $content.= "</IfModule>\n"; + $content.= "</IfModule>\n"; + $content.= "ErrorDocument 403 ".OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page $content.= "ErrorDocument 404 ".OC::$WEBROOT."/core/templates/404.php\n";//custom 404 error page $content.= "<IfModule mod_php5.c>\n"; $content.= "php_value upload_max_filesize 512M\n";//upload limit @@ -599,6 +567,10 @@ class OC_Setup { $content.= "Options -Indexes\n"; @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it + self::protectDataDirectory(); + } + + public static function protectDataDirectory() { $content = "deny from all\n"; $content.= "IndexIgnore *"; file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.htaccess', $content); diff --git a/lib/template.php b/lib/template.php index 3d3589abd1e..a10cabf5931 100644 --- a/lib/template.php +++ b/lib/template.php @@ -103,13 +103,13 @@ function relative_modified_date($timestamp) { if($timediff < 60) { return $l->t('seconds ago'); } else if($timediff < 120) { return $l->t('1 minute ago'); } else if($timediff < 3600) { return $l->t('%d minutes ago', $diffminutes); } - //else if($timediff < 7200) { return '1 hour ago'; } - //else if($timediff < 86400) { return $diffhours.' hours ago'; } + else if($timediff < 7200) { return $l->t('1 hour ago'); } + else if($timediff < 86400) { return $l->t('%d hours ago', $diffhours); } else if((date('G')-$diffhours) > 0) { return $l->t('today'); } else if((date('G')-$diffhours) > -24) { return $l->t('yesterday'); } else if($timediff < 2678400) { return $l->t('%d days ago', $diffdays); } else if($timediff < 5184000) { return $l->t('last month'); } - else if((date('n')-$diffmonths) > 0) { return $l->t('months ago'); } + else if((date('n')-$diffmonths) > 0) { return $l->t('%d months ago', $diffmonths); } else if($timediff < 63113852) { return $l->t('last year'); } else { return $l->t('years ago'); } } diff --git a/lib/util.php b/lib/util.php index 8e6eb6ca032..9b29bfe9d5c 100755 --- a/lib/util.php +++ b/lib/util.php @@ -91,7 +91,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,01); + return array(4,91,02); } /** @@ -182,7 +182,7 @@ class OC_Util { * @param string $url * @return OC_Template */ - public static function getPageNavi($pagecount,$page,$url) { + public static function getPageNavi($pagecount, $page, $url) { $pagelinkcount=8; if ($pagecount>1) { @@ -213,7 +213,7 @@ class OC_Util { $web_server_restart= false; //check for database drivers if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect')) { - $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>','hint'=>'');//TODO: sane hint + $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>', 'hint'=>'');//TODO: sane hint $web_server_restart= true; } @@ -222,13 +222,13 @@ class OC_Util { // Check if config folder is writable. if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) { - $errors[]=array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by giving the webserver user write access to the config directory in owncloud"); + $errors[]=array('error'=>"Can't write into config directory 'config'", 'hint'=>"You can usually fix this by giving the webserver user write access to the config directory in owncloud"); } // Check if there is a writable install folder. if(OC_Config::getValue('appstoreenabled', true)) { if( OC_App::getInstallPath() === null || !is_writable(OC_App::getInstallPath()) || !is_readable(OC_App::getInstallPath()) ) { - $errors[]=array('error'=>"Can't write into apps directory",'hint'=>"You can usually fix this by giving the webserver user write access to the apps directory + $errors[]=array('error'=>"Can't write into apps directory", 'hint'=>"You can usually fix this by giving the webserver user write access to the apps directory in owncloud or disabling the appstore in the config file."); } } @@ -265,57 +265,57 @@ class OC_Util { if(!is_dir($CONFIG_DATADIRECTORY)) { $success=@mkdir($CONFIG_DATADIRECTORY); if(!$success) { - $errors[]=array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY.")",'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '".OC::$SERVERROOT."' (in a terminal, use the command 'chown -R www-data:www-data /path/to/your/owncloud/install/data' "); + $errors[]=array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY.")", 'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '".OC::$SERVERROOT."' (in a terminal, use the command 'chown -R www-data:www-data /path/to/your/owncloud/install/data' "); } } else if(!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) { - $errors[]=array('error'=>'Data directory ('.$CONFIG_DATADIRECTORY.') not writable by ownCloud<br/>','hint'=>$permissionsHint); + $errors[]=array('error'=>'Data directory ('.$CONFIG_DATADIRECTORY.') not writable by ownCloud<br/>', 'hint'=>$permissionsHint); } // check if all required php modules are present if(!class_exists('ZipArchive')) { - $errors[]=array('error'=>'PHP module zip not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module zip not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('mb_detect_encoding')) { - $errors[]=array('error'=>'PHP module mb multibyte not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module mb multibyte not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('ctype_digit')) { - $errors[]=array('error'=>'PHP module ctype is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module ctype is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('json_encode')) { - $errors[]=array('error'=>'PHP module JSON is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module JSON is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('imagepng')) { - $errors[]=array('error'=>'PHP module GD is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module GD is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('gzencode')) { - $errors[]=array('error'=>'PHP module zlib is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module zlib is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('iconv')) { - $errors[]=array('error'=>'PHP module iconv is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module iconv is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('simplexml_load_string')) { - $errors[]=array('error'=>'PHP module SimpleXML is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP module SimpleXML is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(floatval(phpversion())<5.3) { - $errors[]=array('error'=>'PHP 5.3 is required.<br/>','hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher. PHP 5.2 is no longer supported by ownCloud and the PHP community.'); + $errors[]=array('error'=>'PHP 5.3 is required.<br/>', 'hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher. PHP 5.2 is no longer supported by ownCloud and the PHP community.'); $web_server_restart= false; } if(!defined('PDO::ATTR_DRIVER_NAME')) { - $errors[]=array('error'=>'PHP PDO module is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); + $errors[]=array('error'=>'PHP PDO module is not installed.<br/>', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if($web_server_restart) { - $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?<br/>','hint'=>'Please ask your server administrator to restart the web server.'); + $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?<br/>', 'hint'=>'Please ask your server administrator to restart the web server.'); } return $errors; @@ -430,7 +430,7 @@ class OC_Util { } return true; } - + /** * Redirect to the user default page */ @@ -463,7 +463,7 @@ class OC_Util { $id=OC_Config::getValue('instanceid', null); if(is_null($id)) { $id=uniqid(); - OC_Config::setValue('instanceid',$id); + OC_Config::setValue('instanceid', $id); } return $id; } @@ -493,18 +493,15 @@ class OC_Util { */ public static function callRegister() { // Check if a token exists - if(!isset($_SESSION['requesttoken']) || time() >$_SESSION['requesttoken']['time']) { + if(!isset($_SESSION['requesttoken'])) { // No valid token found, generate a new one. - $requestTokenArray = array( - "requesttoken" => self::generate_random_bytes(20), - "time" => time()+self::$callLifespan, - ); - $_SESSION['requesttoken']=$requestTokenArray; + $requestToken = self::generate_random_bytes(20); + $_SESSION['requesttoken']=$requestToken; } else { // Valid token already exists, send it - $requestTokenArray = $_SESSION['requesttoken']; + $requestToken = $_SESSION['requesttoken']; } - return($requestTokenArray['requesttoken']); + return($requestToken); } /** @@ -526,7 +523,7 @@ class OC_Util { } // Check if the token is valid - if(!isset($_SESSION['requesttoken']) || time() > $_SESSION['requesttoken']["time"]) { + if($token !== $_SESSION['requesttoken']) { // Not valid return false; } else { @@ -597,6 +594,33 @@ class OC_Util { } } + + /** + * Check if the ownCloud server can connect to the internet + */ + public static function isinternetconnectionworking() { + + // try to connect to owncloud.org to see if http connections to the internet are possible. + $connected = @fsockopen("www.owncloud.org", 80); + if ($connected) { + fclose($connected); + return true; + }else{ + + // second try in case one server is down + $connected = @fsockopen("apps.owncloud.com", 80); + if ($connected) { + fclose($connected); + return true; + }else{ + return false; + } + + } + + } + + /** * @brief Generates a cryptographical secure pseudorandom string * @param Int with the length of the random string diff --git a/lib/vcategories.php b/lib/vcategories.php index 46256def9c4..406a4eb1074 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -21,6 +21,7 @@ * */ +OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_VCategories', 'post_deleteUser'); /** * Class for easy access to categories in VCARD, VEVENT, VTODO and VJOURNAL. @@ -28,50 +29,261 @@ * anything else that is either parsed from a vobject or that the user chooses * to add. * Category names are not case-sensitive, but will be saved with the case they - * are entered in. If a user already has a category 'family' for an app, and + * are entered in. If a user already has a category 'family' for a type, and * tries to add a category named 'Family' it will be silently ignored. - * NOTE: There is a limitation in that the the configvalue field in the - * preferences table is a varchar(255). */ class OC_VCategories { - const PREF_CATEGORIES_LABEL = 'extra_categories'; + /** * Categories */ private $categories = array(); - private $app = null; + /** + * Used for storing objectid/categoryname pairs while rescanning. + */ + private static $relations = array(); + + private $type = null; private $user = null; + const CATEGORY_TABLE = '*PREFIX*vcategory'; + const RELATION_TABLE = '*PREFIX*vcategory_to_object'; + + const CATEGORY_FAVORITE = '_$!<Favorite>!$_'; + + const FORMAT_LIST = 0; + const FORMAT_MAP = 1; + /** * @brief Constructor. - * @param $app The application identifier e.g. 'contacts' or 'calendar'. + * @param $type The type identifier e.g. 'contact' or 'event'. * @param $user The user whos data the object will operate on. This * parameter should normally be omitted but to make an app able to * update categories for all users it is made possible to provide it. * @param $defcategories An array of default categories to be used if none is stored. */ - public function __construct($app, $user=null, $defcategories=array()) { - $this->app = $app; + public function __construct($type, $user=null, $defcategories=array()) { + $this->type = $type; $this->user = is_null($user) ? OC_User::getUser() : $user; - $categories = trim(OC_Preferences::getValue($this->user, $app, self::PREF_CATEGORIES_LABEL, '')); - if ($categories) { - $categories = @unserialize($categories); + + $this->loadCategories(); + OCP\Util::writeLog('core', __METHOD__ . ', categories: ' + . print_r($this->categories, true), + OCP\Util::DEBUG + ); + + if($defcategories && count($this->categories) === 0) { + $this->addMulti($defcategories, true); + } + } + + /** + * @brief Load categories from db. + */ + private function loadCategories() { + $this->categories = array(); + $result = null; + $sql = 'SELECT `id`, `category` FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`'; + try { + $stmt = OCP\DB::prepare($sql); + $result = $stmt->execute(array($this->user, $this->type)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } + + if(!is_null($result)) { + while( $row = $result->fetchRow()) { + // The keys are prefixed because array_search wouldn't work otherwise :-/ + $this->categories[$row['id']] = $row['category']; + } + } + OCP\Util::writeLog('core', __METHOD__.', categories: ' . print_r($this->categories, true), + OCP\Util::DEBUG); + } + + + /** + * @brief Check if any categories are saved for this type and user. + * @returns boolean. + * @param $type The type identifier e.g. 'contact' or 'event'. + * @param $user The user whos categories will be checked. If not set current user will be used. + */ + public static function isEmpty($type, $user = null) { + $user = is_null($user) ? OC_User::getUser() : $user; + $sql = 'SELECT COUNT(*) FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ?'; + try { + $stmt = OCP\DB::prepare($sql); + $result = $stmt->execute(array($user, $type)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + return ($result->numRows() == 0); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; } - $this->categories = is_array($categories) ? $categories : $defcategories; } /** * @brief Get the categories for a specific user. + * @param * @returns array containing the categories as strings. */ - public function categories() { - //OC_Log::write('core', 'OC_VCategories::categories: '.print_r($this->categories, true), OC_Log::DEBUG); + public function categories($format = null) { if(!$this->categories) { return array(); } - usort($this->categories, 'strnatcasecmp'); // usort to also renumber the keys - return $this->categories; + $categories = array_values($this->categories); + uasort($categories, 'strnatcasecmp'); + if($format == self::FORMAT_MAP) { + $catmap = array(); + foreach($categories as $category) { + if($category !== self::CATEGORY_FAVORITE) { + $catmap[] = array( + 'id' => $this->array_searchi($category, $this->categories), + 'name' => $category + ); + } + } + return $catmap; + } + + // Don't add favorites to normal categories. + $favpos = array_search(self::CATEGORY_FAVORITE, $categories); + if($favpos !== false) { + return array_splice($categories, $favpos); + } else { + return $categories; + } + } + + /** + * Get the a list if items belonging to $category. + * + * Throws an exception if the category could not be found. + * + * @param string|integer $category Category id or name. + * @returns array An array of object ids or false on error. + */ + public function idsForCategory($category) { + $result = null; + if(is_numeric($category)) { + $catid = $category; + } elseif(is_string($category)) { + $catid = $this->array_searchi($category, $this->categories); + } + OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG); + if($catid === false) { + $l10n = OC_L10N::get('core'); + throw new Exception( + $l10n->t('Could not find category "%s"', $category) + ); + } + + $ids = array(); + $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE + . '` WHERE `categoryid` = ?'; + + try { + $stmt = OCP\DB::prepare($sql); + $result = $stmt->execute(array($catid)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + + if(!is_null($result)) { + while( $row = $result->fetchRow()) { + $ids[] = (int)$row['objid']; + } + } + + return $ids; + } + + /** + * Get the a list if items belonging to $category. + * + * Throws an exception if the category could not be found. + * + * @param string|integer $category Category id or name. + * @param array $tableinfo Array in the form {'tablename' => table, 'fields' => ['field1', 'field2']} + * @param int $limit + * @param int $offset + * + * This generic method queries a table assuming that the id + * field is called 'id' and the table name provided is in + * the form '*PREFIX*table_name'. + * + * If the category name cannot be resolved an exception is thrown. + * + * TODO: Maybe add the getting permissions for objects? + * + * @returns array containing the resulting items or false on error. + */ + public function itemsForCategory($category, $tableinfo, $limit = null, $offset = null) { + $result = null; + if(is_numeric($category)) { + $catid = $category; + } elseif(is_string($category)) { + $catid = $this->array_searchi($category, $this->categories); + } + OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG); + if($catid === false) { + $l10n = OC_L10N::get('core'); + throw new Exception( + $l10n->t('Could not find category "%s"', $category) + ); + } + $fields = ''; + foreach($tableinfo['fields'] as $field) { + $fields .= '`' . $tableinfo['tablename'] . '`.`' . $field . '`,'; + } + $fields = substr($fields, 0, -1); + + $items = array(); + $sql = 'SELECT `' . self::RELATION_TABLE . '`.`categoryid`, ' . $fields + . ' FROM `' . $tableinfo['tablename'] . '` JOIN `' + . self::RELATION_TABLE . '` ON `' . $tableinfo['tablename'] + . '`.`id` = `' . self::RELATION_TABLE . '`.`objid` WHERE `' + . self::RELATION_TABLE . '`.`categoryid` = ?'; + + try { + $stmt = OCP\DB::prepare($sql, $limit, $offset); + $result = $stmt->execute(array($catid)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + + if(!is_null($result)) { + while( $row = $result->fetchRow()) { + $items[] = $row; + } + } + //OCP\Util::writeLog('core', __METHOD__.', count: ' . count($items), OCP\Util::DEBUG); + //OCP\Util::writeLog('core', __METHOD__.', sql: ' . $sql, OCP\Util::DEBUG); + + return $items; } /** @@ -84,22 +296,51 @@ class OC_VCategories { } /** - * @brief Add a new category name. + * @brief Add a new category. + * @param $name A string with a name of the category + * @returns int the id of the added category or false if it already exists. + */ + public function add($name) { + OCP\Util::writeLog('core', __METHOD__.', name: ' . $name, OCP\Util::DEBUG); + if($this->hasCategory($name)) { + OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', OCP\Util::DEBUG); + return false; + } + OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $name, + )); + $id = OCP\DB::insertid(self::CATEGORY_TABLE); + OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, OCP\Util::DEBUG); + $this->categories[$id] = $name; + return $id; + } + + /** + * @brief Add a new category. * @param $names A string with a name or an array of strings containing * the name(s) of the categor(y|ies) to add. * @param $sync bool When true, save the categories + * @param $id int Optional object id to add to this|these categor(y|ies) * @returns bool Returns false on error. */ - public function add($names, $sync=false) { + public function addMulti($names, $sync=false, $id = null) { if(!is_array($names)) { $names = array($names); } $names = array_map('trim', $names); $newones = array(); foreach($names as $name) { - if(($this->in_arrayi($name, $this->categories) == false) && $name != '') { + if(($this->in_arrayi( + $name, $this->categories) == false) && $name != '') { $newones[] = $name; } + if(!is_null($id) ) { + // Insert $objectid, $categoryid pairs if not exist. + self::$relations[] = array('objid' => $id, 'category' => $name); + } } if(count($newones) > 0) { $this->categories = array_merge($this->categories, $newones); @@ -114,8 +355,8 @@ class OC_VCategories { * @brief Extracts categories from a vobject and add the ones not already present. * @param $vobject The instance of OC_VObject to load the categories from. */ - public function loadFromVObject($vobject, $sync=false) { - $this->add($vobject->getAsArray('CATEGORIES'), $sync); + public function loadFromVObject($id, $vobject, $sync=false) { + $this->addMulti($vobject->getAsArray('CATEGORIES'), $sync, $id); } /** @@ -128,23 +369,62 @@ class OC_VCategories { * $result = $stmt->execute(); * $objects = array(); * if(!is_null($result)) { - * while( $row = $result->fetchRow()) { - * $objects[] = $row['carddata']; + * while( $row = $result->fetchRow()){ + * $objects[] = array($row['id'], $row['carddata']); * } * } * $categories->rescan($objects); */ public function rescan($objects, $sync=true, $reset=true) { + if($reset === true) { + $result = null; + // Find all objectid/categoryid pairs. + try { + $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ?'); + $result = $stmt->execute(array($this->user, $this->type)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } + + // And delete them. + if(!is_null($result)) { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `categoryid` = ? AND `type`= ?'); + while( $row = $result->fetchRow()) { + $stmt->execute(array($row['id'], $this->type)); + } + } + try { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ? AND `type` = ?'); + $result = $stmt->execute(array($this->user, $this->type)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__ . ', exception: ' + . $e->getMessage(), OCP\Util::ERROR); + return; + } $this->categories = array(); } + // Parse all the VObjects foreach($objects as $object) { - //OC_Log::write('core', 'OC_VCategories::rescan: '.substr($object, 0, 100).'(...)', OC_Log::DEBUG); - $vobject = OC_VObject::parse($object); + $vobject = OC_VObject::parse($object[1]); if(!is_null($vobject)) { - $this->loadFromVObject($vobject, $sync); + // Load the categories + $this->loadFromVObject($object[0], $vobject, $sync); } else { - OC_Log::write('core', 'OC_VCategories::rescan, unable to parse. ID: '.', '.substr($object, 0, 100).'(...)', OC_Log::DEBUG); + OC_Log::write('core', __METHOD__ . ', unable to parse. ID: ' . ', ' + . substr($object, 0, 100) . '(...)', OC_Log::DEBUG); } } $this->save(); @@ -155,16 +435,224 @@ class OC_VCategories { */ private function save() { if(is_array($this->categories)) { - usort($this->categories, 'strnatcasecmp'); // usort to also renumber the keys - $escaped_categories = serialize($this->categories); - OC_Preferences::setValue($this->user, $this->app, self::PREF_CATEGORIES_LABEL, $escaped_categories); - OC_Log::write('core', 'OC_VCategories::save: '.print_r($this->categories, true), OC_Log::DEBUG); + foreach($this->categories as $category) { + OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $category, + )); + } + // reload categories to get the proper ids. + $this->loadCategories(); + // Loop through temporarily cached objectid/categoryname pairs + // and save relations. + $categories = $this->categories; + // For some reason this is needed or array_search(i) will return 0..? + ksort($categories); + foreach(self::$relations as $relation) { + $catid = $this->array_searchi($relation['category'], $categories); + OC_Log::write('core', __METHOD__ . 'catid, ' . $relation['category'] . ' ' . $catid, OC_Log::DEBUG); + if($catid) { + OCP\DB::insertIfNotExist(self::RELATION_TABLE, + array( + 'objid' => $relation['objid'], + 'categoryid' => $catid, + 'type' => $this->type, + )); + } + } + self::$relations = array(); // reset } else { - OC_Log::write('core', 'OC_VCategories::save: $this->categories is not an array! '.print_r($this->categories, true), OC_Log::ERROR); + OC_Log::write('core', __METHOD__.', $this->categories is not an array! ' + . print_r($this->categories, true), OC_Log::ERROR); } } /** + * @brief Delete categories and category/object relations for a user. + * For hooking up on post_deleteUser + * @param string $uid The user id for which entries should be purged. + */ + public static function post_deleteUser($arguments) { + // Find all objectid/categoryid pairs. + $result = null; + try { + $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ?'); + $result = $stmt->execute(array($arguments['uid'])); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } + + if(!is_null($result)) { + try { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `categoryid` = ?'); + while( $row = $result->fetchRow()) { + try { + $stmt->execute(array($row['id'])); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } + } + try { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` ' + . 'WHERE `uid` = ? AND'); + $result = $stmt->execute(array($arguments['uid'])); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__ . ', exception: ' + . $e->getMessage(), OCP\Util::ERROR); + } + } + + /** + * @brief Delete category/object relations from the db + * @param int $id The id of the object + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns boolean Returns false on error. + */ + public function purgeObject($id, $type = null) { + $type = is_null($type) ? $this->type : $type; + try { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `objid` = ? AND `type`= ?'); + $result = $stmt->execute(array($id, $type)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + return true; + } + + /** + * Get favorites for an object type + * + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns array An array of object ids. + */ + public function getFavorites($type = null) { + $type = is_null($type) ? $this->type : $type; + + try { + return $this->idsForCategory(self::CATEGORY_FAVORITE); + } catch(Exception $e) { + // No favorites + return array(); + } + } + + /** + * Add an object to favorites + * + * @param int $objid The id of the object + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns boolean + */ + public function addToFavorites($objid, $type = null) { + $type = is_null($type) ? $this->type : $type; + if(!$this->hasCategory(self::CATEGORY_FAVORITE)) { + $this->add(self::CATEGORY_FAVORITE, true); + } + return $this->addToCategory($objid, self::CATEGORY_FAVORITE, $type); + } + + /** + * Remove an object from favorites + * + * @param int $objid The id of the object + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns boolean + */ + public function removeFromFavorites($objid, $type = null) { + $type = is_null($type) ? $this->type : $type; + return $this->removeFromCategory($objid, self::CATEGORY_FAVORITE, $type); + } + + /** + * @brief Creates a category/object relation. + * @param int $objid The id of the object + * @param int|string $category The id or name of the category + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns boolean Returns false on database error. + */ + public function addToCategory($objid, $category, $type = null) { + $type = is_null($type) ? $this->type : $type; + if(is_string($category) && !is_numeric($category)) { + if(!$this->hasCategory($category)) { + $this->add($category, true); + } + $categoryid = $this->array_searchi($category, $this->categories); + } else { + $categoryid = $category; + } + try { + OCP\DB::insertIfNotExist(self::RELATION_TABLE, + array( + 'objid' => $objid, + 'categoryid' => $categoryid, + 'type' => $type, + )); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + return true; + } + + /** + * @brief Delete single category/object relation from the db + * @param int $objid The id of the object + * @param int|string $category The id or name of the category + * @param string $type The type of object (event/contact/task/journal). + * Defaults to the type set in the instance + * @returns boolean + */ + public function removeFromCategory($objid, $category, $type = null) { + $type = is_null($type) ? $this->type : $type; + $categoryid = (is_string($category) && !is_numeric($category)) + ? $this->array_searchi($category, $this->categories) + : $category; + try { + $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?'; + OCP\Util::writeLog('core', __METHOD__.', sql: ' . $objid . ' ' . $categoryid . ' ' . $type, + OCP\Util::DEBUG); + $stmt = OCP\DB::prepare($sql); + $stmt->execute(array($objid, $categoryid, $type)); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + return true; + } + + /** * @brief Delete categories from the db and from all the vobject supplied * @param $names An array of categories to delete * @param $objects An array of arrays with [id,vobject] (as text) pairs suitable for updating the apps object table. @@ -173,37 +661,87 @@ class OC_VCategories { if(!is_array($names)) { $names = array($names); } - OC_Log::write('core', 'OC_VCategories::delete, before: '.print_r($this->categories, true), OC_Log::DEBUG); + + OC_Log::write('core', __METHOD__ . ', before: ' + . print_r($this->categories, true), OC_Log::DEBUG); foreach($names as $name) { - OC_Log::write('core', 'OC_VCategories::delete: '.$name, OC_Log::DEBUG); + $id = null; + OC_Log::write('core', __METHOD__.', '.$name, OC_Log::DEBUG); if($this->hasCategory($name)) { - //OC_Log::write('core', 'OC_VCategories::delete: '.$name.' got it', OC_Log::DEBUG); - unset($this->categories[$this->array_searchi($name, $this->categories)]); + $id = $this->array_searchi($name, $this->categories); + unset($this->categories[$id]); + } + try { + $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` WHERE ' + . '`uid` = ? AND `type` = ? AND `category` = ?'); + $result = $stmt->execute(array($this->user, $this->type, $name)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__ . ', exception: ' + . $e->getMessage(), OCP\Util::ERROR); + } + if(!is_null($id) && $id !== false) { + try { + $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' + . 'WHERE `categoryid` = ?'; + $stmt = OCP\DB::prepare($sql); + $result = $stmt->execute(array($id)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } } } - $this->save(); - OC_Log::write('core', 'OC_VCategories::delete, after: '.print_r($this->categories, true), OC_Log::DEBUG); + OC_Log::write('core', __METHOD__.', after: ' + . print_r($this->categories, true), OC_Log::DEBUG); if(!is_null($objects)) { foreach($objects as $key=>&$value) { $vobject = OC_VObject::parse($value[1]); if(!is_null($vobject)) { - $categories = $vobject->getAsArray('CATEGORIES'); - //OC_Log::write('core', 'OC_VCategories::delete, before: '.$key.': '.print_r($categories, true), OC_Log::DEBUG); + $object = null; + $componentname = ''; + if (isset($vobject->VEVENT)) { + $object = $vobject->VEVENT; + $componentname = 'VEVENT'; + } else + if (isset($vobject->VTODO)) { + $object = $vobject->VTODO; + $componentname = 'VTODO'; + } else + if (isset($vobject->VJOURNAL)) { + $object = $vobject->VJOURNAL; + $componentname = 'VJOURNAL'; + } else { + $object = $vobject; + } + $categories = $object->getAsArray('CATEGORIES'); foreach($names as $name) { $idx = $this->array_searchi($name, $categories); - //OC_Log::write('core', 'OC_VCategories::delete, loop: '.$name.', '.print_r($idx, true), OC_Log::DEBUG); if($idx !== false) { - OC_Log::write('core', 'OC_VCategories::delete, unsetting: '.$categories[$this->array_searchi($name, $categories)], OC_Log::DEBUG); + OC_Log::write('core', __METHOD__ + .', unsetting: ' + . $categories[$this->array_searchi($name, $categories)], + OC_Log::DEBUG); unset($categories[$this->array_searchi($name, $categories)]); - //unset($categories[$idx]); } } - //OC_Log::write('core', 'OC_VCategories::delete, after: '.$key.': '.print_r($categories, true), OC_Log::DEBUG); - $vobject->setString('CATEGORIES', implode(',', $categories)); + + $object->setString('CATEGORIES', implode(',', $categories)); + if($vobject !== $object) { + $vobject[$componentname] = $object; + } $value[1] = $vobject->serialize(); $objects[$key] = $value; } else { - OC_Log::write('core', 'OC_VCategories::delete, unable to parse. ID: '.$value[0].', '.substr($value[1], 0, 50).'(...)', OC_Log::DEBUG); + OC_Log::write('core', __METHOD__ + .', unable to parse. ID: ' . $value[0] . ', ' + . substr($value[1], 0, 50) . '(...)', OC_Log::DEBUG); } } } @@ -224,5 +762,5 @@ class OC_VCategories { } return array_search(strtolower($needle), array_map('strtolower', $haystack)); } - } + |