Browse Source

Line endings are converted to unix style

tags/3.6
Michael 2 years ago
parent
commit
15a857e411
35 changed files with 1484 additions and 1484 deletions
  1. +67
    -67
      composer.json
  2. +60
    -60
      src/BaseModule.php
  3. +39
    -39
      src/Content/Text/Markdown.php
  4. +162
    -162
      src/Content/Widget/TagCloud.php
  5. +57
    -57
      src/Core/Session.php
  6. +95
    -95
      src/Core/Session/DatabaseSessionHandler.php
  7. +102
    -102
      src/Core/Session/MemcacheSessionHandler.php
  8. +189
    -189
      src/Core/Theme.php
  9. +273
    -273
      src/Database/PostUpdate.php
  10. +60
    -60
      src/Module/Feed.php
  11. +31
    -31
      src/Module/Logout.php
  12. +53
    -53
      src/Module/Oembed.php
  13. +27
    -27
      src/Network/HTTPException.php
  14. +10
    -10
      src/Network/HTTPException/BadGatewayException.php
  15. +10
    -10
      src/Network/HTTPException/BadRequestException.php
  16. +10
    -10
      src/Network/HTTPException/ConflictException.php
  17. +10
    -10
      src/Network/HTTPException/ExpectationFailedException.php
  18. +9
    -9
      src/Network/HTTPException/ForbiddenException.php
  19. +10
    -10
      src/Network/HTTPException/GatewayTimeoutException.php
  20. +10
    -10
      src/Network/HTTPException/GoneException.php
  21. +11
    -11
      src/Network/HTTPException/ImATeapotException.php
  22. +10
    -10
      src/Network/HTTPException/InternalServerErrorException.php
  23. +10
    -10
      src/Network/HTTPException/LenghtRequiredException.php
  24. +10
    -10
      src/Network/HTTPException/MethodNotAllowedException.php
  25. +10
    -10
      src/Network/HTTPException/NonAcceptableException.php
  26. +9
    -9
      src/Network/HTTPException/NotFoundException.php
  27. +10
    -10
      src/Network/HTTPException/NotImplementedException.php
  28. +10
    -10
      src/Network/HTTPException/PreconditionFailedException.php
  29. +10
    -10
      src/Network/HTTPException/ServiceUnavaiableException.php
  30. +10
    -10
      src/Network/HTTPException/TooManyRequestsException.php
  31. +10
    -10
      src/Network/HTTPException/UnauthorizedException.php
  32. +10
    -10
      src/Network/HTTPException/UnprocessableEntityException.php
  33. +10
    -10
      src/Network/HTTPException/UnsupportedMediaTypeException.php
  34. +55
    -55
      src/Render/FriendicaSmarty.php
  35. +15
    -15
      src/Render/ITemplateEngine.php

+ 67
- 67
composer.json View File

@@ -1,67 +1,67 @@
{
"name": "friendica/friendica",
"description": "A decentralized social network part of The Federation",
"type": "project",
"keywords": [
"social network",
"dfrn",
"ostatus",
"diaspora"
],
"license": "AGPL-3.0+",
"support": {
"issues": "https://github.com/friendica/friendica/issues"
},
"require": {
"php": ">5.6",
"ext-xml": "*",
"ezyang/htmlpurifier": "~4.7.0",
"league/html-to-markdown": "~4.4.1",
"lightopenid/lightopenid": "dev-master",
"michelf/php-markdown": "^1.7",
"mobiledetect/mobiledetectlib": "2.8.*",
"paragonie/random_compat": "^2.0",
"pear/Text_LanguageDetect": "1.*",
"pear/Text_Highlighter": "dev-master",
"smarty/smarty": "^3.1",
"fxp/composer-asset-plugin": "~1.3",
"bower-asset/base64": "^1.0",
"bower-asset/Chart-js": "^2.7",
"bower-asset/perfect-scrollbar": "^0.6",
"npm-asset/jquery": "^2.0",
"npm-asset/jquery-colorbox": "^1.6",
"npm-asset/jquery-datetimepicker": "^2.4.0",
"npm-asset/jgrowl": "^1.4",
"npm-asset/fullcalendar": "^3.0.1"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pear/Text_Highlighter"
}
],
"autoload": {
"psr-4": {
"Friendica\\": "src/"
},
"psr-0": {
"": "library/"
}
},
"config": {
"autoloader-suffix": "Friendica",
"optimize-autoloader": true,
"preferred-install": "dist",
"fxp-asset": {
"installer-paths": {
"npm-asset-library": "vendor/asset",
"bower-asset-library": "vendor/asset"
}
}
},
"archive": {
"exclude": [
"log", "cache", "/photo", "/proxy"
]
}
}
{
"name": "friendica/friendica",
"description": "A decentralized social network part of The Federation",
"type": "project",
"keywords": [
"social network",
"dfrn",
"ostatus",
"diaspora"
],
"license": "AGPL-3.0+",
"support": {
"issues": "https://github.com/friendica/friendica/issues"
},
"require": {
"php": ">5.6",
"ext-xml": "*",
"ezyang/htmlpurifier": "~4.7.0",
"league/html-to-markdown": "~4.4.1",
"lightopenid/lightopenid": "dev-master",
"michelf/php-markdown": "^1.7",
"mobiledetect/mobiledetectlib": "2.8.*",
"paragonie/random_compat": "^2.0",
"pear/Text_LanguageDetect": "1.*",
"pear/Text_Highlighter": "dev-master",
"smarty/smarty": "^3.1",
"fxp/composer-asset-plugin": "~1.3",
"bower-asset/base64": "^1.0",
"bower-asset/Chart-js": "^2.7",
"bower-asset/perfect-scrollbar": "^0.6",
"npm-asset/jquery": "^2.0",
"npm-asset/jquery-colorbox": "^1.6",
"npm-asset/jquery-datetimepicker": "^2.4.0",
"npm-asset/jgrowl": "^1.4",
"npm-asset/fullcalendar": "^3.0.1"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pear/Text_Highlighter"
}
],
"autoload": {
"psr-4": {
"Friendica\\": "src/"
},
"psr-0": {
"": "library/"
}
},
"config": {
"autoloader-suffix": "Friendica",
"optimize-autoloader": true,
"preferred-install": "dist",
"fxp-asset": {
"installer-paths": {
"npm-asset-library": "vendor/asset",
"bower-asset-library": "vendor/asset"
}
}
},
"archive": {
"exclude": [
"log", "cache", "/photo", "/proxy"
]
}
}

