]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #7156 from MrPetovan/task/add-relationship-filter
authorPhilipp <admin+Github@philipp.info>
Sat, 25 May 2019 18:17:05 +0000 (20:17 +0200)
committerGitHub <noreply@github.com>
Sat, 25 May 2019 18:17:05 +0000 (20:17 +0200)
Add contact relationship filter

doc/FAQ.md
src/Core/Search.php
src/Database/DBA.php
src/Module/Admin/Summary.php
src/Module/BaseSearchModule.php
src/Module/Contact.php

index 140718178536dd3a25a10e32f6d1e704c1064fa7..83bdce3a27806ca2d1d74cb3cb32707e66327454 100644 (file)
@@ -126,16 +126,15 @@ A **hidden contact** will not be displayed in any "friend list" (except to you).
 However a hidden contact will appear normally in conversations and this may expose his/her hidden status to anybody who can see the conversation.
 
 <a name="removed"></a>
-### What happens when an account is removed? Is it truly deleted?
+### What happens when an account is removed?
 
-If you delete your account, we will immediately remove all your content on **your** server.
+If you remove your account, it will be scheduled for permanent deletion in *seven days*. 
+As soon as you activate the deletion process you won't be able to login any more. 
+Only the administrator of your node can halt this process prior to permanent deletion.
 
-Then Friendica issues requests to all your contacts to remove you.
-This will also remove you from the global directory.
-Doing this requires your account and profile still to be "partially" available for up to 24 hours in order to establish contact with all your friends.
-We can block it in several ways so that it appears empty and all profile information erased, but will then wait for 24 hours (or after all of your contacts have been notified) before we can physically remove it.
-
-After that, your account is deleted.
+After the elapsed time of seven days, all your posts, messages, photos, and personal information stored on your node will be deleted. 
+Your node will also issue removal requests to all your contacts; this will also remove your profile from the global directory if you are listed. 
+Your username cannot be reissued for future sign-ups for security reasons.
 
 <a name="hashtag"></a>
 ### Can I follow a hashtag?
index bd4a81a5f4bd7582115af4ca383514a85ffad7aa..48231f08247a94c1206e8c8f62a774dbc8253f53 100644 (file)
@@ -33,22 +33,24 @@ class Search extends BaseObject
         *
         * @param string $user The user to search for
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
        public static function getContactsFromProbe($user)
        {
+               $emptyResultList = new ResultList(1, 0, 1);
+
                if ((filter_var($user, FILTER_VALIDATE_EMAIL) && Network::isEmailDomainValid($user)) ||
                    (substr(Strings::normaliseLink($user), 0, 7) == "http://")) {
 
                        $user_data = Probe::uri($user);
                        if (empty($user_data)) {
-                               return null;
+                               return $emptyResultList;
                        }
 
                        if (!(in_array($user_data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA]))) {
-                               return null;
+                               return $emptyResultList;
                        }
 
                        $contactDetails = Contact::getDetailsByURL(defaults($user_data, 'url', ''), local_user());
@@ -67,9 +69,8 @@ class Search extends BaseObject
                        );
 
                        return new ResultList(1, 1, 1, [$result]);
-
                } else {
-                       return null;
+                       return $emptyResultList;
                }
        }
 
@@ -82,7 +83,7 @@ class Search extends BaseObject
         * @param int    $type specific type of searching
         * @param int    $page
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         */
        public static function getContactsFromGlobalDirectory($search, $type = self::TYPE_ALL, $page = 1)
@@ -113,8 +114,8 @@ class Search extends BaseObject
 
                $resultList = new ResultList(
                        defaults($results, 'page', 1),
-                       defaults($results, 'count', 1),
-                       defaults($results, 'itemsperpage', 1)
+                       defaults($results, 'count', 0),
+                       defaults($results, 'itemsperpage', 30)
                );
 
                $profiles = defaults($results, 'profiles', []);