+ 60
- 60
src/BaseModule.php View File

@@ -1,60 +1,60 @@
<?php
namespace Friendica;
/**
* All modules in Friendica should extend BaseModule, although not all modules
* need to extend all the methods described here
*
* @author Hypolite Petovan mrpetovan@gmail.com
*/
abstract class BaseModule extends BaseObject
{
/**
* @brief Initialization method common to both content() and post()
*
* Extend this method if you need to do any shared processing before both
* content() or post()
*/
public static function init()
{
}
/**
* @brief Module GET method to display any content
*
* Extend this method if the module is supposed to return any display
* through a GET request. It can be an HTML page through templating or a
* XML feed or a JSON output.
*
* @return string
*/
public static function content()
{
$o = '';
return $o;
}
/**
* @brief Module POST method to process submitted data
*
* Extend this method if the module is supposed to process POST requests.
* Doesn't display any content
*/
public static function post()
{
// goaway('module');
}
/**
* @brief Called after post()
*
* Unknown purpose
*/
public static function afterpost()
{
}
}
<?php
namespace Friendica;
/**
* All modules in Friendica should extend BaseModule, although not all modules
* need to extend all the methods described here
*
* @author Hypolite Petovan mrpetovan@gmail.com
*/
abstract class BaseModule extends BaseObject
{
/**
* @brief Initialization method common to both content() and post()
*
* Extend this method if you need to do any shared processing before both
* content() or post()
*/
public static function init()
{
}
/**
* @brief Module GET method to display any content
*
* Extend this method if the module is supposed to return any display
* through a GET request. It can be an HTML page through templating or a
* XML feed or a JSON output.
*
* @return string
*/
public static function content()
{
$o = '';
return $o;
}
/**
* @brief Module POST method to process submitted data
*
* Extend this method if the module is supposed to process POST requests.
* Doesn't display any content
*/
public static function post()
{
// goaway('module');
}
/**
* @brief Called after post()
*
* Unknown purpose
*/
public static function afterpost()
{
}
}

+ 39
- 39
src/Content/Text/Markdown.php View File

@@ -1,39 +1,39 @@
<?php
/**
* @file src/Content/Text/Markdown.php
*/
namespace Friendica\Content\Text;
use Friendica\BaseObject;
use Michelf\MarkdownExtra;
/**
* Friendica-specific usage of Markdown
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Markdown extends BaseObject
{
/**
* Converts a Markdown string into HTML. The hardwrap parameter maximizes
* compatibility with Diaspora in spite of the Markdown standard.
*
* @brief Converts a Markdown string into HTML
* @param string $text
* @param bool $hardwrap
* @return string
*/
public static function convert($text, $hardwrap = true) {
$stamp1 = microtime(true);
$MarkdownParser = new MarkdownExtra();
$MarkdownParser->hard_wrap = $hardwrap;
$html = $MarkdownParser->transform($text);
self::getApp()->save_timestamp($stamp1, "parser");
return $html;
}
}
<?php
/**
* @file src/Content/Text/Markdown.php
*/
namespace Friendica\Content\Text;
use Friendica\BaseObject;
use Michelf\MarkdownExtra;
/**
* Friendica-specific usage of Markdown
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Markdown extends BaseObject
{
/**
* Converts a Markdown string into HTML. The hardwrap parameter maximizes
* compatibility with Diaspora in spite of the Markdown standard.
*
* @brief Converts a Markdown string into HTML
* @param string $text
* @param bool $hardwrap
* @return string
*/
public static function convert($text, $hardwrap = true) {
$stamp1 = microtime(true);
$MarkdownParser = new MarkdownExtra();
$MarkdownParser->hard_wrap = $hardwrap;
$html = $MarkdownParser->transform($text);
self::getApp()->save_timestamp($stamp1, "parser");
return $html;
}
}

+ 162
- 162
src/Content/Widget/TagCloud.php View File

@@ -1,162 +1,162 @@
<?php
/*
* @file src/Content/Widget/TagCloud.php
*/
namespace Friendica\Content\Widget;
use dba;
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBM;
require_once 'include/dba.php';
require_once 'include/security.php';
/**
* TagCloud widget
*
* @author Rabuzarus
*/
class TagCloud
{
/**
* Construct a tag/term cloud block for an user.
*
* @brief Construct a tag/term cloud block for an user.
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact ID of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return string HTML formatted output.
*/
public static function getHTML($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
$o = '';
$r = self::tagadelic($uid, $count, $owner_id, $flags, $type);
if (count($r)) {
$contact = dba::selectFirst('contact', ['url'], ['uid' => $uid, 'self' => true]);
$url = System::removedBaseUrl($contact['url']);
foreach ($r as $rr) {
$tag['level'] = $rr[2];
$tag['url'] = $url . '?tag=' . urlencode($rr[0]);
$tag['name'] = $rr[0];
$tags[] = $tag;
}
$tpl = get_markup_template('tagblock_widget.tpl');
$o = replace_macros($tpl, [
'$title' => L10n::t('Tags'),
'$tags' => $tags
]);
}
return $o;
}
/**
* Get alphabetical sorted array of used tags/terms of an user including
* a weighting by frequency of use.
*
* @brief Get alphabetical sorted array of used tags/terms of an user including
* a weighting by frequency of use.
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact id of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return arr Alphabetical sorted array of used tags of an user.
*/
private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
$item_condition = item_condition();
$sql_options = item_permissions_sql($uid);
$limit = $count ? sprintf('LIMIT %d', intval($count)) : '';
if ($flags) {
if ($flags === 'wall') {
$sql_options .= ' AND `item`.`wall` ';
}
}
if ($owner_id) {
$sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' ';
}
// Fetch tags
$r = dba::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term`
LEFT JOIN `item` ON `term`.`oid` = `item`.`id`
WHERE `term`.`uid` = ? AND `term`.`type` = ?
AND `term`.`otype` = ?
AND $item_condition $sql_options
GROUP BY `term` ORDER BY `total` DESC $limit",
$uid,
$type,
TERM_OBJ_POST
);
if (!DBM::is_result($r)) {
return [];
}
return self::tagCalc($r);
}
/**
* Calculate weighting of tags according to the frequency of use.
*
* @brief Calculate weighting of tags according to the frequency of use.
* @param array $arr Array of tags/terms with tag/term name and total count of use.
* @return array Alphabetical sorted array of used tags/terms of an user.
*/
private static function tagCalc($arr)
{
$tags = [];
$min = 1e9;
$max = -1e9;
$x = 0;
if (!$arr) {
return [];
}
foreach ($arr as $rr) {
$tags[$x][0] = $rr['term'];
$tags[$x][1] = log($rr['total']);
$tags[$x][2] = 0;
$min = min($min, $tags[$x][1]);
$max = max($max, $tags[$x][1]);
$x ++;
}
usort($tags, 'self::tagsSort');
$range = max(.01, $max - $min) * 1.0001;
for ($x = 0; $x < count($tags); $x ++) {
$tags[$x][2] = 1 + floor(9 * ($tags[$x][1] - $min) / $range);
}
return $tags;
}
/**
* Compare function to sort tags/terms alphabetically.
*
* @brief Compare function to sort tags/terms alphabetically.
* @param type $a
* @param type $b
*
* @return int
*/
private static function tagsSort($a, $b)
{
if (strtolower($a[0]) == strtolower($b[0])) {
return 0;
}
return ((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
}
}
<?php
/*
* @file src/Content/Widget/TagCloud.php
*/
namespace Friendica\Content\Widget;
use dba;
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBM;
require_once 'include/dba.php';
require_once 'include/security.php';
/**
* TagCloud widget
*
* @author Rabuzarus
*/
class TagCloud
{
/**
* Construct a tag/term cloud block for an user.
*
* @brief Construct a tag/term cloud block for an user.
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact ID of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return string HTML formatted output.
*/
public static function getHTML($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
$o = '';
$r = self::tagadelic($uid, $count, $owner_id, $flags, $type);
if (count($r)) {
$contact = dba::selectFirst('contact', ['url'], ['uid' => $uid, 'self' => true]);
$url = System::removedBaseUrl($contact['url']);
foreach ($r as $rr) {
$tag['level'] = $rr[2];
$tag['url'] = $url . '?tag=' . urlencode($rr[0]);
$tag['name'] = $rr[0];
$tags[] = $tag;
}
$tpl = get_markup_template('tagblock_widget.tpl');
$o = replace_macros($tpl, [
'$title' => L10n::t('Tags'),
'$tags' => $tags
]);
}
return $o;
}
/**
* Get alphabetical sorted array of used tags/terms of an user including
* a weighting by frequency of use.
*
* @brief Get alphabetical sorted array of used tags/terms of an user including
* a weighting by frequency of use.
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact id of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return arr Alphabetical sorted array of used tags of an user.
*/
private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
$item_condition = item_condition();
$sql_options = item_permissions_sql($uid);
$limit = $count ? sprintf('LIMIT %d', intval($count)) : '';
if ($flags) {
if ($flags === 'wall') {
$sql_options .= ' AND `item`.`wall` ';
}
}
if ($owner_id) {
$sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' ';
}
// Fetch tags
$r = dba::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term`
LEFT JOIN `item` ON `term`.`oid` = `item`.`id`
WHERE `term`.`uid` = ? AND `term`.`type` = ?
AND `term`.`otype` = ?
AND $item_condition $sql_options
GROUP BY `term` ORDER BY `total` DESC $limit",
$uid,
$type,
TERM_OBJ_POST
);
if (!DBM::is_result($r)) {
return [];
}
return self::tagCalc($r);
}
/**
* Calculate weighting of tags according to the frequency of use.
*
* @brief Calculate weighting of tags according to the frequency of use.
* @param array $arr Array of tags/terms with tag/term name and total count of use.
* @return array Alphabetical sorted array of used tags/terms of an user.
*/
private static function tagCalc($arr)
{
$tags = [];
$min = 1e9;
$max = -1e9;
$x = 0;
if (!$arr) {
return [];
}
foreach ($arr as $rr) {
$tags[$x][0] = $rr['term'];
$tags[$x][1] = log($rr['total']);
$tags[$x][2] = 0;
$min = min($min, $tags[$x][1]);
$max = max($max, $tags[$x][1]);
$x ++;
}
usort($tags, 'self::tagsSort');
$range = max(.01, $max - $min) * 1.0001;
for ($x = 0; $x < count($tags); $x ++) {
$tags[$x][2] = 1 + floor(9 * ($tags[$x][1] - $min) / $range);
}
return $tags;
}
/**
* Compare function to sort tags/terms alphabetically.
*
* @brief Compare function to sort tags/terms alphabetically.
* @param type $a
* @param type $b
*
* @return int
*/
private static function tagsSort($a, $b)
{
if (strtolower($a[0]) == strtolower($b[0])) {
return 0;
}
return ((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
}
}

+ 57
- 57
src/Core/Session.php View File

@@ -1,57 +1,57 @@
<?php
/**
* @file src/Core/Session.php
*/
namespace Friendica\Core;
use Friendica\Core\Session\DatabaseSessionHandler;
use Friendica\Core\Session\MemcacheSessionHandler;
/**
* High-level Session service class
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Session
{
public static $exists = false;
public static $expire = 180000;
public static function init()
{
ini_set('session.gc_probability', 50);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_httponly', 1);
if (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL) {
ini_set('session.cookie_secure', 1);
}
if (!Config::get('system', 'disable_database_session')) {
$memcache = Cache::memcache();
if (is_object($memcache)) {
$SessionHandler = new MemcacheSessionHandler($memcache);
} else {
$SessionHandler = new DatabaseSessionHandler();
}
session_set_save_handler($SessionHandler);
}
}
public static function exists($name)
{
return isset($_SESSION[$name]);
}
public static function get($name)
{
return defaults($_SESSION, $name, null);
}
public static function set($name, $value)
{
$_SESSION[$name] = $value;
}
}
<?php
/**
* @file src/Core/Session.php
*/
namespace Friendica\Core;
use Friendica\Core\Session\DatabaseSessionHandler;
use Friendica\Core\Session\MemcacheSessionHandler;
/**
* High-level Session service class
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Session
{
public static $exists = false;
public static $expire = 180000;
public static function init()
{
ini_set('session.gc_probability', 50);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_httponly', 1);
if (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL) {
ini_set('session.cookie_secure', 1);
}
if (!Config::get('system', 'disable_database_session')) {
$memcache = Cache::memcache();
if (is_object($memcache)) {
$SessionHandler = new MemcacheSessionHandler($memcache);
} else {
$SessionHandler = new DatabaseSessionHandler();
}
session_set_save_handler($SessionHandler);
}
}
public static function exists($name)
{
return isset($_SESSION[$name]);
}
public static function get($name)
{
return defaults($_SESSION, $name, null);
}
public static function set($name, $value)
{
$_SESSION[$name] = $value;
}
}

+ 95
- 95
src/Core/Session/DatabaseSessionHandler.php View File

@@ -1,95 +1,95 @@
<?php
namespace Friendica\Core\Session;
use Friendica\BaseObject;
use Friendica\Core\Session;
use Friendica\Database\DBM;
use SessionHandlerInterface;
use dba;
require_once 'boot.php';
require_once 'include/dba.php';
require_once 'include/text.php';
/**
* SessionHandler using database
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class DatabaseSessionHandler extends BaseObject implements SessionHandlerInterface
{
public function open($save_path, $session_name)
{
return true;
}
public function read($session_id)
{
if (!x($session_id)) {
return '';
}
$session = dba::selectFirst('session', ['data'], ['sid' => $session_id]);
if (DBM::is_result($session)) {
Session::$exists = true;
return $session['data'];
}
logger("no data for session $session_id", LOGGER_TRACE);
return '';
}
/**
* @brief Standard PHP session write callback
*
* This callback updates the DB-stored session data and/or the expiration depending
* on the case. Uses the Session::expire global for existing session, 5 minutes
* for newly created session.
*
* @param string $session_id Session ID with format: [a-z0-9]{26}
* @param string $session_data Serialized session data
* @return boolean Returns false if parameters are missing, true otherwise
*/
public function write($session_id, $session_data)
{
if (!$session_id) {
return false;
}
if (!$session_data) {
return true;
}
$expire = time() + Session::$expire;
$default_expire = time() + 300;
if (Session::$exists) {
$fields = ['data' => $session_data, 'expire' => $expire];
$condition = ["`sid` = ? AND (`data` != ? OR `expire` != ?)", $session_id, $session_data, $expire];
dba::update('session', $fields, $condition);
} else {
$fields = ['sid' => $session_id, 'expire' => $default_expire, 'data' => $session_data];
dba::insert('session', $fields);
}
return true;
}
public function close()
{
return true;
}
public function destroy($id)
{
dba::delete('session', ['sid' => $id]);
return true;
}
public function gc($maxlifetime)
{
dba::delete('session', ["`expire` < ?", time()]);
return true;
}
}
<?php
namespace Friendica\Core\Session;
use Friendica\BaseObject;
use Friendica\Core\Session;
use Friendica\Database\DBM;
use SessionHandlerInterface;
use dba;
require_once 'boot.php';
require_once 'include/dba.php';
require_once 'include/text.php';
/**
* SessionHandler using database
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class DatabaseSessionHandler extends BaseObject implements SessionHandlerInterface
{
public function open($save_path, $session_name)
{
return true;
}
public function read($session_id)
{
if (!x($session_id)) {
return '';
}
$session = dba::selectFirst('session', ['data'], ['sid' => $session_id]);
if (DBM::is_result($session)) {
Session::$exists = true;
return $session['data'];
}
logger("no data for session $session_id", LOGGER_TRACE);
return '';
}
/**
* @brief Standard PHP session write callback
*
* This callback updates the DB-stored session data and/or the expiration depending
* on the case. Uses the Session::expire global for existing session, 5 minutes
* for newly created session.
*
* @param string $session_id Session ID with format: [a-z0-9]{26}
* @param string $session_data Serialized session data
* @return boolean Returns false if parameters are missing, true otherwise
*/
public function write($session_id, $session_data)
{
if (!$session_id) {
return false;
}
if (!$session_data) {
return true;
}
$expire = time() + Session::$expire;
$default_expire = time() + 300;
if (Session::$exists) {
$fields = ['data' => $session_data, 'expire' => $expire];
$condition = ["`sid` = ? AND (`data` != ? OR `expire` != ?)", $session_id, $session_data, $expire];
dba::update('session', $fields, $condition);
} else {
$fields = ['sid' => $session_id, 'expire' => $default_expire, 'data' => $session_data];
dba::insert('session', $fields);
}
return true;
}
public function close()
{
return true;
}
public function destroy($id)
{
dba::delete('session', ['sid' => $id]);
return true;
}
public function gc($maxlifetime)
{
dba::delete('session', ["`expire` < ?", time()]);
return true;
}
}