@@ -148,7 +149,7 @@ class Search extends BaseObject
         * @param int    $start
         * @param int    $itemPage
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         */
        public static function getContactsFromLocalDirectory($search, $type = self::TYPE_ALL, $start = 0, $itemPage = 80)
@@ -173,8 +174,10 @@ class Search extends BaseObject
                        ($type === self::TYPE_FORUM),
                ]);
 
+               $resultList = new ResultList($start, $itemPage, $count);
+
                if (empty($count)) {
-                       return null;
+                       return $resultList;
                }
 
                $data = DBA::select('gcontact', ['nurl'], [
@@ -195,11 +198,9 @@ class Search extends BaseObject
                ]);
 
                if (!DBA::isResult($data)) {
-                       return null;
+                       return $resultList;
                }
 
-               $resultList = new ResultList($start, $itemPage, $count);
-
                while ($row = DBA::fetch($data)) {
                        if (PortableContact::alternateOStatusUrl($row["nurl"])) {
                                continue;
index 2327e4a7f675f9f51c59af3901261fa2139f48d7..9f34a86c15fa9e6d10977bd71fd8f33500f9f261 100644 (file)
@@ -288,6 +288,19 @@ class DBA
                }
        }
 
+       /**
+        * Removes every not whitelisted character from the identifier string
+        *
+        * @param string $identifier
+        *
+        * @return string sanitized identifier
+        * @throws \Exception
+        */
+       private static function sanitizeIdentifier($identifier)
+       {
+               return preg_replace('/[^A-Za-z0-9_\-]+/', '', $identifier);
+       }
+
        public static function escape($str) {
                if (self::$connected) {
                        switch (self::$driver) {
@@ -872,6 +885,29 @@ class DBA
                return $columns;
        }
 
+       /**
+        * @brief Insert a row into a table
+        *
+        * @param string/array $table Table name
+        *
+        * @return string formatted and sanitzed table name
+        * @throws \Exception
+        */
+       public static function formatTableName($table)
+       {
+               if (is_string($table)) {
+                       return "`" . self::sanitizeIdentifier($table) . "`";
+               }
+
+               if (!is_array($table)) {
+                       return '';
+               }
+
+               $scheme = key($table);
+
+               return "`" . self::sanitizeIdentifier($scheme) . "`.`" . self::sanitizeIdentifier($table[$scheme]) . "`";
+       }
+
        /**
         * @brief Insert a row into a table
         *
@@ -889,7 +925,7 @@ class DBA
                        return false;
                }
 
-               $sql = "INSERT INTO `".self::escape($table)."` (`".implode("`, `", array_keys($param))."`) VALUES (".
+               $sql = "INSERT INTO " . self::formatTableName($table) . " (`".implode("`, `", array_keys($param))."`) VALUES (".
                        substr(str_repeat("?, ", count($param)), 0, -2).")";
 
                if ($on_duplicate_update) {
@@ -938,7 +974,7 @@ class DBA
                        self::$connection->autocommit(false);
                }
 
-               $success = self::e("LOCK TABLES `".self::escape($table)."` WRITE");
+               $success = self::e("LOCK TABLES " . self::formatTableName($table) ." WRITE");
 
                if (self::$driver == 'pdo') {
                        self::$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
@@ -1119,7 +1155,7 @@ class DBA
 
                $callstack[$key] = true;
 
-               $table = self::escape($table);
+               $table = self::sanitizeIdentifier($table);
 
                $commands[$key] = ['table' => $table, 'conditions' => $conditions];
 
@@ -1272,8 +1308,6 @@ class DBA
                        return false;
                }
 
-               $table = self::escape($table);
-
                $condition_string = self::buildCondition($condition);
 
                if (is_bool($old_fields)) {
@@ -1306,7 +1340,7 @@ class DBA
                        return true;
                }
 
-               $sql = "UPDATE `".$table."` SET `".
+               $sql = "UPDATE ". self::formatTableName($table) . " SET `".
                        implode("` = ?, `", array_keys($fields))."` = ?".$condition_string;
 
                $params1 = array_values($fields);
@@ -1367,12 +1401,10 @@ class DBA
         */
        public static function select($table, array $fields = [], array $condition = [], array $params = [])
        {
-               if ($table == '') {
+               if (empty($table)) {
                        return false;
                }
 
-               $table = self::escape($table);
-
                if (count($fields) > 0) {
                        $select_fields = "`" . implode("`, `", array_values($fields)) . "`";
                } else {
@@ -1383,7 +1415,7 @@ class DBA
 
                $param_string = self::buildParameter($params);
 
-               $sql = "SELECT " . $select_fields . " FROM `" . $table . "`" . $condition_string . $param_string;
+               $sql = "SELECT " . $select_fields . " FROM " . self::formatTableName($table) . $condition_string . $param_string;
 
                $result = self::p($sql, $condition);
 
@@ -1410,13 +1442,13 @@ class DBA
         */
        public static function count($table, array $condition = [])
        {
-               if ($table == '') {
+               if (empty($table)) {
                        return false;
                }
 
                $condition_string = self::buildCondition($condition);
 
-               $sql = "SELECT COUNT(*) AS `count` FROM `".$table."`".$condition_string;
+               $sql = "SELECT COUNT(*) AS `count` FROM " . self::formatTableName($table) . $condition_string;
 
                $row = self::fetchFirst($sql, $condition);
 
index 901a4b081feaafeaeb5b3881b3b1b269c7555561..98fd74fb32da214ab0af8d5b08c12a5dc4401a7c 100644 (file)
@@ -26,7 +26,7 @@ class Summary extends BaseAdminModule
 
                // are there MyISAM tables in the DB? If so, trigger a warning message
                $warningtext = [];
-               if (DBA::count('`information_schema`.`tables`', ['engine' => 'myisam', 'table_schema' => DBA::databaseName()])) {
+               if (DBA::count(['information_schema' => 'tables'], ['engine' => 'myisam', 'table_schema' => DBA::databaseName()])) {
                        $warningtext[] = L10n::t('Your DB still runs with MyISAM tables. You should change the engine type to InnoDB. As Friendica will use InnoDB only features in the future, you should change this! See <a href="%s">here</a> for a guide that may be helpful converting the table engines. You may also use the command <tt>php bin/console.php dbstructure toinnodb</tt> of your Friendica installation for an automatic conversion.<br />', 'https://dev.mysql.com/doc/refman/5.7/en/converting-tables-to-innodb.html');
                }
 
index 226a4da4d58661724c63ce79cd9aaf8ff89d186a..3393b34123923fe05669a5004ca51093ae85f2b0 100644 (file)
@@ -64,7 +64,6 @@ class BaseSearchModule extends BaseModule
                if ($localSearch && empty($results)) {
                        $pager->setItemsPerPage(80);
                        $results = Search::getContactsFromLocalDirectory($search, $type, $pager->getStart(), $pager->getItemsPerPage());
-
                } elseif (strlen($config->get('system', 'directory')) && empty($results)) {
                        $results = Search::getContactsFromGlobalDirectory($search, $type, $pager->getPage());
                        $pager->setItemsPerPage($results->getItemsPage());
@@ -86,8 +85,8 @@ class BaseSearchModule extends BaseModule
         */
        protected static function printResult(ResultList $results, Pager $pager, $header = '')
        {
-               if (empty($results) || empty($results->getResults())) {
-                       info(L10n::t('No matches') . EOL);
+               if ($results->getTotal() == 0) {
+                       info(L10n::t('No matches'));
                        return '';
                }
 
index a7f0176e53e6fe2df4385c51ce22590694b44f19..847455f498927f0d6444c5a88dcbc858cd780c18 100644 (file)
@@ -260,7 +260,7 @@ class Contact extends BaseModule
        public static function content($update = 0)
        {
                if (!local_user()) {
-                       return Login::form($_SERVER['REQUET_URI']);
+                       return Login::form($_SERVER['REQUEST_URI']);
                }
 
                $a = self::getApp();