+ 102
- 102
src/Core/Session/MemcacheSessionHandler.php View File

@@ -1,102 +1,102 @@
<?php
namespace Friendica\Core\Session;
use Friendica\BaseObject;
use Friendica\Core\Session;
use SessionHandlerInterface;
use Memcache;
require_once 'boot.php';
require_once 'include/text.php';
/**
* SessionHandler using Memcache
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class MemcacheSessionHandler extends BaseObject implements SessionHandlerInterface
{
/**
* @var Memcache
*/
private $memcache = null;
/**
*
* @param Memcache $memcache
*/
public function __construct(Memcache $memcache)
{
$this->memcache = $memcache;
}
public function open($save_path, $session_name)
{
return true;
}
public function read($session_id)
{
if (!x($session_id)) {
return '';
}
$data = $this->memcache->get(self::getApp()->get_hostname() . ":session:" . $session_id);
if (!is_bool($data)) {
Session::$exists = true;
return $data;
}
logger("no data for session $session_id", LOGGER_TRACE);
return '';
}
/**
* @brief Standard PHP session write callback
*
* This callback updates the stored session data and/or the expiration depending
* on the case. Uses the Session::expire for existing session, 5 minutes
* for newly created session.
*
* @param string $session_id Session ID with format: [a-z0-9]{26}
* @param string $session_data Serialized session data
* @return boolean Returns false if parameters are missing, true otherwise
*/
public function write($session_id, $session_data)
{
if (!$session_id) {
return false;
}
if (!$session_data) {
return true;
}
$expire = time() + Session::$expire;
$this->memcache->set(
self::getApp()->get_hostname() . ":session:" . $session_id,
$session_data,
MEMCACHE_COMPRESSED,
$expire
);
return true;
}
public function close()
{
return true;
}
public function destroy($id)
{
$this->memcache->delete(self::getApp()->get_hostname() . ":session:" . $id);
return true;
}
public function gc($maxlifetime)
{
return true;
}
}
<?php
namespace Friendica\Core\Session;
use Friendica\BaseObject;
use Friendica\Core\Session;
use SessionHandlerInterface;
use Memcache;
require_once 'boot.php';
require_once 'include/text.php';
/**
* SessionHandler using Memcache
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class MemcacheSessionHandler extends BaseObject implements SessionHandlerInterface
{
/**
* @var Memcache
*/
private $memcache = null;
/**
*
* @param Memcache $memcache
*/
public function __construct(Memcache $memcache)
{
$this->memcache = $memcache;
}
public function open($save_path, $session_name)
{
return true;
}
public function read($session_id)
{
if (!x($session_id)) {
return '';
}
$data = $this->memcache->get(self::getApp()->get_hostname() . ":session:" . $session_id);
if (!is_bool($data)) {
Session::$exists = true;
return $data;
}
logger("no data for session $session_id", LOGGER_TRACE);
return '';
}
/**
* @brief Standard PHP session write callback
*
* This callback updates the stored session data and/or the expiration depending
* on the case. Uses the Session::expire for existing session, 5 minutes
* for newly created session.
*
* @param string $session_id Session ID with format: [a-z0-9]{26}
* @param string $session_data Serialized session data
* @return boolean Returns false if parameters are missing, true otherwise
*/
public function write($session_id, $session_data)
{
if (!$session_id) {
return false;
}
if (!$session_data) {
return true;
}
$expire = time() + Session::$expire;
$this->memcache->set(
self::getApp()->get_hostname() . ":session:" . $session_id,
$session_data,
MEMCACHE_COMPRESSED,
$expire
);
return true;
}
public function close()
{
return true;
}
public function destroy($id)
{
$this->memcache->delete(self::getApp()->get_hostname() . ":session:" . $id);
return true;
}
public function gc($maxlifetime)
{
return true;
}
}

+ 189
- 189
src/Core/Theme.php View File

@@ -1,189 +1,189 @@
<?php
/**
* @file src/Core/Theme.php
*/
namespace Friendica\Core;
use Friendica\Core\System;
require_once 'boot.php';
/**
* Some functions to handle themes
*/
class Theme
{
/**
* @brief Parse theme comment in search of theme infos.
*
* like
* \code
* ..* Name: My Theme
* * Description: My Cool Theme
* . * Version: 1.2.3
* * Author: John <profile url>
* * Maintainer: Jane <profile url>
* *
* \endcode
* @param string $theme the name of the theme
* @return array
*/
public static function getInfo($theme)
{
$info=[
'name' => $theme,
'description' => "",
'author' => [],
'maintainer' => [],
'version' => "",
'credits' => "",
'experimental' => false,
'unsupported' => false
];
if (file_exists("view/theme/$theme/experimental"))
$info['experimental'] = true;
if (file_exists("view/theme/$theme/unsupported"))
$info['unsupported'] = true;
if (!is_file("view/theme/$theme/theme.php")) return $info;
$a = get_app();
$stamp1 = microtime(true);
$f = file_get_contents("view/theme/$theme/theme.php");
$a->save_timestamp($stamp1, "file");
$r = preg_match("|/\*.*\*/|msU", $f, $m);
if ($r) {
$ll = explode("\n", $m[0]);
foreach ( $ll as $l ) {
$l = trim($l,"\t\n\r */");
if ($l != "") {
list($k, $v) = array_map("trim", explode(":", $l, 2));
$k= strtolower($k);
if ($k == "author") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['author'][] = ['name'=>$m[1], 'link'=>$m[2]];
} else {
$info['author'][] = ['name'=>$v];
}
} elseif ($k == "maintainer") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['maintainer'][] = ['name'=>$m[1], 'link'=>$m[2]];
} else {
$info['maintainer'][] = ['name'=>$v];
}
} else {
if (array_key_exists($k, $info)) {
$info[$k] = $v;
}
}
}
}
}
return $info;
}
/**
* @brief Returns the theme's screenshot.
*
* The screenshot is expected as view/theme/$theme/screenshot.[png|jpg].
*
* @param sring $theme The name of the theme
* @return string
*/
public static function getScreenshot($theme)
{
$exts = ['.png','.jpg'];
foreach ($exts as $ext) {
if (file_exists('view/theme/' . $theme . '/screenshot' . $ext)) {
return(System::baseUrl() . '/view/theme/' . $theme . '/screenshot' . $ext);
}
}
return(System::baseUrl() . '/images/blank.png');
}
// install and uninstall theme
public static function uninstall($theme)
{
logger("Addons: uninstalling theme " . $theme);
include_once("view/theme/$theme/theme.php");
if (function_exists("{$theme}_uninstall")) {
$func = "{$theme}_uninstall";
$func();
}
}
public static function install($theme)
{
// silently fail if theme was removed
if (! file_exists("view/theme/$theme/theme.php")) {
return false;
}
logger("Addons: installing theme $theme");
include_once("view/theme/$theme/theme.php");
if (function_exists("{$theme}_install")) {
$func = "{$theme}_install";
$func();
return true;
} else {
logger("Addons: FAILED installing theme $theme");
return false;
}
}
/**
* @brief Get the full path to relevant theme files by filename
*
* This function search in the theme directory (and if not present in global theme directory)
* if there is a directory with the file extension and for a file with the given
* filename.
*
* @param string $file Filename
* @param string $root Full root path
* @return string Path to the file or empty string if the file isn't found
*/
public static function getPathForFile($file, $root = '')
{
$file = basename($file);
// Make sure $root ends with a slash / if it's not blank
if ($root !== '' && $root[strlen($root)-1] !== '/') {
$root = $root . '/';
}
$theme_info = get_app()->theme_info;
if (is_array($theme_info) && array_key_exists('extends',$theme_info)) {
$parent = $theme_info['extends'];
} else {
$parent = 'NOPATH';
}
$theme = current_theme();
$thname = $theme;
$ext = substr($file,strrpos($file,'.')+1);
$paths = [
"{$root}view/theme/$thname/$ext/$file",
"{$root}view/theme/$parent/$ext/$file",
"{$root}view/$ext/$file",
];
foreach ($paths as $p) {
// strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php)
if (strpos($p,'NOPATH') !== false) {
continue;
} elseif (file_exists($p)) {
return $p;
}
}
return '';
}
}
<?php
/**
* @file src/Core/Theme.php
*/
namespace Friendica\Core;
use Friendica\Core\System;
require_once 'boot.php';
/**
* Some functions to handle themes
*/
class Theme
{
/**
* @brief Parse theme comment in search of theme infos.
*
* like
* \code
* ..* Name: My Theme
* * Description: My Cool Theme
* . * Version: 1.2.3
* * Author: John <profile url>
* * Maintainer: Jane <profile url>
* *
* \endcode
* @param string $theme the name of the theme
* @return array
*/
public static function getInfo($theme)
{
$info=[
'name' => $theme,
'description' => "",
'author' => [],
'maintainer' => [],
'version' => "",
'credits' => "",
'experimental' => false,
'unsupported' => false
];
if (file_exists("view/theme/$theme/experimental"))
$info['experimental'] = true;
if (file_exists("view/theme/$theme/unsupported"))
$info['unsupported'] = true;
if (!is_file("view/theme/$theme/theme.php")) return $info;
$a = get_app();
$stamp1 = microtime(true);
$f = file_get_contents("view/theme/$theme/theme.php");
$a->save_timestamp($stamp1, "file");
$r = preg_match("|/\*.*\*/|msU", $f, $m);
if ($r) {
$ll = explode("\n", $m[0]);
foreach ( $ll as $l ) {
$l = trim($l,"\t\n\r */");
if ($l != "") {
list($k, $v) = array_map("trim", explode(":", $l, 2));
$k= strtolower($k);
if ($k == "author") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['author'][] = ['name'=>$m[1], 'link'=>$m[2]];
} else {
$info['author'][] = ['name'=>$v];
}
} elseif ($k == "maintainer") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['maintainer'][] = ['name'=>$m[1], 'link'=>$m[2]];
} else {
$info['maintainer'][] = ['name'=>$v];
}
} else {
if (array_key_exists($k, $info)) {
$info[$k] = $v;
}
}
}
}
}
return $info;
}
/**
* @brief Returns the theme's screenshot.
*
* The screenshot is expected as view/theme/$theme/screenshot.[png|jpg].
*
* @param sring $theme The name of the theme
* @return string
*/
public static function getScreenshot($theme)
{
$exts = ['.png','.jpg'];
foreach ($exts as $ext) {
if (file_exists('view/theme/' . $theme . '/screenshot' . $ext)) {
return(System::baseUrl() . '/view/theme/' . $theme . '/screenshot' . $ext);
}
}
return(System::baseUrl() . '/images/blank.png');
}
// install and uninstall theme
public static function uninstall($theme)
{
logger("Addons: uninstalling theme " . $theme);
include_once("view/theme/$theme/theme.php");
if (function_exists("{$theme}_uninstall")) {
$func = "{$theme}_uninstall";
$func();
}
}
public static function install($theme)
{
// silently fail if theme was removed
if (! file_exists("view/theme/$theme/theme.php")) {
return false;
}
logger("Addons: installing theme $theme");
include_once("view/theme/$theme/theme.php");
if (function_exists("{$theme}_install")) {
$func = "{$theme}_install";
$func();
return true;
} else {
logger("Addons: FAILED installing theme $theme");
return false;
}
}
/**
* @brief Get the full path to relevant theme files by filename
*
* This function search in the theme directory (and if not present in global theme directory)
* if there is a directory with the file extension and for a file with the given
* filename.
*
* @param string $file Filename
* @param string $root Full root path
* @return string Path to the file or empty string if the file isn't found
*/
public static function getPathForFile($file, $root = '')
{
$file = basename($file);
// Make sure $root ends with a slash / if it's not blank
if ($root !== '' && $root[strlen($root)-1] !== '/') {
$root = $root . '/';
}
$theme_info = get_app()->theme_info;
if (is_array($theme_info) && array_key_exists('extends',$theme_info)) {
$parent = $theme_info['extends'];
} else {
$parent = 'NOPATH';
}
$theme = current_theme();
$thname = $theme;
$ext = substr($file,strrpos($file,'.')+1);
$paths = [
"{$root}view/theme/$thname/$ext/$file",
"{$root}view/theme/$parent/$ext/$file",
"{$root}view/$ext/$file",
];
foreach ($paths as $p) {
// strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php)
if (strpos($p,'NOPATH') !== false) {
continue;
} elseif (file_exists($p)) {
return $p;
}
}
return '';
}
}

+ 273
- 273
src/Database/PostUpdate.php View File

@@ -1,273 +1,273 @@
<?php
/**
* @file src/Database/PostUpdate.php
*/
namespace Friendica\Database;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
use dba;
require_once 'include/dba.php';
/**
* Post update functions
*/
class PostUpdate
{
/**
* @brief Calls the post update functions
*/
public static function update()
{
if (!self::update1192()) {
return;
}
if (!self::update1194()) {
return;
}
if (!self::update1198()) {
return;
}
if (!self::update1206()) {
return;
}
}
/**
* @brief set the gcontact-id in all item entries
*
* This job has to be started multiple times until all entries are set.
* It isn't started in the update function since it would consume too much time and can be done in the background.
*
* @return bool "true" when the job is done
*/
private static function update1192()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1192) {
return true;
}
// Check if the first step is done (Setting "gcontact-id" in the item table)
$r = dba::select('item', ['author-link', 'author-name', 'author-avatar', 'uid', 'network'], ['gcontact-id' => 0], ['limit' => 1000]);
if (!$r) {
// Are there unfinished entries in the thread table?
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
WHERE `thread`.`gcontact-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
if ($r && ($r[0]["total"] == 0)) {
Config::set("system", "post_update_version", 1192);
return true;
}
// Update the thread table from the item table
q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
SET `thread`.`gcontact-id` = `item`.`gcontact-id`
WHERE `thread`.`gcontact-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
return false;
}
$item_arr = [];
foreach ($r as $item) {
$index = $item["author-link"]."-".$item["uid"];
$item_arr[$index] = ["author-link" => $item["author-link"],
"uid" => $item["uid"],
"network" => $item["network"]];
}
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr as $item) {
$gcontact_id = GContact::getId(["url" => $item['author-link'], "network" => $item['network'],
"photo" => $item['author-avatar'], "name" => $item['author-name']]);
dba::update('item', ['gcontact-id' => $gcontact_id], ['uid' => $item['uid'], 'author-link' => $item['author-link'], 'gcontact-id' => 0]);
}
return false;
}
/**
* @brief Updates the "global" field in the item table
*
* @return bool "true" when the job is done
*/
private static function update1194()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1194) {
return true;
}
logger("Start", LOGGER_DEBUG);
$end_id = Config::get("system", "post_update_1194_end");
if (!$end_id) {
$r = q("SELECT `id` FROM `item` WHERE `uid` != 0 ORDER BY `id` DESC LIMIT 1");
if ($r) {
Config::set("system", "post_update_1194_end", $r[0]["id"]);
$end_id = Config::get("system", "post_update_1194_end");
}
}
logger("End ID: ".$end_id, LOGGER_DEBUG);
$start_id = Config::get("system", "post_update_1194_start");
$query1 = "SELECT `item`.`id` FROM `item` ";
$query2 = "INNER JOIN `item` AS `shadow` ON `item`.`uri` = `shadow`.`uri` AND `shadow`.`uid` = 0 ";
$query3 = "WHERE `item`.`uid` != 0 AND `item`.`id` >= %d AND `item`.`id` <= %d
AND `item`.`visible` AND NOT `item`.`private`
AND NOT `item`.`deleted` AND NOT `item`.`moderated`
AND `item`.`network` IN ('%s', '%s', '%s', '')
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND NOT `item`.`global`";
$r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1",
intval($start_id), intval($end_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
if (!$r) {
Config::set("system", "post_update_version", 1194);
logger("Update is done", LOGGER_DEBUG);
return true;
} else {
Config::set("system", "post_update_1194_start", $r[0]["id"]);
$start_id = Config::get("system", "post_update_1194_start");
}
logger("Start ID: ".$start_id, LOGGER_DEBUG);
$r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1000,1",
intval($start_id), intval($end_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
if ($r)
$pos_id = $r[0]["id"];
else
$pos_id = $end_id;
logger("Progress: Start: ".$start_id." position: ".$pos_id." end: ".$end_id, LOGGER_DEBUG);
q("UPDATE `item` ".$query2." SET `item`.`global` = 1 ".$query3,
intval($start_id), intval($pos_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
logger("Done", LOGGER_DEBUG);
}
/**
* @brief set the author-id and owner-id in all item entries
*
* This job has to be started multiple times until all entries are set.
* It isn't started in the update function since it would consume too much time and can be done in the background.
*
* @return bool "true" when the job is done
*/
private static function update1198()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1198) {
return true;
}
logger("Start", LOGGER_DEBUG);
// Check if the first step is done (Setting "author-id" and "owner-id" in the item table)
$r = dba::select('item', ['author-link', 'owner-link', 'uid'], ['author-id' => 0, 'owner-id' => 0], ['limit' => 1000]);
if (!$r) {
// Are there unfinished entries in the thread table?
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
if ($r && ($r[0]["total"] == 0)) {
Config::set("system", "post_update_version", 1198);
logger("Done", LOGGER_DEBUG);
return true;
}
// Update the thread table from the item table
$r = q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
SET `thread`.`author-id` = `item`.`author-id`,
`thread`.`owner-id` = `item`.`owner-id`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
logger("Updated threads", LOGGER_DEBUG);
if (DBM::is_result($r)) {
Config::set("system", "post_update_version", 1198);
logger("Done", LOGGER_DEBUG);
return true;
}
return false;
}
logger("Query done", LOGGER_DEBUG);
$item_arr = [];
foreach ($r as $item) {
$index = $item["author-link"]."-".$item["owner-link"]."-".$item["uid"];
$item_arr[$index] = ["author-link" => $item["author-link"],
"owner-link" => $item["owner-link"],
"uid" => $item["uid"]];
}
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr as $item) {
$author_id = Contact::getIdForURL($item["author-link"], 0);
$owner_id = Contact::getIdForURL($item["owner-link"], 0);
if ($author_id == 0)
$author_id = -1;
if ($owner_id == 0)
$owner_id = -1;
dba::update('item', ['author-id' => $author_id, 'owner-id' => $owner_id], ['uid' => $item['uid'], 'author-link' => $item['author-link'], 'owner-link' => $item['owner-link'], 'author-id' => 0, 'owner-id' => 0]);
}
logger("Updated items", LOGGER_DEBUG);
return false;
}
/**
* @brief update the "last-item" field in the "self" contact
*
* This field avoids cost intensive calls in the admin panel and in "nodeinfo"
*
* @return bool "true" when the job is done
*/
private static function update1206()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1206) {
return true;
}
logger("Start", LOGGER_DEBUG);
$r = q("SELECT `contact`.`id`, `contact`.`last-item`,
(SELECT MAX(`changed`) FROM `item` USE INDEX (`uid_wall_changed`) WHERE `wall` AND `uid` = `user`.`uid`) AS `lastitem_date`
FROM `user`
INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`");
if (!DBM::is_result($r)) {
return false;
}
foreach ($r as $user) {
if (!empty($user["lastitem_date"]) && ($user["lastitem_date"] > $user["last-item"])) {
dba::update('contact', ['last-item' => $user['lastitem_date']], ['id' => $user['id']]);
}
}
Config::set("system", "post_update_version", 1206);
logger("Done", LOGGER_DEBUG);
return true;
}
}
<?php
/**
* @file src/Database/PostUpdate.php
*/
namespace Friendica\Database;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
use dba;
require_once 'include/dba.php';
/**
* Post update functions
*/
class PostUpdate
{
/**
* @brief Calls the post update functions
*/
public static function update()
{
if (!self::update1192()) {
return;
}
if (!self::update1194()) {
return;
}
if (!self::update1198()) {
return;
}
if (!self::update1206()) {
return;
}
}
/**
* @brief set the gcontact-id in all item entries
*
* This job has to be started multiple times until all entries are set.
* It isn't started in the update function since it would consume too much time and can be done in the background.
*
* @return bool "true" when the job is done
*/
private static function update1192()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1192) {
return true;
}
// Check if the first step is done (Setting "gcontact-id" in the item table)
$r = dba::select('item', ['author-link', 'author-name', 'author-avatar', 'uid', 'network'], ['gcontact-id' => 0], ['limit' => 1000]);
if (!$r) {
// Are there unfinished entries in the thread table?
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
WHERE `thread`.`gcontact-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
if ($r && ($r[0]["total"] == 0)) {
Config::set("system", "post_update_version", 1192);
return true;
}
// Update the thread table from the item table
q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
SET `thread`.`gcontact-id` = `item`.`gcontact-id`
WHERE `thread`.`gcontact-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
return false;
}
$item_arr = [];
foreach ($r as $item) {
$index = $item["author-link"]."-".$item["uid"];
$item_arr[$index] = ["author-link" => $item["author-link"],
"uid" => $item["uid"],
"network" => $item["network"]];
}
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr as $item) {
$gcontact_id = GContact::getId(["url" => $item['author-link'], "network" => $item['network'],
"photo" => $item['author-avatar'], "name" => $item['author-name']]);
dba::update('item', ['gcontact-id' => $gcontact_id], ['uid' => $item['uid'], 'author-link' => $item['author-link'], 'gcontact-id' => 0]);
}
return false;
}
/**
* @brief Updates the "global" field in the item table
*
* @return bool "true" when the job is done
*/
private static function update1194()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1194) {
return true;
}
logger("Start", LOGGER_DEBUG);
$end_id = Config::get("system", "post_update_1194_end");
if (!$end_id) {
$r = q("SELECT `id` FROM `item` WHERE `uid` != 0 ORDER BY `id` DESC LIMIT 1");
if ($r) {
Config::set("system", "post_update_1194_end", $r[0]["id"]);
$end_id = Config::get("system", "post_update_1194_end");
}
}
logger("End ID: ".$end_id, LOGGER_DEBUG);
$start_id = Config::get("system", "post_update_1194_start");
$query1 = "SELECT `item`.`id` FROM `item` ";
$query2 = "INNER JOIN `item` AS `shadow` ON `item`.`uri` = `shadow`.`uri` AND `shadow`.`uid` = 0 ";
$query3 = "WHERE `item`.`uid` != 0 AND `item`.`id` >= %d AND `item`.`id` <= %d
AND `item`.`visible` AND NOT `item`.`private`
AND NOT `item`.`deleted` AND NOT `item`.`moderated`
AND `item`.`network` IN ('%s', '%s', '%s', '')
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND NOT `item`.`global`";
$r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1",
intval($start_id), intval($end_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
if (!$r) {
Config::set("system", "post_update_version", 1194);
logger("Update is done", LOGGER_DEBUG);
return true;
} else {
Config::set("system", "post_update_1194_start", $r[0]["id"]);
$start_id = Config::get("system", "post_update_1194_start");
}
logger("Start ID: ".$start_id, LOGGER_DEBUG);
$r = q($query1.$query2.$query3." ORDER BY `item`.`id` LIMIT 1000,1",
intval($start_id), intval($end_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
if ($r)
$pos_id = $r[0]["id"];
else
$pos_id = $end_id;
logger("Progress: Start: ".$start_id." position: ".$pos_id." end: ".$end_id, LOGGER_DEBUG);
q("UPDATE `item` ".$query2." SET `item`.`global` = 1 ".$query3,
intval($start_id), intval($pos_id),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS));
logger("Done", LOGGER_DEBUG);
}
/**
* @brief set the author-id and owner-id in all item entries
*
* This job has to be started multiple times until all entries are set.
* It isn't started in the update function since it would consume too much time and can be done in the background.
*
* @return bool "true" when the job is done
*/
private static function update1198()
{
// Was the script completed?
if (Config::get("system", "post_update_version") >= 1198) {
return true;
}
logger("Start", LOGGER_DEBUG);
// Check if the first step is done (Setting "author-id" and "owner-id" in the item table)
$r = dba::select('item', ['author-link', 'owner-link', 'uid'], ['author-id' => 0, 'owner-id' => 0], ['limit' => 1000]);
if (!$r) {
// Are there unfinished entries in the thread table?
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
if ($r && ($r[0]["total"] == 0)) {
Config::set("system", "post_update_version", 1198);
logger("Done", LOGGER_DEBUG);
return true;
}
// Update the thread table from the item table
$r = q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
SET `thread`.`author-id` = `item`.`author-id`,
`thread`.`owner-id` = `item`.`owner-id`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
logger("Updated threads", LOGGER_DEBUG);
if (DBM::is_result($r)) {
Config::set("system", "post_update_version", 1198);
logger("Done", LOGGER_DEBUG);
return true;
}
return false;
}
logger("Query done", LOGGER_DEBUG);
$item_arr = [];
foreach ($r as $item) {
$index = $item["author-link"]."-".$item["owner-link"]."-".$item["uid"];
$item_arr[$index] = ["author-link" => $item["author-link"],
"owner-link" => $item["owner-link"],
"uid" => $item["uid"]];
}
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr as $item) {
$author_id = Contact::getIdForURL($item["author-link"], 0);
$owner_id = Contact::getIdForURL($item["owner-link"], 0);