From 83a71a2e777dcc9d1c717b6bf438b9aaf41dffba Mon Sep 17 00:00:00 2001 From: Bruno Ais Date: Sun, 2 Dec 2012 23:01:29 +0000 Subject: [ticket/11171] Use the options stored to decide how to show it Added what's needed so that the post in the report is parsed the same way as it was being parsed when the post was reported PHPBB3-11171 --- phpBB/includes/mcp/mcp_reports.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 3426d62cdb..ca730f7728 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -71,7 +71,7 @@ class mcp_reports // closed reports are accessed by report id $report_id = request_var('r', 0); - $sql = 'SELECT r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, r.reported_post_uid, r.reported_post_bitfield, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour + $sql = 'SELECT r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, r.reported_post_uid, r.reported_post_bitfield, r.reported_post_enable_magic_url, r.reported_post_enable_smilies, r.reported_post_enable_bbcode, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour FROM ' . REPORTS_TABLE . ' r, ' . REPORTS_REASONS_TABLE . ' rr, ' . USERS_TABLE . ' u WHERE ' . (($report_id) ? 'r.report_id = ' . $report_id : "r.post_id = $post_id") . ' AND rr.reason_id = r.reason_id @@ -94,6 +94,10 @@ class mcp_reports $post_id = $report['post_id']; $report_id = $report['report_id']; + + $parse_post_flags = $report['reported_post_enable_bbcode'] ? OPTION_FLAG_BBCODE : 0; + $parse_post_flags += $report['reported_post_enable_smilies'] ? OPTION_FLAG_SMILIES : 0; + $parse_post_flags += $report['reported_post_enable_magic_url'] ? OPTION_FLAG_LINKS : 0; $post_info = get_post_data(array($post_id), 'm_report', true); @@ -227,7 +231,7 @@ class mcp_reports 'REPORTER_NAME' => get_username_string('username', $report['user_id'], $report['username'], $report['user_colour']), 'U_VIEW_REPORTER_PROFILE' => get_username_string('profile', $report['user_id'], $report['username'], $report['user_colour']), - 'POST_PREVIEW' => generate_text_for_display($report['reported_post_text'], $report['reported_post_uid'], $report['reported_post_bitfield'], OPTION_FLAG_BBCODE | OPTION_FLAG_SMILIES, false), + 'POST_PREVIEW' => generate_text_for_display($report['reported_post_text'], $report['reported_post_uid'], $report['reported_post_bitfield'], $parse_post_flags, false), 'POST_SUBJECT' => ($post_info['post_subject']) ? $post_info['post_subject'] : $user->lang['NO_SUBJECT'], 'POST_DATE' => $user->format_date($post_info['post_time']), 'POST_IP' => $post_info['poster_ip'], -- cgit v1.2.1 From 73971ef0fa2a53b056847a524bb84f8b2d3e5a4b Mon Sep 17 00:00:00 2001 From: Bruno Ais Date: Sun, 2 Dec 2012 23:19:59 +0000 Subject: [ticket/11171] Cleanup of leftovers I didn't notice that there were actually leftovers from the other PR. Anyway, this will remove all the leftovers I noticed from the other PR. PHPBB3-11171 --- phpBB/includes/mcp/mcp_reports.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index ca730f7728..8da303f6e3 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -140,18 +140,7 @@ class mcp_reports $post_unread = (isset($topic_tracking_info[$post_info['topic_id']]) && $post_info['post_time'] > $topic_tracking_info[$post_info['topic_id']]) ? true : false; - // Process message, leave it uncensored - $message = $post_info['post_text']; - if ($post_info['bbcode_bitfield']) - { - include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx); - $bbcode = new bbcode($post_info['bbcode_bitfield']); - $bbcode->bbcode_second_pass($message, $post_info['bbcode_uid'], $post_info['bbcode_bitfield']); - } - - $message = bbcode_nl2br($message); - $message = smiley_text($message); $report['report_text'] = make_clickable(bbcode_nl2br($report['report_text'])); if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id'])) @@ -172,7 +161,7 @@ class mcp_reports if (sizeof($attachments)) { $update_count = array(); - parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); + parse_attachments($post_info['forum_id'], $report['reported_post_text'], $attachments, $update_count); } // Display not already displayed Attachments for this post, we already parsed them. ;) -- cgit v1.2.1 From 03d2c6413c25b1faf7f37ff20625ce986b19eb88 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 7 Dec 2012 21:57:33 -0500 Subject: [ticket/11248] Convert line endings to LF - develop edition. PHPBB3-11248 --- phpBB/includes/sphinxapi.php | 3424 +++++++++++++++++++++--------------------- 1 file changed, 1712 insertions(+), 1712 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/sphinxapi.php b/phpBB/includes/sphinxapi.php index bd83b1d2e0..6c3b66710c 100644 --- a/phpBB/includes/sphinxapi.php +++ b/phpBB/includes/sphinxapi.php @@ -1,1712 +1,1712 @@ -=8 ) - { - $v = (int)$v; - return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); - } - - // x32, int - if ( is_int($v) ) - return pack ( "NN", $v < 0 ? -1 : 0, $v ); - - // x32, bcmath - if ( function_exists("bcmul") ) - { - if ( bccomp ( $v, 0 ) == -1 ) - $v = bcadd ( "18446744073709551616", $v ); - $h = bcdiv ( $v, "4294967296", 0 ); - $l = bcmod ( $v, "4294967296" ); - return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit - } - - // x32, no-bcmath - $p = max(0, strlen($v) - 13); - $lo = abs((float)substr($v, $p)); - $hi = abs((float)substr($v, 0, $p)); - - $m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912 - $q = floor($m/4294967296.0); - $l = $m - ($q*4294967296.0); - $h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328 - - if ( $v<0 ) - { - if ( $l==0 ) - $h = 4294967296.0 - $h; - else - { - $h = 4294967295.0 - $h; - $l = 4294967296.0 - $l; - } - } - return pack ( "NN", $h, $l ); -} - -/// pack 64-bit unsigned -function sphPackU64 ( $v ) -{ - assert ( is_numeric($v) ); - - // x64 - if ( PHP_INT_SIZE>=8 ) - { - assert ( $v>=0 ); - - // x64, int - if ( is_int($v) ) - return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); - - // x64, bcmath - if ( function_exists("bcmul") ) - { - $h = bcdiv ( $v, 4294967296, 0 ); - $l = bcmod ( $v, 4294967296 ); - return pack ( "NN", $h, $l ); - } - - // x64, no-bcmath - $p = max ( 0, strlen($v) - 13 ); - $lo = (int)substr ( $v, $p ); - $hi = (int)substr ( $v, 0, $p ); - - $m = $lo + $hi*1316134912; - $l = $m % 4294967296; - $h = $hi*2328 + (int)($m/4294967296); - - return pack ( "NN", $h, $l ); - } - - // x32, int - if ( is_int($v) ) - return pack ( "NN", 0, $v ); - - // x32, bcmath - if ( function_exists("bcmul") ) - { - $h = bcdiv ( $v, "4294967296", 0 ); - $l = bcmod ( $v, "4294967296" ); - return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit - } - - // x32, no-bcmath - $p = max(0, strlen($v) - 13); - $lo = (float)substr($v, $p); - $hi = (float)substr($v, 0, $p); - - $m = $lo + $hi*1316134912.0; - $q = floor($m / 4294967296.0); - $l = $m - ($q * 4294967296.0); - $h = $hi*2328.0 + $q; - - return pack ( "NN", $h, $l ); -} - -// unpack 64-bit unsigned -function sphUnpackU64 ( $v ) -{ - list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); - - if ( PHP_INT_SIZE>=8 ) - { - if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again - if ( $lo<0 ) $lo += (1<<32); - - // x64, int - if ( $hi<=2147483647 ) - return ($hi<<32) + $lo; - - // x64, bcmath - if ( function_exists("bcmul") ) - return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); - - // x64, no-bcmath - $C = 100000; - $h = ((int)($hi / $C) << 32) + (int)($lo / $C); - $l = (($hi % $C) << 32) + ($lo % $C); - if ( $l>$C ) - { - $h += (int)($l / $C); - $l = $l % $C; - } - - if ( $h==0 ) - return $l; - return sprintf ( "%d%05d", $h, $l ); - } - - // x32, int - if ( $hi==0 ) - { - if ( $lo>0 ) - return $lo; - return sprintf ( "%u", $lo ); - } - - $hi = sprintf ( "%u", $hi ); - $lo = sprintf ( "%u", $lo ); - - // x32, bcmath - if ( function_exists("bcmul") ) - return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); - - // x32, no-bcmath - $hi = (float)$hi; - $lo = (float)$lo; - - $q = floor($hi/10000000.0); - $r = $hi - $q*10000000.0; - $m = $lo + $r*4967296.0; - $mq = floor($m/10000000.0); - $l = $m - $mq*10000000.0; - $h = $q*4294967296.0 + $r*429.0 + $mq; - - $h = sprintf ( "%.0f", $h ); - $l = sprintf ( "%07.0f", $l ); - if ( $h=="0" ) - return sprintf( "%.0f", (float)$l ); - return $h . $l; -} - -// unpack 64-bit signed -function sphUnpackI64 ( $v ) -{ - list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); - - // x64 - if ( PHP_INT_SIZE>=8 ) - { - if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again - if ( $lo<0 ) $lo += (1<<32); - - return ($hi<<32) + $lo; - } - - // x32, int - if ( $hi==0 ) - { - if ( $lo>0 ) - return $lo; - return sprintf ( "%u", $lo ); - } - // x32, int - elseif ( $hi==-1 ) - { - if ( $lo<0 ) - return $lo; - return sprintf ( "%.0f", $lo - 4294967296.0 ); - } - - $neg = ""; - $c = 0; - if ( $hi<0 ) - { - $hi = ~$hi; - $lo = ~$lo; - $c = 1; - $neg = "-"; - } - - $hi = sprintf ( "%u", $hi ); - $lo = sprintf ( "%u", $lo ); - - // x32, bcmath - if ( function_exists("bcmul") ) - return $neg . bcadd ( bcadd ( $lo, bcmul ( $hi, "4294967296" ) ), $c ); - - // x32, no-bcmath - $hi = (float)$hi; - $lo = (float)$lo; - - $q = floor($hi/10000000.0); - $r = $hi - $q*10000000.0; - $m = $lo + $r*4967296.0; - $mq = floor($m/10000000.0); - $l = $m - $mq*10000000.0 + $c; - $h = $q*4294967296.0 + $r*429.0 + $mq; - if ( $l==10000000 ) - { - $l = 0; - $h += 1; - } - - $h = sprintf ( "%.0f", $h ); - $l = sprintf ( "%07.0f", $l ); - if ( $h=="0" ) - return $neg . sprintf( "%.0f", (float)$l ); - return $neg . $h . $l; -} - - -function sphFixUint ( $value ) -{ - if ( PHP_INT_SIZE>=8 ) - { - // x64 route, workaround broken unpack() in 5.2.2+ - if ( $value<0 ) $value += (1<<32); - return $value; - } - else - { - // x32 route, workaround php signed/unsigned braindamage - return sprintf ( "%u", $value ); - } -} - - -/// sphinx searchd client class -class SphinxClient -{ - var $_host; ///< searchd host (default is "localhost") - var $_port; ///< searchd port (default is 9312) - var $_offset; ///< how many records to seek from result-set start (default is 0) - var $_limit; ///< how many records to return from result-set starting at offset (default is 20) - var $_mode; ///< query matching mode (default is SPH_MATCH_ALL) - var $_weights; ///< per-field weights (default is 1 for all fields) - var $_sort; ///< match sorting mode (default is SPH_SORT_RELEVANCE) - var $_sortby; ///< attribute to sort by (defualt is "") - var $_min_id; ///< min ID to match (default is 0, which means no limit) - var $_max_id; ///< max ID to match (default is 0, which means no limit) - var $_filters; ///< search filters - var $_groupby; ///< group-by attribute name - var $_groupfunc; ///< group-by function (to pre-process group-by attribute value with) - var $_groupsort; ///< group-by sorting clause (to sort groups in result set with) - var $_groupdistinct;///< group-by count-distinct attribute - var $_maxmatches; ///< max matches to retrieve - var $_cutoff; ///< cutoff to stop searching at (default is 0) - var $_retrycount; ///< distributed retries count - var $_retrydelay; ///< distributed retries delay - var $_anchor; ///< geographical anchor point - var $_indexweights; ///< per-index weights - var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25) - var $_rankexpr; ///< ranking mode expression (for SPH_RANK_EXPR) - var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit) - var $_fieldweights; ///< per-field-name weights - var $_overrides; ///< per-query attribute values overrides - var $_select; ///< select-list (attributes or expressions, with optional aliases) - - var $_error; ///< last error message - var $_warning; ///< last warning message - var $_connerror; ///< connection error vs remote error flag - - var $_reqs; ///< requests array for multi-query - var $_mbenc; ///< stored mbstring encoding - var $_arrayresult; ///< whether $result["matches"] should be a hash or an array - var $_timeout; ///< connect timeout - - ///////////////////////////////////////////////////////////////////////////// - // common stuff - ///////////////////////////////////////////////////////////////////////////// - - /// create a new client object and fill defaults - function SphinxClient () - { - // per-client-object settings - $this->_host = "localhost"; - $this->_port = 9312; - $this->_path = false; - $this->_socket = false; - - // per-query settings - $this->_offset = 0; - $this->_limit = 20; - $this->_mode = SPH_MATCH_ALL; - $this->_weights = array (); - $this->_sort = SPH_SORT_RELEVANCE; - $this->_sortby = ""; - $this->_min_id = 0; - $this->_max_id = 0; - $this->_filters = array (); - $this->_groupby = ""; - $this->_groupfunc = SPH_GROUPBY_DAY; - $this->_groupsort = "@group desc"; - $this->_groupdistinct= ""; - $this->_maxmatches = 1000; - $this->_cutoff = 0; - $this->_retrycount = 0; - $this->_retrydelay = 0; - $this->_anchor = array (); - $this->_indexweights= array (); - $this->_ranker = SPH_RANK_PROXIMITY_BM25; - $this->_rankexpr = ""; - $this->_maxquerytime= 0; - $this->_fieldweights= array(); - $this->_overrides = array(); - $this->_select = "*"; - - $this->_error = ""; // per-reply fields (for single-query case) - $this->_warning = ""; - $this->_connerror = false; - - $this->_reqs = array (); // requests storage (for multi-query case) - $this->_mbenc = ""; - $this->_arrayresult = false; - $this->_timeout = 0; - } - - function __destruct() - { - if ( $this->_socket !== false ) - fclose ( $this->_socket ); - } - - /// get last error message (string) - function GetLastError () - { - return $this->_error; - } - - /// get last warning message (string) - function GetLastWarning () - { - return $this->_warning; - } - - /// get last error flag (to tell network connection errors from searchd errors or broken responses) - function IsConnectError() - { - return $this->_connerror; - } - - /// set searchd host name (string) and port (integer) - function SetServer ( $host, $port = 0 ) - { - assert ( is_string($host) ); - if ( $host[0] == '/') - { - $this->_path = 'unix://' . $host; - return; - } - if ( substr ( $host, 0, 7 )=="unix://" ) - { - $this->_path = $host; - return; - } - - assert ( is_int($port) ); - $this->_host = $host; - $this->_port = $port; - $this->_path = ''; - - } - - /// set server connection timeout (0 to remove) - function SetConnectTimeout ( $timeout ) - { - assert ( is_numeric($timeout) ); - $this->_timeout = $timeout; - } - - - function _Send ( $handle, $data, $length ) - { - if ( feof($handle) || fwrite ( $handle, $data, $length ) !== $length ) - { - $this->_error = 'connection unexpectedly closed (timed out?)'; - $this->_connerror = true; - return false; - } - return true; - } - - ///////////////////////////////////////////////////////////////////////////// - - /// enter mbstring workaround mode - function _MBPush () - { - $this->_mbenc = ""; - if ( ini_get ( "mbstring.func_overload" ) & 2 ) - { - $this->_mbenc = mb_internal_encoding(); - mb_internal_encoding ( "latin1" ); - } - } - - /// leave mbstring workaround mode - function _MBPop () - { - if ( $this->_mbenc ) - mb_internal_encoding ( $this->_mbenc ); - } - - /// connect to searchd server - function _Connect () - { - if ( $this->_socket!==false ) - { - // we are in persistent connection mode, so we have a socket - // however, need to check whether it's still alive - if ( !@feof ( $this->_socket ) ) - return $this->_socket; - - // force reopen - $this->_socket = false; - } - - $errno = 0; - $errstr = ""; - $this->_connerror = false; - - if ( $this->_path ) - { - $host = $this->_path; - $port = 0; - } - else - { - $host = $this->_host; - $port = $this->_port; - } - - if ( $this->_timeout<=0 ) - $fp = @fsockopen ( $host, $port, $errno, $errstr ); - else - $fp = @fsockopen ( $host, $port, $errno, $errstr, $this->_timeout ); - - if ( !$fp ) - { - if ( $this->_path ) - $location = $this->_path; - else - $location = "{$this->_host}:{$this->_port}"; - - $errstr = trim ( $errstr ); - $this->_error = "connection to $location failed (errno=$errno, msg=$errstr)"; - $this->_connerror = true; - return false; - } - - // send my version - // this is a subtle part. we must do it before (!) reading back from searchd. - // because otherwise under some conditions (reported on FreeBSD for instance) - // TCP stack could throttle write-write-read pattern because of Nagle. - if ( !$this->_Send ( $fp, pack ( "N", 1 ), 4 ) ) - { - fclose ( $fp ); - $this->_error = "failed to send client protocol version"; - return false; - } - - // check version - list(,$v) = unpack ( "N*", fread ( $fp, 4 ) ); - $v = (int)$v; - if ( $v<1 ) - { - fclose ( $fp ); - $this->_error = "expected searchd protocol version 1+, got version '$v'"; - return false; - } - - return $fp; - } - - /// get and check response packet from searchd server - function _GetResponse ( $fp, $client_ver ) - { - $response = ""; - $len = 0; - - $header = fread ( $fp, 8 ); - if ( strlen($header)==8 ) - { - list ( $status, $ver, $len ) = array_values ( unpack ( "n2a/Nb", $header ) ); - $left = $len; - while ( $left>0 && !feof($fp) ) - { - $chunk = fread ( $fp, min ( 8192, $left ) ); - if ( $chunk ) - { - $response .= $chunk; - $left -= strlen($chunk); - } - } - } - if ( $this->_socket === false ) - fclose ( $fp ); - - // check response - $read = strlen ( $response ); - if ( !$response || $read!=$len ) - { - $this->_error = $len - ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)" - : "received zero-sized searchd response"; - return false; - } - - // check status - if ( $status==SEARCHD_WARNING ) - { - list(,$wlen) = unpack ( "N*", substr ( $response, 0, 4 ) ); - $this->_warning = substr ( $response, 4, $wlen ); - return substr ( $response, 4+$wlen ); - } - if ( $status==SEARCHD_ERROR ) - { - $this->_error = "searchd error: " . substr ( $response, 4 ); - return false; - } - if ( $status==SEARCHD_RETRY ) - { - $this->_error = "temporary searchd error: " . substr ( $response, 4 ); - return false; - } - if ( $status!=SEARCHD_OK ) - { - $this->_error = "unknown status code '$status'"; - return false; - } - - // check version - if ( $ver<$client_ver ) - { - $this->_warning = sprintf ( "searchd command v.%d.%d older than client's v.%d.%d, some options might not work", - $ver>>8, $ver&0xff, $client_ver>>8, $client_ver&0xff ); - } - - return $response; - } - - ///////////////////////////////////////////////////////////////////////////// - // searching - ///////////////////////////////////////////////////////////////////////////// - - /// set offset and count into result set, - /// and optionally set max-matches and cutoff limits - function SetLimits ( $offset, $limit, $max=0, $cutoff=0 ) - { - assert ( is_int($offset) ); - assert ( is_int($limit) ); - assert ( $offset>=0 ); - assert ( $limit>0 ); - assert ( $max>=0 ); - $this->_offset = $offset; - $this->_limit = $limit; - if ( $max>0 ) - $this->_maxmatches = $max; - if ( $cutoff>0 ) - $this->_cutoff = $cutoff; - } - - /// set maximum query time, in milliseconds, per-index - /// integer, 0 means "do not limit" - function SetMaxQueryTime ( $max ) - { - assert ( is_int($max) ); - assert ( $max>=0 ); - $this->_maxquerytime = $max; - } - - /// set matching mode - function SetMatchMode ( $mode ) - { - assert ( $mode==SPH_MATCH_ALL - || $mode==SPH_MATCH_ANY - || $mode==SPH_MATCH_PHRASE - || $mode==SPH_MATCH_BOOLEAN - || $mode==SPH_MATCH_EXTENDED - || $mode==SPH_MATCH_FULLSCAN - || $mode==SPH_MATCH_EXTENDED2 ); - $this->_mode = $mode; - } - - /// set ranking mode - function SetRankingMode ( $ranker, $rankexpr="" ) - { - assert ( $ranker>=0 && $ranker_ranker = $ranker; - $this->_rankexpr = $rankexpr; - } - - /// set matches sorting mode - function SetSortMode ( $mode, $sortby="" ) - { - assert ( - $mode==SPH_SORT_RELEVANCE || - $mode==SPH_SORT_ATTR_DESC || - $mode==SPH_SORT_ATTR_ASC || - $mode==SPH_SORT_TIME_SEGMENTS || - $mode==SPH_SORT_EXTENDED || - $mode==SPH_SORT_EXPR ); - assert ( is_string($sortby) ); - assert ( $mode==SPH_SORT_RELEVANCE || strlen($sortby)>0 ); - - $this->_sort = $mode; - $this->_sortby = $sortby; - } - - /// bind per-field weights by order - /// DEPRECATED; use SetFieldWeights() instead - function SetWeights ( $weights ) - { - assert ( is_array($weights) ); - foreach ( $weights as $weight ) - assert ( is_int($weight) ); - - $this->_weights = $weights; - } - - /// bind per-field weights by name - function SetFieldWeights ( $weights ) - { - assert ( is_array($weights) ); - foreach ( $weights as $name=>$weight ) - { - assert ( is_string($name) ); - assert ( is_int($weight) ); - } - $this->_fieldweights = $weights; - } - - /// bind per-index weights by name - function SetIndexWeights ( $weights ) - { - assert ( is_array($weights) ); - foreach ( $weights as $index=>$weight ) - { - assert ( is_string($index) ); - assert ( is_int($weight) ); - } - $this->_indexweights = $weights; - } - - /// set IDs range to match - /// only match records if document ID is beetwen $min and $max (inclusive) - function SetIDRange ( $min, $max ) - { - assert ( is_numeric($min) ); - assert ( is_numeric($max) ); - assert ( $min<=$max ); - $this->_min_id = $min; - $this->_max_id = $max; - } - - /// set values set filter - /// only match records where $attribute value is in given set - function SetFilter ( $attribute, $values, $exclude=false ) - { - assert ( is_string($attribute) ); - assert ( is_array($values) ); - assert ( count($values) ); - - if ( is_array($values) && count($values) ) - { - foreach ( $values as $value ) - assert ( is_numeric($value) ); - - $this->_filters[] = array ( "type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values ); - } - } - - /// set range filter - /// only match records if $attribute value is beetwen $min and $max (inclusive) - function SetFilterRange ( $attribute, $min, $max, $exclude=false ) - { - assert ( is_string($attribute) ); - assert ( is_numeric($min) ); - assert ( is_numeric($max) ); - assert ( $min<=$max ); - - $this->_filters[] = array ( "type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); - } - - /// set float range filter - /// only match records if $attribute value is beetwen $min and $max (inclusive) - function SetFilterFloatRange ( $attribute, $min, $max, $exclude=false ) - { - assert ( is_string($attribute) ); - assert ( is_float($min) ); - assert ( is_float($max) ); - assert ( $min<=$max ); - - $this->_filters[] = array ( "type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); - } - - /// setup anchor point for geosphere distance calculations - /// required to use @geodist in filters and sorting - /// latitude and longitude must be in radians - function SetGeoAnchor ( $attrlat, $attrlong, $lat, $long ) - { - assert ( is_string($attrlat) ); - assert ( is_string($attrlong) ); - assert ( is_float($lat) ); - assert ( is_float($long) ); - - $this->_anchor = array ( "attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long ); - } - - /// set grouping attribute and function - function SetGroupBy ( $attribute, $func, $groupsort="@group desc" ) - { - assert ( is_string($attribute) ); - assert ( is_string($groupsort) ); - assert ( $func==SPH_GROUPBY_DAY - || $func==SPH_GROUPBY_WEEK - || $func==SPH_GROUPBY_MONTH - || $func==SPH_GROUPBY_YEAR - || $func==SPH_GROUPBY_ATTR - || $func==SPH_GROUPBY_ATTRPAIR ); - - $this->_groupby = $attribute; - $this->_groupfunc = $func; - $this->_groupsort = $groupsort; - } - - /// set count-distinct attribute for group-by queries - function SetGroupDistinct ( $attribute ) - { - assert ( is_string($attribute) ); - $this->_groupdistinct = $attribute; - } - - /// set distributed retries count and delay - function SetRetries ( $count, $delay=0 ) - { - assert ( is_int($count) && $count>=0 ); - assert ( is_int($delay) && $delay>=0 ); - $this->_retrycount = $count; - $this->_retrydelay = $delay; - } - - /// set result set format (hash or array; hash by default) - /// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs - function SetArrayResult ( $arrayresult ) - { - assert ( is_bool($arrayresult) ); - $this->_arrayresult = $arrayresult; - } - - /// set attribute values override - /// there can be only one override per attribute - /// $values must be a hash that maps document IDs to attribute values - function SetOverride ( $attrname, $attrtype, $values ) - { - assert ( is_string ( $attrname ) ); - assert ( in_array ( $attrtype, array ( SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT ) ) ); - assert ( is_array ( $values ) ); - - $this->_overrides[$attrname] = array ( "attr"=>$attrname, "type"=>$attrtype, "values"=>$values ); - } - - /// set select-list (attributes or expressions), SQL-like syntax - function SetSelect ( $select ) - { - assert ( is_string ( $select ) ); - $this->_select = $select; - } - - ////////////////////////////////////////////////////////////////////////////// - - /// clear all filters (for multi-queries) - function ResetFilters () - { - $this->_filters = array(); - $this->_anchor = array(); - } - - /// clear groupby settings (for multi-queries) - function ResetGroupBy () - { - $this->_groupby = ""; - $this->_groupfunc = SPH_GROUPBY_DAY; - $this->_groupsort = "@group desc"; - $this->_groupdistinct= ""; - } - - /// clear all attribute value overrides (for multi-queries) - function ResetOverrides () - { - $this->_overrides = array (); - } - - ////////////////////////////////////////////////////////////////////////////// - - /// connect to searchd server, run given search query through given indexes, - /// and return the search results - function Query ( $query, $index="*", $comment="" ) - { - assert ( empty($this->_reqs) ); - - $this->AddQuery ( $query, $index, $comment ); - $results = $this->RunQueries (); - $this->_reqs = array (); // just in case it failed too early - - if ( !is_array($results) ) - return false; // probably network error; error message should be already filled - - $this->_error = $results[0]["error"]; - $this->_warning = $results[0]["warning"]; - if ( $results[0]["status"]==SEARCHD_ERROR ) - return false; - else - return $results[0]; - } - - /// helper to pack floats in network byte order - function _PackFloat ( $f ) - { - $t1 = pack ( "f", $f ); // machine order - list(,$t2) = unpack ( "L*", $t1 ); // int in machine order - return pack ( "N", $t2 ); - } - - /// add query to multi-query batch - /// returns index into results array from RunQueries() call - function AddQuery ( $query, $index="*", $comment="" ) - { - // mbstring workaround - $this->_MBPush (); - - // build request - $req = pack ( "NNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker ); - if ( $this->_ranker==SPH_RANK_EXPR ) - $req .= pack ( "N", strlen($this->_rankexpr) ) . $this->_rankexpr; - $req .= pack ( "N", $this->_sort ); // (deprecated) sort mode - $req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby; - $req .= pack ( "N", strlen($query) ) . $query; // query itself - $req .= pack ( "N", count($this->_weights) ); // weights - foreach ( $this->_weights as $weight ) - $req .= pack ( "N", (int)$weight ); - $req .= pack ( "N", strlen($index) ) . $index; // indexes - $req .= pack ( "N", 1 ); // id64 range marker - $req .= sphPackU64 ( $this->_min_id ) . sphPackU64 ( $this->_max_id ); // id64 range - - // filters - $req .= pack ( "N", count($this->_filters) ); - foreach ( $this->_filters as $filter ) - { - $req .= pack ( "N", strlen($filter["attr"]) ) . $filter["attr"]; - $req .= pack ( "N", $filter["type"] ); - switch ( $filter["type"] ) - { - case SPH_FILTER_VALUES: - $req .= pack ( "N", count($filter["values"]) ); - foreach ( $filter["values"] as $value ) - $req .= sphPackI64 ( $value ); - break; - - case SPH_FILTER_RANGE: - $req .= sphPackI64 ( $filter["min"] ) . sphPackI64 ( $filter["max"] ); - break; - - case SPH_FILTER_FLOATRANGE: - $req .= $this->_PackFloat ( $filter["min"] ) . $this->_PackFloat ( $filter["max"] ); - break; - - default: - assert ( 0 && "internal error: unhandled filter type" ); - } - $req .= pack ( "N", $filter["exclude"] ); - } - - // group-by clause, max-matches count, group-sort clause, cutoff count - $req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby; - $req .= pack ( "N", $this->_maxmatches ); - $req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort; - $req .= pack ( "NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay ); - $req .= pack ( "N", strlen($this->_groupdistinct) ) . $this->_groupdistinct; - - // anchor point - if ( empty($this->_anchor) ) - { - $req .= pack ( "N", 0 ); - } else - { - $a =& $this->_anchor; - $req .= pack ( "N", 1 ); - $req .= pack ( "N", strlen($a["attrlat"]) ) . $a["attrlat"]; - $req .= pack ( "N", strlen($a["attrlong"]) ) . $a["attrlong"]; - $req .= $this->_PackFloat ( $a["lat"] ) . $this->_PackFloat ( $a["long"] ); - } - - // per-index weights - $req .= pack ( "N", count($this->_indexweights) ); - foreach ( $this->_indexweights as $idx=>$weight ) - $req .= pack ( "N", strlen($idx) ) . $idx . pack ( "N", $weight ); - - // max query time - $req .= pack ( "N", $this->_maxquerytime ); - - // per-field weights - $req .= pack ( "N", count($this->_fieldweights) ); - foreach ( $this->_fieldweights as $field=>$weight ) - $req .= pack ( "N", strlen($field) ) . $field . pack ( "N", $weight ); - - // comment - $req .= pack ( "N", strlen($comment) ) . $comment; - - // attribute overrides - $req .= pack ( "N", count($this->_overrides) ); - foreach ( $this->_overrides as $key => $entry ) - { - $req .= pack ( "N", strlen($entry["attr"]) ) . $entry["attr"]; - $req .= pack ( "NN", $entry["type"], count($entry["values"]) ); - foreach ( $entry["values"] as $id=>$val ) - { - assert ( is_numeric($id) ); - assert ( is_numeric($val) ); - - $req .= sphPackU64 ( $id ); - switch ( $entry["type"] ) - { - case SPH_ATTR_FLOAT: $req .= $this->_PackFloat ( $val ); break; - case SPH_ATTR_BIGINT: $req .= sphPackI64 ( $val ); break; - default: $req .= pack ( "N", $val ); break; - } - } - } - - // select-list - $req .= pack ( "N", strlen($this->_select) ) . $this->_select; - - // mbstring workaround - $this->_MBPop (); - - // store request to requests array - $this->_reqs[] = $req; - return count($this->_reqs)-1; - } - - /// connect to searchd, run queries batch, and return an array of result sets - function RunQueries () - { - if ( empty($this->_reqs) ) - { - $this->_error = "no queries defined, issue AddQuery() first"; - return false; - } - - // mbstring workaround - $this->_MBPush (); - - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop (); - return false; - } - - // send query, get response - $nreqs = count($this->_reqs); - $req = join ( "", $this->_reqs ); - $len = 8+strlen($req); - $req = pack ( "nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs ) . $req; // add header - - if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || - !( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ) ) - { - $this->_MBPop (); - return false; - } - - // query sent ok; we can reset reqs now - $this->_reqs = array (); - - // parse and return response - return $this->_ParseSearchResponse ( $response, $nreqs ); - } - - /// parse and return search query (or queries) response - function _ParseSearchResponse ( $response, $nreqs ) - { - $p = 0; // current position - $max = strlen($response); // max position for checks, to protect against broken responses - - $results = array (); - for ( $ires=0; $ires<$nreqs && $p<$max; $ires++ ) - { - $results[] = array(); - $result =& $results[$ires]; - - $result["error"] = ""; - $result["warning"] = ""; - - // extract status - list(,$status) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $result["status"] = $status; - if ( $status!=SEARCHD_OK ) - { - list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $message = substr ( $response, $p, $len ); $p += $len; - - if ( $status==SEARCHD_WARNING ) - { - $result["warning"] = $message; - } else - { - $result["error"] = $message; - continue; - } - } - - // read schema - $fields = array (); - $attrs = array (); - - list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - while ( $nfields-->0 && $p<$max ) - { - list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $fields[] = substr ( $response, $p, $len ); $p += $len; - } - $result["fields"] = $fields; - - list(,$nattrs) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - while ( $nattrs-->0 && $p<$max ) - { - list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $attr = substr ( $response, $p, $len ); $p += $len; - list(,$type) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $attrs[$attr] = $type; - } - $result["attrs"] = $attrs; - - // read match count - list(,$count) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - list(,$id64) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - - // read matches - $idx = -1; - while ( $count-->0 && $p<$max ) - { - // index into result array - $idx++; - - // parse document id and weight - if ( $id64 ) - { - $doc = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8; - list(,$weight) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - } - else - { - list ( $doc, $weight ) = array_values ( unpack ( "N*N*", - substr ( $response, $p, 8 ) ) ); - $p += 8; - $doc = sphFixUint($doc); - } - $weight = sprintf ( "%u", $weight ); - - // create match entry - if ( $this->_arrayresult ) - $result["matches"][$idx] = array ( "id"=>$doc, "weight"=>$weight ); - else - $result["matches"][$doc]["weight"] = $weight; - - // parse and create attributes - $attrvals = array (); - foreach ( $attrs as $attr=>$type ) - { - // handle 64bit ints - if ( $type==SPH_ATTR_BIGINT ) - { - $attrvals[$attr] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8; - continue; - } - - // handle floats - if ( $type==SPH_ATTR_FLOAT ) - { - list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - list(,$fval) = unpack ( "f*", pack ( "L", $uval ) ); - $attrvals[$attr] = $fval; - continue; - } - - // handle everything else as unsigned ints - list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - if ( $type==SPH_ATTR_MULTI ) - { - $attrvals[$attr] = array (); - $nvalues = $val; - while ( $nvalues-->0 && $p<$max ) - { - list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $attrvals[$attr][] = sphFixUint($val); - } - } else if ( $type==SPH_ATTR_MULTI64 ) - { - $attrvals[$attr] = array (); - $nvalues = $val; - while ( $nvalues>0 && $p<$max ) - { - $attrvals[$attr][] = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8; - $nvalues -= 2; - } - } else if ( $type==SPH_ATTR_STRING ) - { - $attrvals[$attr] = substr ( $response, $p, $val ); - $p += $val; - } else - { - $attrvals[$attr] = sphFixUint($val); - } - } - - if ( $this->_arrayresult ) - $result["matches"][$idx]["attrs"] = $attrvals; - else - $result["matches"][$doc]["attrs"] = $attrvals; - } - - list ( $total, $total_found, $msecs, $words ) = - array_values ( unpack ( "N*N*N*N*", substr ( $response, $p, 16 ) ) ); - $result["total"] = sprintf ( "%u", $total ); - $result["total_found"] = sprintf ( "%u", $total_found ); - $result["time"] = sprintf ( "%.3f", $msecs/1000 ); - $p += 16; - - while ( $words-->0 && $p<$max ) - { - list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $word = substr ( $response, $p, $len ); $p += $len; - list ( $docs, $hits ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; - $result["words"][$word] = array ( - "docs"=>sprintf ( "%u", $docs ), - "hits"=>sprintf ( "%u", $hits ) ); - } - } - - $this->_MBPop (); - return $results; - } - - ///////////////////////////////////////////////////////////////////////////// - // excerpts generation - ///////////////////////////////////////////////////////////////////////////// - - /// connect to searchd server, and generate exceprts (snippets) - /// of given documents for given query. returns false on failure, - /// an array of snippets on success - function BuildExcerpts ( $docs, $index, $words, $opts=array() ) - { - assert ( is_array($docs) ); - assert ( is_string($index) ); - assert ( is_string($words) ); - assert ( is_array($opts) ); - - $this->_MBPush (); - - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop(); - return false; - } - - ///////////////// - // fixup options - ///////////////// - - if ( !isset($opts["before_match"]) ) $opts["before_match"] = ""; - if ( !isset($opts["after_match"]) ) $opts["after_match"] = ""; - if ( !isset($opts["chunk_separator"]) ) $opts["chunk_separator"] = " ... "; - if ( !isset($opts["limit"]) ) $opts["limit"] = 256; - if ( !isset($opts["limit_passages"]) ) $opts["limit_passages"] = 0; - if ( !isset($opts["limit_words"]) ) $opts["limit_words"] = 0; - if ( !isset($opts["around"]) ) $opts["around"] = 5; - if ( !isset($opts["exact_phrase"]) ) $opts["exact_phrase"] = false; - if ( !isset($opts["single_passage"]) ) $opts["single_passage"] = false; - if ( !isset($opts["use_boundaries"]) ) $opts["use_boundaries"] = false; - if ( !isset($opts["weight_order"]) ) $opts["weight_order"] = false; - if ( !isset($opts["query_mode"]) ) $opts["query_mode"] = false; - if ( !isset($opts["force_all_words"]) ) $opts["force_all_words"] = false; - if ( !isset($opts["start_passage_id"]) ) $opts["start_passage_id"] = 1; - if ( !isset($opts["load_files"]) ) $opts["load_files"] = false; - if ( !isset($opts["html_strip_mode"]) ) $opts["html_strip_mode"] = "index"; - if ( !isset($opts["allow_empty"]) ) $opts["allow_empty"] = false; - if ( !isset($opts["passage_boundary"]) ) $opts["passage_boundary"] = "none"; - if ( !isset($opts["emit_zones"]) ) $opts["emit_zones"] = false; - if ( !isset($opts["load_files_scattered"]) ) $opts["load_files_scattered"] = false; - - - ///////////////// - // build request - ///////////////// - - // v.1.2 req - $flags = 1; // remove spaces - if ( $opts["exact_phrase"] ) $flags |= 2; - if ( $opts["single_passage"] ) $flags |= 4; - if ( $opts["use_boundaries"] ) $flags |= 8; - if ( $opts["weight_order"] ) $flags |= 16; - if ( $opts["query_mode"] ) $flags |= 32; - if ( $opts["force_all_words"] ) $flags |= 64; - if ( $opts["load_files"] ) $flags |= 128; - if ( $opts["allow_empty"] ) $flags |= 256; - if ( $opts["emit_zones"] ) $flags |= 512; - if ( $opts["load_files_scattered"] ) $flags |= 1024; - $req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags - $req .= pack ( "N", strlen($index) ) . $index; // req index - $req .= pack ( "N", strlen($words) ) . $words; // req words - - // options - $req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"]; - $req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"]; - $req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"]; - $req .= pack ( "NN", (int)$opts["limit"], (int)$opts["around"] ); - $req .= pack ( "NNN", (int)$opts["limit_passages"], (int)$opts["limit_words"], (int)$opts["start_passage_id"] ); // v.1.2 - $req .= pack ( "N", strlen($opts["html_strip_mode"]) ) . $opts["html_strip_mode"]; - $req .= pack ( "N", strlen($opts["passage_boundary"]) ) . $opts["passage_boundary"]; - - // documents - $req .= pack ( "N", count($docs) ); - foreach ( $docs as $doc ) - { - assert ( is_string($doc) ); - $req .= pack ( "N", strlen($doc) ) . $doc; - } - - //////////////////////////// - // send query, get response - //////////////////////////// - - $len = strlen($req); - $req = pack ( "nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len ) . $req; // add header - if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || - !( $response = $this->_GetResponse ( $fp, VER_COMMAND_EXCERPT ) ) ) - { - $this->_MBPop (); - return false; - } - - ////////////////// - // parse response - ////////////////// - - $pos = 0; - $res = array (); - $rlen = strlen($response); - for ( $i=0; $i $rlen ) - { - $this->_error = "incomplete reply"; - $this->_MBPop (); - return false; - } - $res[] = $len ? substr ( $response, $pos, $len ) : ""; - $pos += $len; - } - - $this->_MBPop (); - return $res; - } - - - ///////////////////////////////////////////////////////////////////////////// - // keyword generation - ///////////////////////////////////////////////////////////////////////////// - - /// connect to searchd server, and generate keyword list for a given query - /// returns false on failure, - /// an array of words on success - function BuildKeywords ( $query, $index, $hits ) - { - assert ( is_string($query) ); - assert ( is_string($index) ); - assert ( is_bool($hits) ); - - $this->_MBPush (); - - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop(); - return false; - } - - ///////////////// - // build request - ///////////////// - - // v.1.0 req - $req = pack ( "N", strlen($query) ) . $query; // req query - $req .= pack ( "N", strlen($index) ) . $index; // req index - $req .= pack ( "N", (int)$hits ); - - //////////////////////////// - // send query, get response - //////////////////////////// - - $len = strlen($req); - $req = pack ( "nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len ) . $req; // add header - if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || - !( $response = $this->_GetResponse ( $fp, VER_COMMAND_KEYWORDS ) ) ) - { - $this->_MBPop (); - return false; - } - - ////////////////// - // parse response - ////////////////// - - $pos = 0; - $res = array (); - $rlen = strlen($response); - list(,$nwords) = unpack ( "N*", substr ( $response, $pos, 4 ) ); - $pos += 4; - for ( $i=0; $i<$nwords; $i++ ) - { - list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; - $tokenized = $len ? substr ( $response, $pos, $len ) : ""; - $pos += $len; - - list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; - $normalized = $len ? substr ( $response, $pos, $len ) : ""; - $pos += $len; - - $res[] = array ( "tokenized"=>$tokenized, "normalized"=>$normalized ); - - if ( $hits ) - { - list($ndocs,$nhits) = array_values ( unpack ( "N*N*", substr ( $response, $pos, 8 ) ) ); - $pos += 8; - $res [$i]["docs"] = $ndocs; - $res [$i]["hits"] = $nhits; - } - - if ( $pos > $rlen ) - { - $this->_error = "incomplete reply"; - $this->_MBPop (); - return false; - } - } - - $this->_MBPop (); - return $res; - } - - function EscapeString ( $string ) - { - $from = array ( '\\', '(',')','|','-','!','@','~','"','&', '/', '^', '$', '=' ); - $to = array ( '\\\\', '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/', '\^', '\$', '\=' ); - - return str_replace ( $from, $to, $string ); - } - - ///////////////////////////////////////////////////////////////////////////// - // attribute updates - ///////////////////////////////////////////////////////////////////////////// - - /// batch update given attributes in given rows in given indexes - /// returns amount of updated documents (0 or more) on success, or -1 on failure - function UpdateAttributes ( $index, $attrs, $values, $mva=false ) - { - // verify everything - assert ( is_string($index) ); - assert ( is_bool($mva) ); - - assert ( is_array($attrs) ); - foreach ( $attrs as $attr ) - assert ( is_string($attr) ); - - assert ( is_array($values) ); - foreach ( $values as $id=>$entry ) - { - assert ( is_numeric($id) ); - assert ( is_array($entry) ); - assert ( count($entry)==count($attrs) ); - foreach ( $entry as $v ) - { - if ( $mva ) - { - assert ( is_array($v) ); - foreach ( $v as $vv ) - assert ( is_int($vv) ); - } else - assert ( is_int($v) ); - } - } - - // build request - $this->_MBPush (); - $req = pack ( "N", strlen($index) ) . $index; - - $req .= pack ( "N", count($attrs) ); - foreach ( $attrs as $attr ) - { - $req .= pack ( "N", strlen($attr) ) . $attr; - $req .= pack ( "N", $mva ? 1 : 0 ); - } - - $req .= pack ( "N", count($values) ); - foreach ( $values as $id=>$entry ) - { - $req .= sphPackU64 ( $id ); - foreach ( $entry as $v ) - { - $req .= pack ( "N", $mva ? count($v) : $v ); - if ( $mva ) - foreach ( $v as $vv ) - $req .= pack ( "N", $vv ); - } - } - - // connect, send query, get response - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop (); - return -1; - } - - $len = strlen($req); - $req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header - if ( !$this->_Send ( $fp, $req, $len+8 ) ) - { - $this->_MBPop (); - return -1; - } - - if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) )) - { - $this->_MBPop (); - return -1; - } - - // parse response - list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) ); - $this->_MBPop (); - return $updated; - } - - ///////////////////////////////////////////////////////////////////////////// - // persistent connections - ///////////////////////////////////////////////////////////////////////////// - - function Open() - { - if ( $this->_socket !== false ) - { - $this->_error = 'already connected'; - return false; - } - if ( !$fp = $this->_Connect() ) - return false; - - // command, command version = 0, body length = 4, body = 1 - $req = pack ( "nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1 ); - if ( !$this->_Send ( $fp, $req, 12 ) ) - return false; - - $this->_socket = $fp; - return true; - } - - function Close() - { - if ( $this->_socket === false ) - { - $this->_error = 'not connected'; - return false; - } - - fclose ( $this->_socket ); - $this->_socket = false; - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - // status - ////////////////////////////////////////////////////////////////////////// - - function Status () - { - $this->_MBPush (); - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop(); - return false; - } - - $req = pack ( "nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1 ); // len=4, body=1 - if ( !( $this->_Send ( $fp, $req, 12 ) ) || - !( $response = $this->_GetResponse ( $fp, VER_COMMAND_STATUS ) ) ) - { - $this->_MBPop (); - return false; - } - - $res = substr ( $response, 4 ); // just ignore length, error handling, etc - $p = 0; - list ( $rows, $cols ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; - - $res = array(); - for ( $i=0; $i<$rows; $i++ ) - for ( $j=0; $j<$cols; $j++ ) - { - list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; - $res[$i][] = substr ( $response, $p, $len ); $p += $len; - } - - $this->_MBPop (); - return $res; - } - - ////////////////////////////////////////////////////////////////////////// - // flush - ////////////////////////////////////////////////////////////////////////// - - function FlushAttributes () - { - $this->_MBPush (); - if (!( $fp = $this->_Connect() )) - { - $this->_MBPop(); - return -1; - } - - $req = pack ( "nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0 ); // len=0 - if ( !( $this->_Send ( $fp, $req, 8 ) ) || - !( $response = $this->_GetResponse ( $fp, VER_COMMAND_FLUSHATTRS ) ) ) - { - $this->_MBPop (); - return -1; - } - - $tag = -1; - if ( strlen($response)==4 ) - list(,$tag) = unpack ( "N*", $response ); - else - $this->_error = "unexpected response length"; - - $this->_MBPop (); - return $tag; - } -} - -// -// $Id: sphinxapi.php 3087 2012-01-30 23:07:35Z shodan $ -// +=8 ) + { + $v = (int)$v; + return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); + } + + // x32, int + if ( is_int($v) ) + return pack ( "NN", $v < 0 ? -1 : 0, $v ); + + // x32, bcmath + if ( function_exists("bcmul") ) + { + if ( bccomp ( $v, 0 ) == -1 ) + $v = bcadd ( "18446744073709551616", $v ); + $h = bcdiv ( $v, "4294967296", 0 ); + $l = bcmod ( $v, "4294967296" ); + return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit + } + + // x32, no-bcmath + $p = max(0, strlen($v) - 13); + $lo = abs((float)substr($v, $p)); + $hi = abs((float)substr($v, 0, $p)); + + $m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912 + $q = floor($m/4294967296.0); + $l = $m - ($q*4294967296.0); + $h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328 + + if ( $v<0 ) + { + if ( $l==0 ) + $h = 4294967296.0 - $h; + else + { + $h = 4294967295.0 - $h; + $l = 4294967296.0 - $l; + } + } + return pack ( "NN", $h, $l ); +} + +/// pack 64-bit unsigned +function sphPackU64 ( $v ) +{ + assert ( is_numeric($v) ); + + // x64 + if ( PHP_INT_SIZE>=8 ) + { + assert ( $v>=0 ); + + // x64, int + if ( is_int($v) ) + return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); + + // x64, bcmath + if ( function_exists("bcmul") ) + { + $h = bcdiv ( $v, 4294967296, 0 ); + $l = bcmod ( $v, 4294967296 ); + return pack ( "NN", $h, $l ); + } + + // x64, no-bcmath + $p = max ( 0, strlen($v) - 13 ); + $lo = (int)substr ( $v, $p ); + $hi = (int)substr ( $v, 0, $p ); + + $m = $lo + $hi*1316134912; + $l = $m % 4294967296; + $h = $hi*2328 + (int)($m/4294967296); + + return pack ( "NN", $h, $l ); + } + + // x32, int + if ( is_int($v) ) + return pack ( "NN", 0, $v ); + + // x32, bcmath + if ( function_exists("bcmul") ) + { + $h = bcdiv ( $v, "4294967296", 0 ); + $l = bcmod ( $v, "4294967296" ); + return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit + } + + // x32, no-bcmath + $p = max(0, strlen($v) - 13); + $lo = (float)substr($v, $p); + $hi = (float)substr($v, 0, $p); + + $m = $lo + $hi*1316134912.0; + $q = floor($m / 4294967296.0); + $l = $m - ($q * 4294967296.0); + $h = $hi*2328.0 + $q; + + return pack ( "NN", $h, $l ); +} + +// unpack 64-bit unsigned +function sphUnpackU64 ( $v ) +{ + list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); + + if ( PHP_INT_SIZE>=8 ) + { + if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again + if ( $lo<0 ) $lo += (1<<32); + + // x64, int + if ( $hi<=2147483647 ) + return ($hi<<32) + $lo; + + // x64, bcmath + if ( function_exists("bcmul") ) + return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); + + // x64, no-bcmath + $C = 100000; + $h = ((int)($hi / $C) << 32) + (int)($lo / $C); + $l = (($hi % $C) << 32) + ($lo % $C); + if ( $l>$C ) + { + $h += (int)($l / $C); + $l = $l % $C; + } + + if ( $h==0 ) + return $l; + return sprintf ( "%d%05d", $h, $l ); + } + + // x32, int + if ( $hi==0 ) + { + if ( $lo>0 ) + return $lo; + return sprintf ( "%u", $lo ); + } + + $hi = sprintf ( "%u", $hi ); + $lo = sprintf ( "%u", $lo ); + + // x32, bcmath + if ( function_exists("bcmul") ) + return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); + + // x32, no-bcmath + $hi = (float)$hi; + $lo = (float)$lo; + + $q = floor($hi/10000000.0); + $r = $hi - $q*10000000.0; + $m = $lo + $r*4967296.0; + $mq = floor($m/10000000.0); + $l = $m - $mq*10000000.0; + $h = $q*4294967296.0 + $r*429.0 + $mq; + + $h = sprintf ( "%.0f", $h ); + $l = sprintf ( "%07.0f", $l ); + if ( $h=="0" ) + return sprintf( "%.0f", (float)$l ); + return $h . $l; +} + +// unpack 64-bit signed +function sphUnpackI64 ( $v ) +{ + list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); + + // x64 + if ( PHP_INT_SIZE>=8 ) + { + if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again + if ( $lo<0 ) $lo += (1<<32); + + return ($hi<<32) + $lo; + } + + // x32, int + if ( $hi==0 ) + { + if ( $lo>0 ) + return $lo; + return sprintf ( "%u", $lo ); + } + // x32, int + elseif ( $hi==-1 ) + { + if ( $lo<0 ) + return $lo; + return sprintf ( "%.0f", $lo - 4294967296.0 ); + } + + $neg = ""; + $c = 0; + if ( $hi<0 ) + { + $hi = ~$hi; + $lo = ~$lo; + $c = 1; + $neg = "-"; + } + + $hi = sprintf ( "%u", $hi ); + $lo = sprintf ( "%u", $lo ); + + // x32, bcmath + if ( function_exists("bcmul") ) + return $neg . bcadd ( bcadd ( $lo, bcmul ( $hi, "4294967296" ) ), $c ); + + // x32, no-bcmath + $hi = (float)$hi; + $lo = (float)$lo; + + $q = floor($hi/10000000.0); + $r = $hi - $q*10000000.0; + $m = $lo + $r*4967296.0; + $mq = floor($m/10000000.0); + $l = $m - $mq*10000000.0 + $c; + $h = $q*4294967296.0 + $r*429.0 + $mq; + if ( $l==10000000 ) + { + $l = 0; + $h += 1; + } + + $h = sprintf ( "%.0f", $h ); + $l = sprintf ( "%07.0f", $l ); + if ( $h=="0" ) + return $neg . sprintf( "%.0f", (float)$l ); + return $neg . $h . $l; +} + + +function sphFixUint ( $value ) +{ + if ( PHP_INT_SIZE>=8 ) + { + // x64 route, workaround broken unpack() in 5.2.2+ + if ( $value<0 ) $value += (1<<32); + return $value; + } + else + { + // x32 route, workaround php signed/unsigned braindamage + return sprintf ( "%u", $value ); + } +} + + +/// sphinx searchd client class +class SphinxClient +{ + var $_host; ///< searchd host (default is "localhost") + var $_port; ///< searchd port (default is 9312) + var $_offset; ///< how many records to seek from result-set start (default is 0) + var $_limit; ///< how many records to return from result-set starting at offset (default is 20) + var $_mode; ///< query matching mode (default is SPH_MATCH_ALL) + var $_weights; ///< per-field weights (default is 1 for all fields) + var $_sort; ///< match sorting mode (default is SPH_SORT_RELEVANCE) + var $_sortby; ///< attribute to sort by (defualt is "") + var $_min_id; ///< min ID to match (default is 0, which means no limit) + var $_max_id; ///< max ID to match (default is 0, which means no limit) + var $_filters; ///< search filters + var $_groupby; ///< group-by attribute name + var $_groupfunc; ///< group-by function (to pre-process group-by attribute value with) + var $_groupsort; ///< group-by sorting clause (to sort groups in result set with) + var $_groupdistinct;///< group-by count-distinct attribute + var $_maxmatches; ///< max matches to retrieve + var $_cutoff; ///< cutoff to stop searching at (default is 0) + var $_retrycount; ///< distributed retries count + var $_retrydelay; ///< distributed retries delay + var $_anchor; ///< geographical anchor point + var $_indexweights; ///< per-index weights + var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25) + var $_rankexpr; ///< ranking mode expression (for SPH_RANK_EXPR) + var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit) + var $_fieldweights; ///< per-field-name weights + var $_overrides; ///< per-query attribute values overrides + var $_select; ///< select-list (attributes or expressions, with optional aliases) + + var $_error; ///< last error message + var $_warning; ///< last warning message + var $_connerror; ///< connection error vs remote error flag + + var $_reqs; ///< requests array for multi-query + var $_mbenc; ///< stored mbstring encoding + var $_arrayresult; ///< whether $result["matches"] should be a hash or an array + var $_timeout; ///< connect timeout + + ///////////////////////////////////////////////////////////////////////////// + // common stuff + ///////////////////////////////////////////////////////////////////////////// + + /// create a new client object and fill defaults + function SphinxClient () + { + // per-client-object settings + $this->_host = "localhost"; + $this->_port = 9312; + $this->_path = false; + $this->_socket = false; + + // per-query settings + $this->_offset = 0; + $this->_limit = 20; + $this->_mode = SPH_MATCH_ALL; + $this->_weights = array (); + $this->_sort = SPH_SORT_RELEVANCE; + $this->_sortby = ""; + $this->_min_id = 0; + $this->_max_id = 0; + $this->_filters = array (); + $this->_groupby = ""; + $this->_groupfunc = SPH_GROUPBY_DAY; + $this->_groupsort = "@group desc"; + $this->_groupdistinct= ""; + $this->_maxmatches = 1000; + $this->_cutoff = 0; + $this->_retrycount = 0; + $this->_retrydelay = 0; + $this->_anchor = array (); + $this->_indexweights= array (); + $this->_ranker = SPH_RANK_PROXIMITY_BM25; + $this->_rankexpr = ""; + $this->_maxquerytime= 0; + $this->_fieldweights= array(); + $this->_overrides = array(); + $this->_select = "*"; + + $this->_error = ""; // per-reply fields (for single-query case) + $this->_warning = ""; + $this->_connerror = false; + + $this->_reqs = array (); // requests storage (for multi-query case) + $this->_mbenc = ""; + $this->_arrayresult = false; + $this->_timeout = 0; + } + + function __destruct() + { + if ( $this->_socket !== false ) + fclose ( $this->_socket ); + } + + /// get last error message (string) + function GetLastError () + { + return $this->_error; + } + + /// get last warning message (string) + function GetLastWarning () + { + return $this->_warning; + } + + /// get last error flag (to tell network connection errors from searchd errors or broken responses) + function IsConnectError() + { + return $this->_connerror; + } + + /// set searchd host name (string) and port (integer) + function SetServer ( $host, $port = 0 ) + { + assert ( is_string($host) ); + if ( $host[0] == '/') + { + $this->_path = 'unix://' . $host; + return; + } + if ( substr ( $host, 0, 7 )=="unix://" ) + { + $this->_path = $host; + return; + } + + assert ( is_int($port) ); + $this->_host = $host; + $this->_port = $port; + $this->_path = ''; + + } + + /// set server connection timeout (0 to remove) + function SetConnectTimeout ( $timeout ) + { + assert ( is_numeric($timeout) ); + $this->_timeout = $timeout; + } + + + function _Send ( $handle, $data, $length ) + { + if ( feof($handle) || fwrite ( $handle, $data, $length ) !== $length ) + { + $this->_error = 'connection unexpectedly closed (timed out?)'; + $this->_connerror = true; + return false; + } + return true; + } + + ///////////////////////////////////////////////////////////////////////////// + + /// enter mbstring workaround mode + function _MBPush () + { + $this->_mbenc = ""; + if ( ini_get ( "mbstring.func_overload" ) & 2 ) + { + $this->_mbenc = mb_internal_encoding(); + mb_internal_encoding ( "latin1" ); + } + } + + /// leave mbstring workaround mode + function _MBPop () + { + if ( $this->_mbenc ) + mb_internal_encoding ( $this->_mbenc ); + } + + /// connect to searchd server + function _Connect () + { + if ( $this->_socket!==false ) + { + // we are in persistent connection mode, so we have a socket + // however, need to check whether it's still alive + if ( !@feof ( $this->_socket ) ) + return $this->_socket; + + // force reopen + $this->_socket = false; + } + + $errno = 0; + $errstr = ""; + $this->_connerror = false; + + if ( $this->_path ) + { + $host = $this->_path; + $port = 0; + } + else + { + $host = $this->_host; + $port = $this->_port; + } + + if ( $this->_timeout<=0 ) + $fp = @fsockopen ( $host, $port, $errno, $errstr ); + else + $fp = @fsockopen ( $host, $port, $errno, $errstr, $this->_timeout ); + + if ( !$fp ) + { + if ( $this->_path ) + $location = $this->_path; + else + $location = "{$this->_host}:{$this->_port}"; + + $errstr = trim ( $errstr ); + $this->_error = "connection to $location failed (errno=$errno, msg=$errstr)"; + $this->_connerror = true; + return false; + } + + // send my version + // this is a subtle part. we must do it before (!) reading back from searchd. + // because otherwise under some conditions (reported on FreeBSD for instance) + // TCP stack could throttle write-write-read pattern because of Nagle. + if ( !$this->_Send ( $fp, pack ( "N", 1 ), 4 ) ) + { + fclose ( $fp ); + $this->_error = "failed to send client protocol version"; + return false; + } + + // check version + list(,$v) = unpack ( "N*", fread ( $fp, 4 ) ); + $v = (int)$v; + if ( $v<1 ) + { + fclose ( $fp ); + $this->_error = "expected searchd protocol version 1+, got version '$v'"; + return false; + } + + return $fp; + } + + /// get and check response packet from searchd server + function _GetResponse ( $fp, $client_ver ) + { + $response = ""; + $len = 0; + + $header = fread ( $fp, 8 ); + if ( strlen($header)==8 ) + { + list ( $status, $ver, $len ) = array_values ( unpack ( "n2a/Nb", $header ) ); + $left = $len; + while ( $left>0 && !feof($fp) ) + { + $chunk = fread ( $fp, min ( 8192, $left ) ); + if ( $chunk ) + { + $response .= $chunk; + $left -= strlen($chunk); + } + } + } + if ( $this->_socket === false ) + fclose ( $fp ); + + // check response + $read = strlen ( $response ); + if ( !$response || $read!=$len ) + { + $this->_error = $len + ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)" + : "received zero-sized searchd response"; + return false; + } + + // check status + if ( $status==SEARCHD_WARNING ) + { + list(,$wlen) = unpack ( "N*", substr ( $response, 0, 4 ) ); + $this->_warning = substr ( $response, 4, $wlen ); + return substr ( $response, 4+$wlen ); + } + if ( $status==SEARCHD_ERROR ) + { + $this->_error = "searchd error: " . substr ( $response, 4 ); + return false; + } + if ( $status==SEARCHD_RETRY ) + { + $this->_error = "temporary searchd error: " . substr ( $response, 4 ); + return false; + } + if ( $status!=SEARCHD_OK ) + { + $this->_error = "unknown status code '$status'"; + return false; + } + + // check version + if ( $ver<$client_ver ) + { + $this->_warning = sprintf ( "searchd command v.%d.%d older than client's v.%d.%d, some options might not work", + $ver>>8, $ver&0xff, $client_ver>>8, $client_ver&0xff ); + } + + return $response; + } + + ///////////////////////////////////////////////////////////////////////////// + // searching + ///////////////////////////////////////////////////////////////////////////// + + /// set offset and count into result set, + /// and optionally set max-matches and cutoff limits + function SetLimits ( $offset, $limit, $max=0, $cutoff=0 ) + { + assert ( is_int($offset) ); + assert ( is_int($limit) ); + assert ( $offset>=0 ); + assert ( $limit>0 ); + assert ( $max>=0 ); + $this->_offset = $offset; + $this->_limit = $limit; + if ( $max>0 ) + $this->_maxmatches = $max; + if ( $cutoff>0 ) + $this->_cutoff = $cutoff; + } + + /// set maximum query time, in milliseconds, per-index + /// integer, 0 means "do not limit" + function SetMaxQueryTime ( $max ) + { + assert ( is_int($max) ); + assert ( $max>=0 ); + $this->_maxquerytime = $max; + } + + /// set matching mode + function SetMatchMode ( $mode ) + { + assert ( $mode==SPH_MATCH_ALL + || $mode==SPH_MATCH_ANY + || $mode==SPH_MATCH_PHRASE + || $mode==SPH_MATCH_BOOLEAN + || $mode==SPH_MATCH_EXTENDED + || $mode==SPH_MATCH_FULLSCAN + || $mode==SPH_MATCH_EXTENDED2 ); + $this->_mode = $mode; + } + + /// set ranking mode + function SetRankingMode ( $ranker, $rankexpr="" ) + { + assert ( $ranker>=0 && $ranker_ranker = $ranker; + $this->_rankexpr = $rankexpr; + } + + /// set matches sorting mode + function SetSortMode ( $mode, $sortby="" ) + { + assert ( + $mode==SPH_SORT_RELEVANCE || + $mode==SPH_SORT_ATTR_DESC || + $mode==SPH_SORT_ATTR_ASC || + $mode==SPH_SORT_TIME_SEGMENTS || + $mode==SPH_SORT_EXTENDED || + $mode==SPH_SORT_EXPR ); + assert ( is_string($sortby) ); + assert ( $mode==SPH_SORT_RELEVANCE || strlen($sortby)>0 ); + + $this->_sort = $mode; + $this->_sortby = $sortby; + } + + /// bind per-field weights by order + /// DEPRECATED; use SetFieldWeights() instead + function SetWeights ( $weights ) + { + assert ( is_array($weights) ); + foreach ( $weights as $weight ) + assert ( is_int($weight) ); + + $this->_weights = $weights; + } + + /// bind per-field weights by name + function SetFieldWeights ( $weights ) + { + assert ( is_array($weights) ); + foreach ( $weights as $name=>$weight ) + { + assert ( is_string($name) ); + assert ( is_int($weight) ); + } + $this->_fieldweights = $weights; + } + + /// bind per-index weights by name + function SetIndexWeights ( $weights ) + { + assert ( is_array($weights) ); + foreach ( $weights as $index=>$weight ) + { + assert ( is_string($index) ); + assert ( is_int($weight) ); + } + $this->_indexweights = $weights; + } + + /// set IDs range to match + /// only match records if document ID is beetwen $min and $max (inclusive) + function SetIDRange ( $min, $max ) + { + assert ( is_numeric($min) ); + assert ( is_numeric($max) ); + assert ( $min<=$max ); + $this->_min_id = $min; + $this->_max_id = $max; + } + + /// set values set filter + /// only match records where $attribute value is in given set + function SetFilter ( $attribute, $values, $exclude=false ) + { + assert ( is_string($attribute) ); + assert ( is_array($values) ); + assert ( count($values) ); + + if ( is_array($values) && count($values) ) + { + foreach ( $values as $value ) + assert ( is_numeric($value) ); + + $this->_filters[] = array ( "type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values ); + } + } + + /// set range filter + /// only match records if $attribute value is beetwen $min and $max (inclusive) + function SetFilterRange ( $attribute, $min, $max, $exclude=false ) + { + assert ( is_string($attribute) ); + assert ( is_numeric($min) ); + assert ( is_numeric($max) ); + assert ( $min<=$max ); + + $this->_filters[] = array ( "type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); + } + + /// set float range filter + /// only match records if $attribute value is beetwen $min and $max (inclusive) + function SetFilterFloatRange ( $attribute, $min, $max, $exclude=false ) + { + assert ( is_string($attribute) ); + assert ( is_float($min) ); + assert ( is_float($max) ); + assert ( $min<=$max ); + + $this->_filters[] = array ( "type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); + } + + /// setup anchor point for geosphere distance calculations + /// required to use @geodist in filters and sorting + /// latitude and longitude must be in radians + function SetGeoAnchor ( $attrlat, $attrlong, $lat, $long ) + { + assert ( is_string($attrlat) ); + assert ( is_string($attrlong) ); + assert ( is_float($lat) ); + assert ( is_float($long) ); + + $this->_anchor = array ( "attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long ); + } + + /// set grouping attribute and function + function SetGroupBy ( $attribute, $func, $groupsort="@group desc" ) + { + assert ( is_string($attribute) ); + assert ( is_string($groupsort) ); + assert ( $func==SPH_GROUPBY_DAY + || $func==SPH_GROUPBY_WEEK + || $func==SPH_GROUPBY_MONTH + || $func==SPH_GROUPBY_YEAR + || $func==SPH_GROUPBY_ATTR + || $func==SPH_GROUPBY_ATTRPAIR ); + + $this->_groupby = $attribute; + $this->_groupfunc = $func; + $this->_groupsort = $groupsort; + } + + /// set count-distinct attribute for group-by queries + function SetGroupDistinct ( $attribute ) + { + assert ( is_string($attribute) ); + $this->_groupdistinct = $attribute; + } + + /// set distributed retries count and delay + function SetRetries ( $count, $delay=0 ) + { + assert ( is_int($count) && $count>=0 ); + assert ( is_int($delay) && $delay>=0 ); + $this->_retrycount = $count; + $this->_retrydelay = $delay; + } + + /// set result set format (hash or array; hash by default) + /// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs + function SetArrayResult ( $arrayresult ) + { + assert ( is_bool($arrayresult) ); + $this->_arrayresult = $arrayresult; + } + + /// set attribute values override + /// there can be only one override per attribute + /// $values must be a hash that maps document IDs to attribute values + function SetOverride ( $attrname, $attrtype, $values ) + { + assert ( is_string ( $attrname ) ); + assert ( in_array ( $attrtype, array ( SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT ) ) ); + assert ( is_array ( $values ) ); + + $this->_overrides[$attrname] = array ( "attr"=>$attrname, "type"=>$attrtype, "values"=>$values ); + } + + /// set select-list (attributes or expressions), SQL-like syntax + function SetSelect ( $select ) + { + assert ( is_string ( $select ) ); + $this->_select = $select; + } + + ////////////////////////////////////////////////////////////////////////////// + + /// clear all filters (for multi-queries) + function ResetFilters () + { + $this->_filters = array(); + $this->_anchor = array(); + } + + /// clear groupby settings (for multi-queries) + function ResetGroupBy () + { + $this->_groupby = ""; + $this->_groupfunc = SPH_GROUPBY_DAY; + $this->_groupsort = "@group desc"; + $this->_groupdistinct= ""; + } + + /// clear all attribute value overrides (for multi-queries) + function ResetOverrides () + { + $this->_overrides = array (); + } + + ////////////////////////////////////////////////////////////////////////////// + + /// connect to searchd server, run given search query through given indexes, + /// and return the search results + function Query ( $query, $index="*", $comment="" ) + { + assert ( empty($this->_reqs) ); + + $this->AddQuery ( $query, $index, $comment ); + $results = $this->RunQueries (); + $this->_reqs = array (); // just in case it failed too early + + if ( !is_array($results) ) + return false; // probably network error; error message should be already filled + + $this->_error = $results[0]["error"]; + $this->_warning = $results[0]["warning"]; + if ( $results[0]["status"]==SEARCHD_ERROR ) + return false; + else + return $results[0]; + } + + /// helper to pack floats in network byte order + function _PackFloat ( $f ) + { + $t1 = pack ( "f", $f ); // machine order + list(,$t2) = unpack ( "L*", $t1 ); // int in machine order + return pack ( "N", $t2 ); + } + + /// add query to multi-query batch + /// returns index into results array from RunQueries() call + function AddQuery ( $query, $index="*", $comment="" ) + { + // mbstring workaround + $this->_MBPush (); + + // build request + $req = pack ( "NNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker ); + if ( $this->_ranker==SPH_RANK_EXPR ) + $req .= pack ( "N", strlen($this->_rankexpr) ) . $this->_rankexpr; + $req .= pack ( "N", $this->_sort ); // (deprecated) sort mode + $req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby; + $req .= pack ( "N", strlen($query) ) . $query; // query itself + $req .= pack ( "N", count($this->_weights) ); // weights + foreach ( $this->_weights as $weight ) + $req .= pack ( "N", (int)$weight ); + $req .= pack ( "N", strlen($index) ) . $index; // indexes + $req .= pack ( "N", 1 ); // id64 range marker + $req .= sphPackU64 ( $this->_min_id ) . sphPackU64 ( $this->_max_id ); // id64 range + + // filters + $req .= pack ( "N", count($this->_filters) ); + foreach ( $this->_filters as $filter ) + { + $req .= pack ( "N", strlen($filter["attr"]) ) . $filter["attr"]; + $req .= pack ( "N", $filter["type"] ); + switch ( $filter["type"] ) + { + case SPH_FILTER_VALUES: + $req .= pack ( "N", count($filter["values"]) ); + foreach ( $filter["values"] as $value ) + $req .= sphPackI64 ( $value ); + break; + + case SPH_FILTER_RANGE: + $req .= sphPackI64 ( $filter["min"] ) . sphPackI64 ( $filter["max"] ); + break; + + case SPH_FILTER_FLOATRANGE: + $req .= $this->_PackFloat ( $filter["min"] ) . $this->_PackFloat ( $filter["max"] ); + break; + + default: + assert ( 0 && "internal error: unhandled filter type" ); + } + $req .= pack ( "N", $filter["exclude"] ); + } + + // group-by clause, max-matches count, group-sort clause, cutoff count + $req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby; + $req .= pack ( "N", $this->_maxmatches ); + $req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort; + $req .= pack ( "NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay ); + $req .= pack ( "N", strlen($this->_groupdistinct) ) . $this->_groupdistinct; + + // anchor point + if ( empty($this->_anchor) ) + { + $req .= pack ( "N", 0 ); + } else + { + $a =& $this->_anchor; + $req .= pack ( "N", 1 ); + $req .= pack ( "N", strlen($a["attrlat"]) ) . $a["attrlat"]; + $req .= pack ( "N", strlen($a["attrlong"]) ) . $a["attrlong"]; + $req .= $this->_PackFloat ( $a["lat"] ) . $this->_PackFloat ( $a["long"] ); + } + + // per-index weights + $req .= pack ( "N", count($this->_indexweights) ); + foreach ( $this->_indexweights as $idx=>$weight ) + $req .= pack ( "N", strlen($idx) ) . $idx . pack ( "N", $weight ); + + // max query time + $req .= pack ( "N", $this->_maxquerytime ); + + // per-field weights + $req .= pack ( "N", count($this->_fieldweights) ); + foreach ( $this->_fieldweights as $field=>$weight ) + $req .= pack ( "N", strlen($field) ) . $field . pack ( "N", $weight ); + + // comment + $req .= pack ( "N", strlen($comment) ) . $comment; + + // attribute overrides + $req .= pack ( "N", count($this->_overrides) ); + foreach ( $this->_overrides as $key => $entry ) + { + $req .= pack ( "N", strlen($entry["attr"]) ) . $entry["attr"]; + $req .= pack ( "NN", $entry["type"], count($entry["values"]) ); + foreach ( $entry["values"] as $id=>$val ) + { + assert ( is_numeric($id) ); + assert ( is_numeric($val) ); + + $req .= sphPackU64 ( $id ); + switch ( $entry["type"] ) + { + case SPH_ATTR_FLOAT: $req .= $this->_PackFloat ( $val ); break; + case SPH_ATTR_BIGINT: $req .= sphPackI64 ( $val ); break; + default: $req .= pack ( "N", $val ); break; + } + } + } + + // select-list + $req .= pack ( "N", strlen($this->_select) ) . $this->_select; + + // mbstring workaround + $this->_MBPop (); + + // store request to requests array + $this->_reqs[] = $req; + return count($this->_reqs)-1; + } + + /// connect to searchd, run queries batch, and return an array of result sets + function RunQueries () + { + if ( empty($this->_reqs) ) + { + $this->_error = "no queries defined, issue AddQuery() first"; + return false; + } + + // mbstring workaround + $this->_MBPush (); + + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop (); + return false; + } + + // send query, get response + $nreqs = count($this->_reqs); + $req = join ( "", $this->_reqs ); + $len = 8+strlen($req); + $req = pack ( "nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs ) . $req; // add header + + if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || + !( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ) ) + { + $this->_MBPop (); + return false; + } + + // query sent ok; we can reset reqs now + $this->_reqs = array (); + + // parse and return response + return $this->_ParseSearchResponse ( $response, $nreqs ); + } + + /// parse and return search query (or queries) response + function _ParseSearchResponse ( $response, $nreqs ) + { + $p = 0; // current position + $max = strlen($response); // max position for checks, to protect against broken responses + + $results = array (); + for ( $ires=0; $ires<$nreqs && $p<$max; $ires++ ) + { + $results[] = array(); + $result =& $results[$ires]; + + $result["error"] = ""; + $result["warning"] = ""; + + // extract status + list(,$status) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $result["status"] = $status; + if ( $status!=SEARCHD_OK ) + { + list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $message = substr ( $response, $p, $len ); $p += $len; + + if ( $status==SEARCHD_WARNING ) + { + $result["warning"] = $message; + } else + { + $result["error"] = $message; + continue; + } + } + + // read schema + $fields = array (); + $attrs = array (); + + list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + while ( $nfields-->0 && $p<$max ) + { + list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $fields[] = substr ( $response, $p, $len ); $p += $len; + } + $result["fields"] = $fields; + + list(,$nattrs) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + while ( $nattrs-->0 && $p<$max ) + { + list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $attr = substr ( $response, $p, $len ); $p += $len; + list(,$type) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $attrs[$attr] = $type; + } + $result["attrs"] = $attrs; + + // read match count + list(,$count) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + list(,$id64) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + + // read matches + $idx = -1; + while ( $count-->0 && $p<$max ) + { + // index into result array + $idx++; + + // parse document id and weight + if ( $id64 ) + { + $doc = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8; + list(,$weight) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + } + else + { + list ( $doc, $weight ) = array_values ( unpack ( "N*N*", + substr ( $response, $p, 8 ) ) ); + $p += 8; + $doc = sphFixUint($doc); + } + $weight = sprintf ( "%u", $weight ); + + // create match entry + if ( $this->_arrayresult ) + $result["matches"][$idx] = array ( "id"=>$doc, "weight"=>$weight ); + else + $result["matches"][$doc]["weight"] = $weight; + + // parse and create attributes + $attrvals = array (); + foreach ( $attrs as $attr=>$type ) + { + // handle 64bit ints + if ( $type==SPH_ATTR_BIGINT ) + { + $attrvals[$attr] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8; + continue; + } + + // handle floats + if ( $type==SPH_ATTR_FLOAT ) + { + list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + list(,$fval) = unpack ( "f*", pack ( "L", $uval ) ); + $attrvals[$attr] = $fval; + continue; + } + + // handle everything else as unsigned ints + list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + if ( $type==SPH_ATTR_MULTI ) + { + $attrvals[$attr] = array (); + $nvalues = $val; + while ( $nvalues-->0 && $p<$max ) + { + list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $attrvals[$attr][] = sphFixUint($val); + } + } else if ( $type==SPH_ATTR_MULTI64 ) + { + $attrvals[$attr] = array (); + $nvalues = $val; + while ( $nvalues>0 && $p<$max ) + { + $attrvals[$attr][] = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8; + $nvalues -= 2; + } + } else if ( $type==SPH_ATTR_STRING ) + { + $attrvals[$attr] = substr ( $response, $p, $val ); + $p += $val; + } else + { + $attrvals[$attr] = sphFixUint($val); + } + } + + if ( $this->_arrayresult ) + $result["matches"][$idx]["attrs"] = $attrvals; + else + $result["matches"][$doc]["attrs"] = $attrvals; + } + + list ( $total, $total_found, $msecs, $words ) = + array_values ( unpack ( "N*N*N*N*", substr ( $response, $p, 16 ) ) ); + $result["total"] = sprintf ( "%u", $total ); + $result["total_found"] = sprintf ( "%u", $total_found ); + $result["time"] = sprintf ( "%.3f", $msecs/1000 ); + $p += 16; + + while ( $words-->0 && $p<$max ) + { + list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $word = substr ( $response, $p, $len ); $p += $len; + list ( $docs, $hits ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; + $result["words"][$word] = array ( + "docs"=>sprintf ( "%u", $docs ), + "hits"=>sprintf ( "%u", $hits ) ); + } + } + + $this->_MBPop (); + return $results; + } + + ///////////////////////////////////////////////////////////////////////////// + // excerpts generation + ///////////////////////////////////////////////////////////////////////////// + + /// connect to searchd server, and generate exceprts (snippets) + /// of given documents for given query. returns false on failure, + /// an array of snippets on success + function BuildExcerpts ( $docs, $index, $words, $opts=array() ) + { + assert ( is_array($docs) ); + assert ( is_string($index) ); + assert ( is_string($words) ); + assert ( is_array($opts) ); + + $this->_MBPush (); + + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop(); + return false; + } + + ///////////////// + // fixup options + ///////////////// + + if ( !isset($opts["before_match"]) ) $opts["before_match"] = ""; + if ( !isset($opts["after_match"]) ) $opts["after_match"] = ""; + if ( !isset($opts["chunk_separator"]) ) $opts["chunk_separator"] = " ... "; + if ( !isset($opts["limit"]) ) $opts["limit"] = 256; + if ( !isset($opts["limit_passages"]) ) $opts["limit_passages"] = 0; + if ( !isset($opts["limit_words"]) ) $opts["limit_words"] = 0; + if ( !isset($opts["around"]) ) $opts["around"] = 5; + if ( !isset($opts["exact_phrase"]) ) $opts["exact_phrase"] = false; + if ( !isset($opts["single_passage"]) ) $opts["single_passage"] = false; + if ( !isset($opts["use_boundaries"]) ) $opts["use_boundaries"] = false; + if ( !isset($opts["weight_order"]) ) $opts["weight_order"] = false; + if ( !isset($opts["query_mode"]) ) $opts["query_mode"] = false; + if ( !isset($opts["force_all_words"]) ) $opts["force_all_words"] = false; + if ( !isset($opts["start_passage_id"]) ) $opts["start_passage_id"] = 1; + if ( !isset($opts["load_files"]) ) $opts["load_files"] = false; + if ( !isset($opts["html_strip_mode"]) ) $opts["html_strip_mode"] = "index"; + if ( !isset($opts["allow_empty"]) ) $opts["allow_empty"] = false; + if ( !isset($opts["passage_boundary"]) ) $opts["passage_boundary"] = "none"; + if ( !isset($opts["emit_zones"]) ) $opts["emit_zones"] = false; + if ( !isset($opts["load_files_scattered"]) ) $opts["load_files_scattered"] = false; + + + ///////////////// + // build request + ///////////////// + + // v.1.2 req + $flags = 1; // remove spaces + if ( $opts["exact_phrase"] ) $flags |= 2; + if ( $opts["single_passage"] ) $flags |= 4; + if ( $opts["use_boundaries"] ) $flags |= 8; + if ( $opts["weight_order"] ) $flags |= 16; + if ( $opts["query_mode"] ) $flags |= 32; + if ( $opts["force_all_words"] ) $flags |= 64; + if ( $opts["load_files"] ) $flags |= 128; + if ( $opts["allow_empty"] ) $flags |= 256; + if ( $opts["emit_zones"] ) $flags |= 512; + if ( $opts["load_files_scattered"] ) $flags |= 1024; + $req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags + $req .= pack ( "N", strlen($index) ) . $index; // req index + $req .= pack ( "N", strlen($words) ) . $words; // req words + + // options + $req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"]; + $req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"]; + $req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"]; + $req .= pack ( "NN", (int)$opts["limit"], (int)$opts["around"] ); + $req .= pack ( "NNN", (int)$opts["limit_passages"], (int)$opts["limit_words"], (int)$opts["start_passage_id"] ); // v.1.2 + $req .= pack ( "N", strlen($opts["html_strip_mode"]) ) . $opts["html_strip_mode"]; + $req .= pack ( "N", strlen($opts["passage_boundary"]) ) . $opts["passage_boundary"]; + + // documents + $req .= pack ( "N", count($docs) ); + foreach ( $docs as $doc ) + { + assert ( is_string($doc) ); + $req .= pack ( "N", strlen($doc) ) . $doc; + } + + //////////////////////////// + // send query, get response + //////////////////////////// + + $len = strlen($req); + $req = pack ( "nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len ) . $req; // add header + if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || + !( $response = $this->_GetResponse ( $fp, VER_COMMAND_EXCERPT ) ) ) + { + $this->_MBPop (); + return false; + } + + ////////////////// + // parse response + ////////////////// + + $pos = 0; + $res = array (); + $rlen = strlen($response); + for ( $i=0; $i $rlen ) + { + $this->_error = "incomplete reply"; + $this->_MBPop (); + return false; + } + $res[] = $len ? substr ( $response, $pos, $len ) : ""; + $pos += $len; + } + + $this->_MBPop (); + return $res; + } + + + ///////////////////////////////////////////////////////////////////////////// + // keyword generation + ///////////////////////////////////////////////////////////////////////////// + + /// connect to searchd server, and generate keyword list for a given query + /// returns false on failure, + /// an array of words on success + function BuildKeywords ( $query, $index, $hits ) + { + assert ( is_string($query) ); + assert ( is_string($index) ); + assert ( is_bool($hits) ); + + $this->_MBPush (); + + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop(); + return false; + } + + ///////////////// + // build request + ///////////////// + + // v.1.0 req + $req = pack ( "N", strlen($query) ) . $query; // req query + $req .= pack ( "N", strlen($index) ) . $index; // req index + $req .= pack ( "N", (int)$hits ); + + //////////////////////////// + // send query, get response + //////////////////////////// + + $len = strlen($req); + $req = pack ( "nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len ) . $req; // add header + if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || + !( $response = $this->_GetResponse ( $fp, VER_COMMAND_KEYWORDS ) ) ) + { + $this->_MBPop (); + return false; + } + + ////////////////// + // parse response + ////////////////// + + $pos = 0; + $res = array (); + $rlen = strlen($response); + list(,$nwords) = unpack ( "N*", substr ( $response, $pos, 4 ) ); + $pos += 4; + for ( $i=0; $i<$nwords; $i++ ) + { + list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; + $tokenized = $len ? substr ( $response, $pos, $len ) : ""; + $pos += $len; + + list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; + $normalized = $len ? substr ( $response, $pos, $len ) : ""; + $pos += $len; + + $res[] = array ( "tokenized"=>$tokenized, "normalized"=>$normalized ); + + if ( $hits ) + { + list($ndocs,$nhits) = array_values ( unpack ( "N*N*", substr ( $response, $pos, 8 ) ) ); + $pos += 8; + $res [$i]["docs"] = $ndocs; + $res [$i]["hits"] = $nhits; + } + + if ( $pos > $rlen ) + { + $this->_error = "incomplete reply"; + $this->_MBPop (); + return false; + } + } + + $this->_MBPop (); + return $res; + } + + function EscapeString ( $string ) + { + $from = array ( '\\', '(',')','|','-','!','@','~','"','&', '/', '^', '$', '=' ); + $to = array ( '\\\\', '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/', '\^', '\$', '\=' ); + + return str_replace ( $from, $to, $string ); + } + + ///////////////////////////////////////////////////////////////////////////// + // attribute updates + ///////////////////////////////////////////////////////////////////////////// + + /// batch update given attributes in given rows in given indexes + /// returns amount of updated documents (0 or more) on success, or -1 on failure + function UpdateAttributes ( $index, $attrs, $values, $mva=false ) + { + // verify everything + assert ( is_string($index) ); + assert ( is_bool($mva) ); + + assert ( is_array($attrs) ); + foreach ( $attrs as $attr ) + assert ( is_string($attr) ); + + assert ( is_array($values) ); + foreach ( $values as $id=>$entry ) + { + assert ( is_numeric($id) ); + assert ( is_array($entry) ); + assert ( count($entry)==count($attrs) ); + foreach ( $entry as $v ) + { + if ( $mva ) + { + assert ( is_array($v) ); + foreach ( $v as $vv ) + assert ( is_int($vv) ); + } else + assert ( is_int($v) ); + } + } + + // build request + $this->_MBPush (); + $req = pack ( "N", strlen($index) ) . $index; + + $req .= pack ( "N", count($attrs) ); + foreach ( $attrs as $attr ) + { + $req .= pack ( "N", strlen($attr) ) . $attr; + $req .= pack ( "N", $mva ? 1 : 0 ); + } + + $req .= pack ( "N", count($values) ); + foreach ( $values as $id=>$entry ) + { + $req .= sphPackU64 ( $id ); + foreach ( $entry as $v ) + { + $req .= pack ( "N", $mva ? count($v) : $v ); + if ( $mva ) + foreach ( $v as $vv ) + $req .= pack ( "N", $vv ); + } + } + + // connect, send query, get response + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop (); + return -1; + } + + $len = strlen($req); + $req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header + if ( !$this->_Send ( $fp, $req, $len+8 ) ) + { + $this->_MBPop (); + return -1; + } + + if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) )) + { + $this->_MBPop (); + return -1; + } + + // parse response + list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) ); + $this->_MBPop (); + return $updated; + } + + ///////////////////////////////////////////////////////////////////////////// + // persistent connections + ///////////////////////////////////////////////////////////////////////////// + + function Open() + { + if ( $this->_socket !== false ) + { + $this->_error = 'already connected'; + return false; + } + if ( !$fp = $this->_Connect() ) + return false; + + // command, command version = 0, body length = 4, body = 1 + $req = pack ( "nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1 ); + if ( !$this->_Send ( $fp, $req, 12 ) ) + return false; + + $this->_socket = $fp; + return true; + } + + function Close() + { + if ( $this->_socket === false ) + { + $this->_error = 'not connected'; + return false; + } + + fclose ( $this->_socket ); + $this->_socket = false; + + return true; + } + + ////////////////////////////////////////////////////////////////////////// + // status + ////////////////////////////////////////////////////////////////////////// + + function Status () + { + $this->_MBPush (); + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop(); + return false; + } + + $req = pack ( "nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1 ); // len=4, body=1 + if ( !( $this->_Send ( $fp, $req, 12 ) ) || + !( $response = $this->_GetResponse ( $fp, VER_COMMAND_STATUS ) ) ) + { + $this->_MBPop (); + return false; + } + + $res = substr ( $response, 4 ); // just ignore length, error handling, etc + $p = 0; + list ( $rows, $cols ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; + + $res = array(); + for ( $i=0; $i<$rows; $i++ ) + for ( $j=0; $j<$cols; $j++ ) + { + list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; + $res[$i][] = substr ( $response, $p, $len ); $p += $len; + } + + $this->_MBPop (); + return $res; + } + + ////////////////////////////////////////////////////////////////////////// + // flush + ////////////////////////////////////////////////////////////////////////// + + function FlushAttributes () + { + $this->_MBPush (); + if (!( $fp = $this->_Connect() )) + { + $this->_MBPop(); + return -1; + } + + $req = pack ( "nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0 ); // len=0 + if ( !( $this->_Send ( $fp, $req, 8 ) ) || + !( $response = $this->_GetResponse ( $fp, VER_COMMAND_FLUSHATTRS ) ) ) + { + $this->_MBPop (); + return -1; + } + + $tag = -1; + if ( strlen($response)==4 ) + list(,$tag) = unpack ( "N*", $response ); + else + $this->_error = "unexpected response length"; + + $this->_MBPop (); + return $tag; + } +} + +// +// $Id: sphinxapi.php 3087 2012-01-30 23:07:35Z shodan $ +// -- cgit v1.2.1 From 6dee2539419ba2c050830b7677294603a63b559a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Dec 2012 17:01:08 -0600 Subject: [ticket/11259] Make phpbb_admin_path available everywhere PHPBB3-11259 --- phpBB/includes/db/dbal.php | 4 ++-- phpBB/includes/functions.php | 4 ++-- phpBB/includes/functions_install.php | 3 +++ phpBB/includes/ucp/ucp_groups.php | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index ef1dd7d14d..c2708b09b2 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -822,7 +822,7 @@ class dbal */ function sql_report($mode, $query = '') { - global $cache, $starttime, $phpbb_root_path, $user; + global $cache, $starttime, $phpbb_root_path, $phpbb_admin_path, $user; global $request; if (is_object($request) && !$request->variable('explain', false)) @@ -852,7 +852,7 @@ class dbal SQL Report - +
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e492f97022..5fa5c5f505 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5339,7 +5339,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 function page_footer($run_cron = true, $display_template = true, $exit_handler = true) { global $db, $config, $template, $user, $auth, $cache, $starttime, $phpbb_root_path, $phpEx; - global $request, $phpbb_dispatcher; + global $request, $phpbb_dispatcher, $phpbb_admin_path; // A listener can set this variable to `true` when it overrides this function $page_footer_override = false; @@ -5395,7 +5395,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler = 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'CREDIT_LINE' => $user->lang('POWERED_BY', 'phpBB® Forum Software © phpBB Group'), - 'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_root_path}adm/index.$phpEx", false, true, $user->session_id) : '') + 'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id) : '') ); // Call cron-type script diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index ab6b3ea009..1218ac401b 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -515,6 +515,9 @@ function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_test 'dbuser' => $data['dbuser'], 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), 'table_prefix' => $data['table_prefix'], + + 'adm_relative_path' => 'adm/', + 'acm_type' => 'phpbb_cache_driver_file', ); diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 9652986cf2..d92aea91f8 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -25,7 +25,7 @@ class ucp_groups function main($id, $mode) { - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $phpbb_admin_path; global $db, $user, $auth, $cache, $template; global $request; @@ -438,7 +438,7 @@ class ucp_groups $group_name = $group_row['group_name']; $group_type = $group_row['group_type']; - $avatar_img = (!empty($group_row['group_avatar'])) ? get_user_avatar($group_row['group_avatar'], $group_row['group_avatar_type'], $group_row['group_avatar_width'], $group_row['group_avatar_height'], 'GROUP_AVATAR') : ''; + $avatar_img = (!empty($group_row['group_avatar'])) ? get_user_avatar($group_row['group_avatar'], $group_row['group_avatar_type'], $group_row['group_avatar_width'], $group_row['group_avatar_height'], 'GROUP_AVATAR') : ''; $template->assign_vars(array( 'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name, @@ -730,7 +730,7 @@ class ucp_groups 'GROUP_CLOSED' => $type_closed, 'GROUP_HIDDEN' => $type_hidden, - 'U_SWATCH' => append_sid("{$phpbb_root_path}adm/swatch.$phpEx", 'form=ucp&name=group_colour'), + 'U_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=ucp&name=group_colour'), 'S_UCP_ACTION' => $this->u_action . "&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(), )); -- cgit v1.2.1 From bff76f9ca81e30a03f116669645774ebd49ba1b1 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Dec 2012 17:05:12 -0600 Subject: [ticket/11259] Also make adm_relative_path available in the container PHPBB3-11259 --- phpBB/includes/di/extension/config.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/di/extension/config.php b/phpBB/includes/di/extension/config.php index fb5ca90070..bb3c04637a 100644 --- a/phpBB/includes/di/extension/config.php +++ b/phpBB/includes/di/extension/config.php @@ -42,6 +42,7 @@ class phpbb_di_extension_config extends Extension { require($this->config_file); + $container->setParameter('core.adm_relative_path', (isset($adm_relative_path) ? $adm_relative_path : 'adm/')); $container->setParameter('core.table_prefix', $table_prefix); $container->setParameter('cache.driver.class', $this->fix_acm_type($acm_type)); $container->setParameter('dbal.driver.class', 'dbal_'.$dbms); -- cgit v1.2.1 From 30de17f69f70a0c23fa314de479bac57e3dbae2b Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Dec 2012 19:29:51 -0600 Subject: [ticket/11259] adm_relative_path -> phpbb_adm_relative_path We can assume they properly format their config settings, right? PHPBB3-11259 --- phpBB/includes/di/extension/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/di/extension/config.php b/phpBB/includes/di/extension/config.php index bb3c04637a..59b4c66870 100644 --- a/phpBB/includes/di/extension/config.php +++ b/phpBB/includes/di/extension/config.php @@ -42,7 +42,7 @@ class phpbb_di_extension_config extends Extension { require($this->config_file); - $container->setParameter('core.adm_relative_path', (isset($adm_relative_path) ? $adm_relative_path : 'adm/')); + $container->setParameter('core.adm_relative_path', (isset($phpbb_adm_relative_path) ? $phpbb_adm_relative_path : 'adm/')); $container->setParameter('core.table_prefix', $table_prefix); $container->setParameter('cache.driver.class', $this->fix_acm_type($acm_type)); $container->setParameter('dbal.driver.class', 'dbal_'.$dbms); -- cgit v1.2.1 From 61391f648c95251466f805f148f1656e940f2027 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Dec 2012 21:16:08 -0600 Subject: [ticket/11259] htmlspecialchars($phpbb_admin_path) PHPBB3-11259 --- phpBB/includes/acp/acp_ranks.php | 14 +++++++------- phpBB/includes/db/dbal.php | 2 +- phpBB/includes/functions_acp.php | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php index d9ed5b17f1..6b06d03f52 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -71,7 +71,7 @@ class acp_ranks 'rank_min' => $min_posts, 'rank_image' => htmlspecialchars_decode($rank_image) ); - + if ($rank_id) { $sql = 'UPDATE ' . RANKS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE rank_id = $rank_id"; @@ -122,7 +122,7 @@ class acp_ranks $cache->destroy('_ranks'); add_log('admin', 'LOG_RANK_REMOVED', $rank_title); - + if ($request->is_ajax()) { $json_response = new phpbb_json_response; @@ -151,7 +151,7 @@ class acp_ranks case 'add': $data = $ranks = $existing_imgs = array(); - + $sql = 'SELECT * FROM ' . RANKS_TABLE . ' ORDER BY rank_min ASC, rank_special ASC'; @@ -209,17 +209,17 @@ class acp_ranks 'RANK_TITLE' => (isset($ranks['rank_title'])) ? $ranks['rank_title'] : '', 'S_FILENAME_LIST' => $filename_list, - 'RANK_IMAGE' => ($edit_img) ? $phpbb_root_path . $config['ranks_path'] . '/' . $edit_img : $phpbb_admin_path . 'images/spacer.gif', + 'RANK_IMAGE' => ($edit_img) ? $phpbb_root_path . $config['ranks_path'] . '/' . $edit_img : htmlspecialchars($phpbb_admin_path) . 'images/spacer.gif', 'S_SPECIAL_RANK' => (isset($ranks['rank_special']) && $ranks['rank_special']) ? true : false, 'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0) ); - + return; break; } - + $template->assign_vars(array( 'U_ACTION' => $this->u_action) ); @@ -241,7 +241,7 @@ class acp_ranks 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['rank_id'], 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['rank_id']) - ); + ); } $db->sql_freeresult($result); diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index c2708b09b2..c6a3638f9f 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -852,7 +852,7 @@ class dbal SQL Report - +
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 2f3fd7bac0..32fd76e74d 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -82,16 +82,16 @@ function adm_page_header($page_title) 'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/", - 'ICON_MOVE_UP' => '' . $user->lang['MOVE_UP'] . '', - 'ICON_MOVE_UP_DISABLED' => '' . $user->lang['MOVE_UP'] . '', - 'ICON_MOVE_DOWN' => '' . $user->lang['MOVE_DOWN'] . '', - 'ICON_MOVE_DOWN_DISABLED' => '' . $user->lang['MOVE_DOWN'] . '', - 'ICON_EDIT' => '' . $user->lang['EDIT'] . '', - 'ICON_EDIT_DISABLED' => '' . $user->lang['EDIT'] . '', - 'ICON_DELETE' => '' . $user->lang['DELETE'] . '', - 'ICON_DELETE_DISABLED' => '' . $user->lang['DELETE'] . '', - 'ICON_SYNC' => '' . $user->lang['RESYNC'] . '', - 'ICON_SYNC_DISABLED' => '' . $user->lang['RESYNC'] . '', + 'ICON_MOVE_UP' => '' . $user->lang['MOVE_UP'] . '', + 'ICON_MOVE_UP_DISABLED' => '' . $user->lang['MOVE_UP'] . '', + 'ICON_MOVE_DOWN' => '' . $user->lang['MOVE_DOWN'] . '', + 'ICON_MOVE_DOWN_DISABLED' => '' . $user->lang['MOVE_DOWN'] . '', + 'ICON_EDIT' => '' . $user->lang['EDIT'] . '', + 'ICON_EDIT_DISABLED' => '' . $user->lang['EDIT'] . '', + 'ICON_DELETE' => '' . $user->lang['DELETE'] . '', + 'ICON_DELETE_DISABLED' => '' . $user->lang['DELETE'] . '', + 'ICON_SYNC' => '' . $user->lang['RESYNC'] . '', + 'ICON_SYNC_DISABLED' => '' . $user->lang['RESYNC'] . '', 'S_USER_LANG' => $user->lang['USER_LANG'], 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], -- cgit v1.2.1 From 7ce009f2e29045b2bd29dd670c900b79f7f3bd70 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 12 Dec 2012 12:46:20 +0100 Subject: [ticket/10954] Mark forums read without popup or page refresh PHPBB3-10954 --- phpBB/includes/functions_display.php | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 73129803ee..9745d493c4 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -61,10 +61,23 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod { markread('all', false, false, request_var('mark_time', 0)); - trigger_error( - $user->lang['FORUMS_MARKED'] . '

' . - sprintf($user->lang['RETURN_INDEX'], '', '') - ); + if (!$request->is_ajax()) + { + trigger_error( + $user->lang['FORUMS_MARKED'] . '

' . + sprintf($user->lang['RETURN_INDEX'], '', '') + ); + } + else + { + // Tell the ajax script what language vars need to be replaced + $data = array( + 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], + 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'] + ); + $json_response = new phpbb_json_response(); + $json_response->send($data); + } } else { @@ -313,7 +326,20 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $message = sprintf($user->lang['RETURN_FORUM'], '', ''); meta_refresh(3, $redirect); - trigger_error($user->lang['FORUMS_MARKED'] . '

' . $message); + if (!$request->is_ajax()) + { + trigger_error($user->lang['FORUMS_MARKED'] . '

' . $message); + } + else + { + // Tell the ajax script what language vars need to be replaced + $data = array( + 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], + 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'] + ); + $json_response = new phpbb_json_response(); + $json_response->send($data); + } } else { -- cgit v1.2.1 From 7efc37d1f9d4a4335fc91af147cd059c17b7d45e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 12 Dec 2012 19:09:18 +0100 Subject: [ticket/10954] Modify is_ajax check for consistency PHPBB3-10954 --- phpBB/includes/functions_display.php | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 9745d493c4..f3198bc1e5 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -61,14 +61,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod { markread('all', false, false, request_var('mark_time', 0)); - if (!$request->is_ajax()) - { - trigger_error( - $user->lang['FORUMS_MARKED'] . '

' . - sprintf($user->lang['RETURN_INDEX'], '', '') - ); - } - else + if ($request->is_ajax()) { // Tell the ajax script what language vars need to be replaced $data = array( @@ -78,6 +71,11 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $json_response = new phpbb_json_response(); $json_response->send($data); } + + trigger_error( + $user->lang['FORUMS_MARKED'] . '

' . + sprintf($user->lang['RETURN_INDEX'], '', '') + ); } else { @@ -326,11 +324,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $message = sprintf($user->lang['RETURN_FORUM'], '', ''); meta_refresh(3, $redirect); - if (!$request->is_ajax()) - { - trigger_error($user->lang['FORUMS_MARKED'] . '

' . $message); - } - else + if ($request->is_ajax()) { // Tell the ajax script what language vars need to be replaced $data = array( @@ -340,6 +334,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $json_response = new phpbb_json_response(); $json_response->send($data); } + + trigger_error($user->lang['FORUMS_MARKED'] . '

' . $message); } else { -- cgit v1.2.1 From abcc59fca6bd5d899adbec248ba60db6c013e6a2 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 3 Sep 2012 15:10:08 -0500 Subject: [ticket/8610] Update Bookmarks when merging topics Update bookmarks to the new topic when merging multiple topics using the merge_topics function. PHPBB3-8610 --- phpBB/includes/mcp/mcp_forum.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index b70601b479..865e464e81 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -422,6 +422,14 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) $db->sql_query('DELETE FROM ' . TOPICS_WATCH_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + // If the topic no longer exist, we will update the bookmarks table. + // To not let it error out on users who bookmarked both topics, we just return on an error... + $db->sql_return_on_error(true); + $db->sql_query('UPDATE ' . BOOKMARKS_TABLE . ' SET topic_id = ' . (int) $to_topic_id . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + $db->sql_return_on_error(false); + + $db->sql_query('DELETE FROM ' . BOOKMARKS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + // Link to the new topic $return_link .= (($return_link) ? '

' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '', ''); } @@ -444,4 +452,4 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) } } -?> \ No newline at end of file +?> -- cgit v1.2.1 From 8dd2a151cc53a5482fcf462736cf5c2eabccf599 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 3 Sep 2012 15:18:30 -0500 Subject: [ticket/8610] Update Bookmarks when forking topics Update bookmarks to the new topic when forking topics using the mcp_fork_topic function. PHPBB3-8610 --- phpBB/includes/mcp/mcp_main.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index ffede11d37..f7c49539ea 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1251,6 +1251,26 @@ function mcp_fork_topic($topic_ids) { $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary); } + + $sql = 'SELECT user_id + FROM ' . BOOKMARKS_TABLE . ' + WHERE topic_id = ' . $topic_id; + $result = $db->sql_query($sql); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary[] = array( + 'topic_id' => (int) $new_topic_id, + 'user_id' => (int) $row['user_id'], + ); + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert(BOOKMARKS_TABLE, $sql_ary); + } } // Sync new topics, parent forums and board stats @@ -1314,4 +1334,4 @@ function mcp_fork_topic($topic_ids) } } -?> \ No newline at end of file +?> -- cgit v1.2.1 From 05d7decdd35eac3b58807b9ced318421a6ce15da Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 3 Sep 2012 15:30:52 -0500 Subject: [ticket/8610] Update Bookmarks when merging posts into another topic Update bookmarks to the new topic when merging posts into another topic using the merge_posts function. PHPBB3-8610 --- phpBB/includes/mcp/mcp_topic.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 7d4edaf362..36cfe1e355 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -626,6 +626,14 @@ function merge_posts($topic_id, $to_topic_id) $db->sql_return_on_error(false); $db->sql_query('DELETE FROM ' . TOPICS_WATCH_TABLE . ' WHERE topic_id = ' . (int) $topic_id); + + // If the topic no longer exist, we will update the bookmarks table. + // To not let it error out on users who bookmarked both topics, we just return on an error... + $db->sql_return_on_error(true); + $db->sql_query('UPDATE ' . BOOKMARKS_TABLE . ' SET topic_id = ' . (int) $to_topic_id . ' WHERE topic_id = ' . (int) $topic_id); + $db->sql_return_on_error(false); + + $db->sql_query('DELETE FROM ' . BOOKMARKS_TABLE . ' WHERE topic_id = ' . (int) $topic_id); } // Link to the new topic @@ -650,4 +658,4 @@ function merge_posts($topic_id, $to_topic_id) } } -?> \ No newline at end of file +?> -- cgit v1.2.1 From 5a88bd1bf103537aece6713145fd13288cf3c329 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 3 Sep 2012 15:35:06 -0500 Subject: [ticket/8610] Update Bookmarks and Subscriptions when splitting topics Update bookmarks and subscriptions to add bookmarks/subscriptions to the new topic when using the split_topic function PHPBB3-8610 --- phpBB/includes/mcp/mcp_forum.php | 12 +++++++-- phpBB/includes/mcp/mcp_topic.php | 56 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 4 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 865e464e81..ce709e7f71 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -98,6 +98,9 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total; $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; + $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); + $template->assign_vars(array( 'ACTION' => $action, 'FORUM_NAME' => $forum_info['forum_name'], @@ -425,10 +428,15 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) // If the topic no longer exist, we will update the bookmarks table. // To not let it error out on users who bookmarked both topics, we just return on an error... $db->sql_return_on_error(true); - $db->sql_query('UPDATE ' . BOOKMARKS_TABLE . ' SET topic_id = ' . (int) $to_topic_id . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + $sql = 'UPDATE ' . BOOKMARKS_TABLE . ' + SET topic_id = ' . (int) $to_topic_id . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); $db->sql_return_on_error(false); - $db->sql_query('DELETE FROM ' . BOOKMARKS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + $sql = 'DELETE FROM ' . BOOKMARKS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); // Link to the new topic $return_link .= (($return_link) ? '

' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '', ''); diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 36cfe1e355..f0775f9137 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -307,6 +307,12 @@ function mcp_topic_view($id, $mode, $action) 'post_ids' => $post_id_list, )); + $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"); + if ($posts_per_page) + { + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $posts_per_page, $start); + } + $template->assign_vars(array( 'TOPIC_TITLE' => $topic_info['topic_title'], 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_info['forum_id'] . '&t=' . $topic_info['topic_id']), @@ -517,6 +523,47 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) WHERE post_id = {$post_id_list[0]}"; $db->sql_query($sql); + $sql = 'SELECT user_id, notify_status + FROM ' . TOPICS_WATCH_TABLE . ' + WHERE topic_id = ' . $topic_id; + $result = $db->sql_query($sql); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary[] = array( + 'topic_id' => (int) $to_topic_id, + 'user_id' => (int) $row['user_id'], + 'notify_status' => (int) $row['notify_status'], + ); + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary); + } + + $sql = 'SELECT user_id + FROM ' . BOOKMARKS_TABLE . ' + WHERE topic_id = ' . $topic_id; + $result = $db->sql_query($sql); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary[] = array( + 'topic_id' => (int) $to_topic_id, + 'user_id' => (int) $row['user_id'], + ); + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert(BOOKMARKS_TABLE, $sql_ary); + } + $success_msg = 'TOPIC_SPLIT_SUCCESS'; // Update forum statistics @@ -630,10 +677,15 @@ function merge_posts($topic_id, $to_topic_id) // If the topic no longer exist, we will update the bookmarks table. // To not let it error out on users who bookmarked both topics, we just return on an error... $db->sql_return_on_error(true); - $db->sql_query('UPDATE ' . BOOKMARKS_TABLE . ' SET topic_id = ' . (int) $to_topic_id . ' WHERE topic_id = ' . (int) $topic_id); + $sql = 'UPDATE ' . BOOKMARKS_TABLE . ' + SET topic_id = ' . (int) $to_topic_id . ' + WHERE topic_id = ' . (int) $topic_id; + $db->sql_query($sql); $db->sql_return_on_error(false); - $db->sql_query('DELETE FROM ' . BOOKMARKS_TABLE . ' WHERE topic_id = ' . (int) $topic_id); + $sql = 'DELETE FROM ' . BOOKMARKS_TABLE . ' + WHERE topic_id = ' . (int) $topic_id; + $db->sql_query($sql); } // Link to the new topic -- cgit v1.2.1 From 71bcc58feecd49fe05f6b7e0e2bca8a94424f240 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 30 Oct 2012 12:27:02 -0500 Subject: [ticket/8610] Add some comments PHPBB3-8610 --- phpBB/includes/mcp/mcp_main.php | 2 ++ phpBB/includes/mcp/mcp_topic.php | 2 ++ 2 files changed, 4 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index f7c49539ea..cce4db8b4d 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1231,6 +1231,7 @@ function mcp_fork_topic($topic_ids) } } + // Copy topic subscriptions to new topic $sql = 'SELECT user_id, notify_status FROM ' . TOPICS_WATCH_TABLE . ' WHERE topic_id = ' . $topic_id; @@ -1252,6 +1253,7 @@ function mcp_fork_topic($topic_ids) $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary); } + // Copy bookmarks to new topic $sql = 'SELECT user_id FROM ' . BOOKMARKS_TABLE . ' WHERE topic_id = ' . $topic_id; diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index f0775f9137..28f5c6a41d 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -523,6 +523,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) WHERE post_id = {$post_id_list[0]}"; $db->sql_query($sql); + // Copy topic subscriptions to new topic $sql = 'SELECT user_id, notify_status FROM ' . TOPICS_WATCH_TABLE . ' WHERE topic_id = ' . $topic_id; @@ -544,6 +545,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary); } + // Copy bookmarks to new topic $sql = 'SELECT user_id FROM ' . BOOKMARKS_TABLE . ' WHERE topic_id = ' . $topic_id; -- cgit v1.2.1 From 5c614ff6249c441637103ba0b78338f878057479 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 13 Dec 2012 20:30:16 -0600 Subject: [ticket/8610] Revert some funky merging I did from rebase PHPBB3-8610 --- phpBB/includes/mcp/mcp_forum.php | 5 +---- phpBB/includes/mcp/mcp_main.php | 2 +- phpBB/includes/mcp/mcp_topic.php | 8 +------- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index ce709e7f71..78239698a9 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -98,9 +98,6 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total; $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; - $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); - $template->assign_vars(array( 'ACTION' => $action, 'FORUM_NAME' => $forum_info['forum_name'], @@ -460,4 +457,4 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) } } -?> +?> \ No newline at end of file diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index cce4db8b4d..0cef8933fc 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1336,4 +1336,4 @@ function mcp_fork_topic($topic_ids) } } -?> +?> \ No newline at end of file diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 28f5c6a41d..ba11b04884 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -307,12 +307,6 @@ function mcp_topic_view($id, $mode, $action) 'post_ids' => $post_id_list, )); - $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"); - if ($posts_per_page) - { - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $posts_per_page, $start); - } - $template->assign_vars(array( 'TOPIC_TITLE' => $topic_info['topic_title'], 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_info['forum_id'] . '&t=' . $topic_info['topic_id']), @@ -712,4 +706,4 @@ function merge_posts($topic_id, $to_topic_id) } } -?> +?> \ No newline at end of file -- cgit v1.2.1 From a50907250e487675baf9ac77be564b6ccb72b056 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 13 Dec 2012 20:42:10 -0600 Subject: [ticket/8610] Use phpbb_update_rows_avoiding_duplicates PHPBB3-8610 --- phpBB/includes/mcp/mcp_forum.php | 16 +++++----------- phpBB/includes/mcp/mcp_topic.php | 12 +----------- 2 files changed, 6 insertions(+), 22 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 78239698a9..097f67487d 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -423,17 +423,11 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) $db->sql_query('DELETE FROM ' . TOPICS_WATCH_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); // If the topic no longer exist, we will update the bookmarks table. - // To not let it error out on users who bookmarked both topics, we just return on an error... - $db->sql_return_on_error(true); - $sql = 'UPDATE ' . BOOKMARKS_TABLE . ' - SET topic_id = ' . (int) $to_topic_id . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); - $db->sql_return_on_error(false); - - $sql = 'DELETE FROM ' . BOOKMARKS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); + if (!function_exists('phpbb_update_rows_avoiding_duplicates')) + { + include($phpbb_root_path . 'includes/functions_database_helper.' . $phpEx); + } + phpbb_update_rows_avoiding_duplicates($db, BOOKMARKS_TABLE, 'topic_id', $topic_ids, $to_topic_id); // Link to the new topic $return_link .= (($return_link) ? '

' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '', ''); diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index ba11b04884..29d7a0e41b 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -671,17 +671,7 @@ function merge_posts($topic_id, $to_topic_id) $db->sql_query('DELETE FROM ' . TOPICS_WATCH_TABLE . ' WHERE topic_id = ' . (int) $topic_id); // If the topic no longer exist, we will update the bookmarks table. - // To not let it error out on users who bookmarked both topics, we just return on an error... - $db->sql_return_on_error(true); - $sql = 'UPDATE ' . BOOKMARKS_TABLE . ' - SET topic_id = ' . (int) $to_topic_id . ' - WHERE topic_id = ' . (int) $topic_id; - $db->sql_query($sql); - $db->sql_return_on_error(false); - - $sql = 'DELETE FROM ' . BOOKMARKS_TABLE . ' - WHERE topic_id = ' . (int) $topic_id; - $db->sql_query($sql); + phpbb_update_rows_avoiding_duplicates($db, BOOKMARKS_TABLE, 'topic_id', $topic_id, $to_topic_id); } // Link to the new topic -- cgit v1.2.1 From 16c021e98667fe353e6b3a6cb0bbf3b8f2319f98 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Dec 2012 15:46:45 +0100 Subject: [ticket/10954] Change behavior of marking topics/forums It will now display a popup message for 3 seconds which will confirm the taken action. The amount of DOM traversals have been significantly reduced and jQuery.each is now used instead of for loops. Additionally, it is now possible to click on the mark topics/forums read links without triggering an AJAX error. PHPBB3-10954 --- phpBB/includes/functions_display.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index f3198bc1e5..cd4c901b58 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -63,10 +63,13 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($request->is_ajax()) { - // Tell the ajax script what language vars need to be replaced + // Tell the ajax script what language vars and URL need to be replaced $data = array( 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], - 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'] + 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'], + 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time()) : '', + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED'] ); $json_response = new phpbb_json_response(); $json_response->send($data); @@ -326,10 +329,13 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($request->is_ajax()) { - // Tell the ajax script what language vars need to be replaced + // Tell the ajax script what language vars and URL need to be replaced $data = array( 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], - 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'] + 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'], + 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums&mark_time=' . time()) : '', + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED'] ); $json_response = new phpbb_json_response(); $json_response->send($data); -- cgit v1.2.1 From 5c496674f63b31e892d0f3bed7921feb947ed839 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 15 Dec 2012 01:19:55 -0500 Subject: [ticket/10758] Dependency inject parameters into cache_moderators. Also add phpbb prefix since the signature is being changed anyway. PHPBB3-10758 --- phpBB/includes/acp/acp_forums.php | 6 +++--- phpBB/includes/acp/acp_main.php | 18 +++++++++--------- phpBB/includes/acp/acp_permissions.php | 16 ++++++++-------- phpBB/includes/acp/acp_styles.php | 4 +++- phpBB/includes/functions_admin.php | 14 +++++++++----- phpBB/includes/functions_user.php | 12 ++++++------ 6 files changed, 38 insertions(+), 32 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index c6dbf5eb9c..7e8d5d8388 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -206,7 +206,7 @@ class acp_forums ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')))) { copy_forum_permissions($forum_perm_from, $forum_data['forum_id'], ($action == 'edit') ? true : false); - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); $copied_permissions = true; } /* Commented out because of questionable UI workflow - re-visit for 3.0.7 @@ -266,7 +266,7 @@ class acp_forums add_log('admin', 'LOG_FORUM_' . strtoupper($action), $row['forum_name'], $move_forum_name); $cache->destroy('sql', FORUMS_TABLE); } - + if ($request->is_ajax()) { $json_response = new phpbb_json_response; @@ -768,7 +768,7 @@ class acp_forums if (!empty($forum_perm_from) && $forum_perm_from != $forum_id) { copy_forum_permissions($forum_perm_from, $forum_id, true); - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); $auth->acl_clear_prefetch(); $cache->destroy('sql', FORUMS_TABLE); diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index d419bc3b99..c44bc1b8a6 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -24,7 +24,7 @@ class acp_main function main($id, $mode) { - global $config, $db, $user, $auth, $template, $request; + global $config, $db, $cache, $user, $auth, $template, $request; global $phpbb_root_path, $phpbb_admin_path, $phpEx; // Show restore permissions notice @@ -129,7 +129,7 @@ class acp_main set_config('record_online_users', 1, true); set_config('record_online_date', time(), true); add_log('admin', 'LOG_RESET_ONLINE'); - + if ($request->is_ajax()) { trigger_error('RESET_ONLINE_SUCCESS'); @@ -184,7 +184,7 @@ class acp_main update_last_username(); add_log('admin', 'LOG_RESYNC_STATS'); - + if ($request->is_ajax()) { trigger_error('RESYNC_STATS_SUCCESS'); @@ -251,7 +251,7 @@ class acp_main } add_log('admin', 'LOG_RESYNC_POSTCOUNTS'); - + if ($request->is_ajax()) { trigger_error('RESYNC_POSTCOUNTS_SUCCESS'); @@ -266,7 +266,7 @@ class acp_main set_config('board_startdate', time() - 1); add_log('admin', 'LOG_RESET_DATE'); - + if ($request->is_ajax()) { trigger_error('RESET_DATE_SUCCESS'); @@ -346,7 +346,7 @@ class acp_main } add_log('admin', 'LOG_RESYNC_POST_MARKING'); - + if ($request->is_ajax()) { trigger_error('RESYNC_POST_MARKING_SUCCESS'); @@ -359,10 +359,10 @@ class acp_main // Clear permissions $auth->acl_clear_prefetch(); - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); add_log('admin', 'LOG_PURGE_CACHE'); - + if ($request->is_ajax()) { trigger_error('PURGE_CACHE_SUCCESS'); @@ -413,7 +413,7 @@ class acp_main $db->sql_query($sql); add_log('admin', 'LOG_PURGE_SESSIONS'); - + if ($request->is_ajax()) { trigger_error('PURGE_SESSIONS_SUCCESS'); diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index dd071074de..d65a9cbb9e 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -656,7 +656,7 @@ class acp_permissions */ function set_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) { - global $user, $auth; + global $db, $cache, $user, $auth; global $request; $psubmit = request_var('psubmit', array(0 => array(0 => 0))); @@ -726,7 +726,7 @@ class acp_permissions // Do we need to recache the moderator lists? if ($permission_type == 'm_') { - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); } // Remove users who are now moderators or admins from everyones foes list @@ -745,7 +745,7 @@ class acp_permissions */ function set_all_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) { - global $user, $auth; + global $db, $cache, $user, $auth; global $request; // User or group to be set? @@ -794,7 +794,7 @@ class acp_permissions // Do we need to recache the moderator lists? if ($permission_type == 'm_') { - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); } // Remove users who are now moderators or admins from everyones foes list @@ -858,7 +858,7 @@ class acp_permissions */ function remove_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id, &$forum_id) { - global $user, $db, $auth; + global $user, $db, $cache, $auth; // User or group to be set? $ug_type = (sizeof($user_id)) ? 'user' : 'group'; @@ -874,7 +874,7 @@ class acp_permissions // Do we need to recache the moderator lists? if ($permission_type == 'm_') { - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); } $this->log_action($mode, 'del', $permission_type, $ug_type, (($ug_type == 'user') ? $user_id : $group_id), (sizeof($forum_id) ? $forum_id : array(0 => 0))); @@ -1172,7 +1172,7 @@ class acp_permissions */ function copy_forum_permissions() { - global $auth, $cache, $template, $user; + global $db, $auth, $cache, $template, $user; $user->add_lang('acp/forums'); @@ -1187,7 +1187,7 @@ class acp_permissions { if (copy_forum_permissions($src, $dest)) { - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); $auth->acl_clear_prefetch(); $cache->destroy('sql', FORUMS_TABLE); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index db77825ae7..266495972b 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -137,11 +137,13 @@ class acp_styles */ protected function action_cache() { + global $db, $cache, $auth; + $this->cache->purge(); // Clear permissions $this->auth->acl_clear_prefetch(); - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); add_log('admin', 'LOG_PURGE_CACHE'); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 15930f9a2c..571f1acd1d 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2292,13 +2292,17 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr } /** -* Cache moderators, called whenever permissions are changed via admin_permissions. Changes of username -* and group names must be carried through for the moderators table +* Cache moderators. Called whenever permissions are changed +* via admin_permissions. Changes of usernames and group names +* must be carried through for the moderators table +* +* @param phpbb_db_driver $db Database connection +* @param phpbb_cache_driver_interface Cache driver +* @param phpbb_auth $auth Authentication object +* @return null */ -function cache_moderators() +function phpbb_cache_moderators($db, $cache, $auth) { - global $db, $cache, $auth, $phpbb_root_path, $phpEx; - // Remove cached sql results $cache->destroy('sql', MODERATOR_CACHE_TABLE); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 8f9c9198f4..2d6c15a5b1 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2842,7 +2842,7 @@ function avatar_remove_db($avatar_name) */ function group_delete($group_id, $group_name = false) { - global $db, $phpbb_root_path, $phpEx, $phpbb_dispatcher; + global $db, $cache, $auth, $phpbb_root_path, $phpEx, $phpbb_dispatcher; if (!$group_name) { @@ -2913,12 +2913,12 @@ function group_delete($group_id, $group_name = false) extract($phpbb_dispatcher->trigger_event('core.delete_group_after', compact($vars))); // Re-cache moderators - if (!function_exists('cache_moderators')) + if (!function_exists('phpbb_cache_moderators')) { include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); add_log('admin', 'LOG_GROUP_DELETE', $group_name); @@ -3678,7 +3678,7 @@ function group_memberships($group_id_ary = false, $user_id_ary = false, $return_ */ function group_update_listings($group_id) { - global $auth; + global $db, $cache, $auth; $hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_')); @@ -3720,12 +3720,12 @@ function group_update_listings($group_id) if ($mod_permissions) { - if (!function_exists('cache_moderators')) + if (!function_exists('phpbb_cache_moderators')) { global $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } - cache_moderators(); + phpbb_cache_moderators($db, $cache, $auth); } if ($mod_permissions || $admin_permissions) -- cgit v1.2.1 From e82833d4b8bc9241641577b12a779e12338ace39 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 15 Dec 2012 01:29:10 -0500 Subject: [ticket/10758] Dependency inject parameters into update_foes. Also add phpbb prefix since the signature is being changed anyway. PHPBB3-10758 --- phpBB/includes/acp/acp_permissions.php | 4 ++-- phpBB/includes/functions_admin.php | 12 ++++++++---- phpBB/includes/functions_user.php | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index d65a9cbb9e..3d4c256a3f 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -732,7 +732,7 @@ class acp_permissions // Remove users who are now moderators or admins from everyones foes list if ($permission_type == 'm_' || $permission_type == 'a_') { - update_foes($group_id, $user_id); + phpbb_update_foes($db, $auth, $group_id, $user_id); } $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_id, $forum_id); @@ -800,7 +800,7 @@ class acp_permissions // Remove users who are now moderators or admins from everyones foes list if ($permission_type == 'm_' || $permission_type == 'a_') { - update_foes($group_id, $user_id); + phpbb_update_foes($db, $auth, $group_id, $user_id); } $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_ids, $forum_ids); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 571f1acd1d..e8dd55813b 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2744,12 +2744,16 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id } /** -* Update foes - remove moderators and administrators from foe lists... +* Removes moderators and administrators from foe lists. +* +* @param phpbb_db_driver $db Database connection +* @param phpbb_auth $auth Authentication object +* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore +* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore +* @return null */ -function update_foes($group_id = false, $user_id = false) +function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false) { - global $db, $auth; - // update foes for some user if (is_array($user_id) && sizeof($user_id)) { diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 2d6c15a5b1..a50d5175fe 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -3730,12 +3730,12 @@ function group_update_listings($group_id) if ($mod_permissions || $admin_permissions) { - if (!function_exists('update_foes')) + if (!function_exists('phpbb_update_foes')) { global $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } - update_foes(array($group_id)); + phpbb_update_foes($db, $auth, array($group_id)); } } -- cgit v1.2.1 From 9e7d663e7638bac9add20d82467b8008e5c83e3b Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 15 Dec 2012 14:09:33 -0500 Subject: [ticket/10758] Spelling fix. PHPBB3-10758 --- phpBB/includes/auth/auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/auth/auth.php b/phpBB/includes/auth/auth.php index e3bccaf47b..1ad9f94d26 100644 --- a/phpBB/includes/auth/auth.php +++ b/phpBB/includes/auth/auth.php @@ -191,7 +191,7 @@ class phpbb_auth /** * Get forums with the specified permission setting - * if the option is prefixed with !, then the result becomes nagated + * if the option is prefixed with !, then the result becomes negated * * @param bool $clean set to true if only values needs to be returned which are set/unset */ -- cgit v1.2.1 From 649e009f7b42a751d7b208bd5a4659c0fc442912 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sat, 15 Dec 2012 16:23:48 -0600 Subject: [ticket/8610] Update comment PHPBB3-8610 --- phpBB/includes/mcp/mcp_forum.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index de2966d34e..04e0e70f1d 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -422,7 +422,7 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) // Update the topic watch table. phpbb_update_rows_avoiding_duplicates_notify_status($db, TOPICS_WATCH_TABLE, 'topic_id', $topic_ids, $to_topic_id); - // If the topic no longer exist, we will update the bookmarks table. + // Update the bookmarks table. phpbb_update_rows_avoiding_duplicates($db, BOOKMARKS_TABLE, 'topic_id', $topic_ids, $to_topic_id); // Link to the new topic -- cgit v1.2.1 From 54d96dfac720d5aa1cdc617ca93749d26ee9f264 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 17 Dec 2012 12:59:44 +0100 Subject: [ticket/10763] Make functions for remote avatars static fileupload::image_types() and filespec::get_extension() are called statically while submitting the form for the remote avatar. Make them static as described in the ticket in order to prevent a PHP notice. Also change the tests to use the static functions. PHPBB3-10763 --- phpBB/includes/functions_upload.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index b467aa93d1..d4cb34cc4e 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -70,7 +70,7 @@ class filespec $this->mimetype = 'application/octetstream'; } - $this->extension = strtolower($this->get_extension($this->realname)); + $this->extension = strtolower(filespec::get_extension($this->realname)); // Try to get real filesize from temporary folder (not always working) ;) $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize; @@ -187,8 +187,11 @@ class filespec /** * Get file extension + * + * @param string Filename that needs to be checked + * @return string Extension of the supplied filename */ - function get_extension($filename) + static public function get_extension($filename) { if (strpos($filename, '.') === false) { @@ -369,7 +372,7 @@ class filespec } // Check image type - $types = $this->upload->image_types(); + $types = fileupload::image_types(); if (!isset($types[$this->image_info[2]]) || !in_array($this->extension, $types[$this->image_info[2]])) { @@ -1019,9 +1022,11 @@ class fileupload } /** - * Return image type/extension mapping + * Get image type/extension mapping + * + * @return array Array containing the image types and their extensions */ - function image_types() + static public function image_types() { return array( IMAGETYPE_GIF => array('gif'), -- cgit v1.2.1 From 4ae0c787828ea34bb927a8346804e52bd25cffac Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 17 Dec 2012 19:17:32 +0100 Subject: [ticket/10763] Use self when calling get_extension() in filespec class PHPBB3-10763 --- phpBB/includes/functions_upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index d4cb34cc4e..4f31a85e83 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -70,7 +70,7 @@ class filespec $this->mimetype = 'application/octetstream'; } - $this->extension = strtolower(filespec::get_extension($this->realname)); + $this->extension = strtolower(self::get_extension($this->realname)); // Try to get real filesize from temporary folder (not always working) ;) $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize; -- cgit v1.2.1 From 9a1df948c635d9dbabaff94313652c6d8d1df28d Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 19 Dec 2012 21:50:03 -0500 Subject: [ticket/10758] Extract obtain_user_data for the benefit of tests. PHPBB3-10758 --- phpBB/includes/acp/acp_permissions.php | 7 +------ phpBB/includes/auth/auth.php | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index 3d4c256a3f..a64765f4f5 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -952,12 +952,7 @@ class acp_permissions if ($user_id != $user->data['user_id']) { - $sql = 'SELECT user_id, username, user_permissions, user_type - FROM ' . USERS_TABLE . ' - WHERE user_id = ' . $user_id; - $result = $db->sql_query($sql); - $userdata = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $userdata = $auth->obtain_user_data($user_id); } else { diff --git a/phpBB/includes/auth/auth.php b/phpBB/includes/auth/auth.php index 1ad9f94d26..2535247571 100644 --- a/phpBB/includes/auth/auth.php +++ b/phpBB/includes/auth/auth.php @@ -102,6 +102,26 @@ class phpbb_auth return; } + /** + * Retrieves data wanted by acl function from the database for the + * specified user. + * + * @param int $user_id User ID + * @return array User attributes + */ + public function obtain_user_data($user_id) + { + global $db; + + $sql = 'SELECT user_id, username, user_permissions, user_type + FROM ' . USERS_TABLE . ' + WHERE user_id = ' . $user_id; + $result = $db->sql_query($sql); + $user_data = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + return $user_data; + } + /** * Fill ACL array with relevant bitstrings from user_permissions column * @access private -- cgit v1.2.1 From 917a2fa9a6cf8b01a347df67fc14d3fc826aa3ed Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 02:20:21 +0200 Subject: [ticket/10880] The m_approve permisson no longer implies f_noapprove. PHPBB3-10880 --- phpBB/includes/functions_posting.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index a1029ab97a..e5cbae0d71 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1698,8 +1698,9 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // The variable name should be $post_approved, because it indicates if the post is approved or not $post_approval = 1; - // Check the permissions for post approval. Moderators are not affected. - if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) + // Check the permissions for post approval. + // Moderators must go through post approval like ordinary users. + if (!$auth->acl_get('f_noapprove', $data['forum_id'])) { // Post not approved, but in queue $post_approval = 0; -- cgit v1.2.1 From 69e373c1af09e10722c1146f44493e8dc3669918 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 19 Dec 2012 21:47:53 -0500 Subject: [ticket/10758] Add compat functions. PHPBB3-10758 --- phpBB/includes/functions_admin.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index e8dd55813b..496d3eba09 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2472,6 +2472,20 @@ function phpbb_cache_moderators($db, $cache, $auth) $db->sql_multi_insert(MODERATOR_CACHE_TABLE, $sql_ary); } +/** +* Cache moderators. Called whenever permissions are changed +* via admin_permissions. Changes of usernames and group names +* must be carried through for the moderators table +* +* @return null +*/ +function cache_moderators() +{ + global $db, $cache, $auth; + return phpbb_cache_moderators($db, $cache, $auth); +} + + /** * View log * If $log_count is set to false, we will skip counting all entries in the database. @@ -2862,6 +2876,19 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false) unset($perms); } +/** +* Removes moderators and administrators from foe lists. +* +* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore +* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore +* @return null +*/ +function update_foes($group_id = false, $user_id = false) +{ + global $db, $auth; + phpbb_update_foes($db, $auth, $group_id, $user_id); +} + /** * Lists inactive users */ -- cgit v1.2.1 From e50f69187f21e29a12512880e0c69f2876e84aa1 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 20 Dec 2012 04:35:30 -0500 Subject: [ticket/11037] Eliminate global $db usage in cache drivers. The only time $db is needed in cache drivers is to navigate the result set in sql_save. Pass it as a parameter in that function. PHPBB3-11037 --- phpBB/includes/cache/driver/file.php | 6 ++---- phpBB/includes/cache/driver/interface.php | 3 ++- phpBB/includes/cache/driver/memory.php | 6 ++---- phpBB/includes/cache/driver/null.php | 4 ++-- phpBB/includes/db/driver/firebird.php | 2 +- phpBB/includes/db/driver/mssql.php | 2 +- phpBB/includes/db/driver/mssql_odbc.php | 2 +- phpBB/includes/db/driver/mssqlnative.php | 2 +- phpBB/includes/db/driver/mysql.php | 2 +- phpBB/includes/db/driver/mysqli.php | 2 +- phpBB/includes/db/driver/oracle.php | 2 +- phpBB/includes/db/driver/postgres.php | 2 +- phpBB/includes/db/driver/sqlite.php | 2 +- 13 files changed, 17 insertions(+), 20 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/cache/driver/file.php b/phpBB/includes/cache/driver/file.php index 691abe0438..85decbe3e8 100644 --- a/phpBB/includes/cache/driver/file.php +++ b/phpBB/includes/cache/driver/file.php @@ -367,12 +367,10 @@ class phpbb_cache_driver_file extends phpbb_cache_driver_base } /** - * Save sql query + * {@inheritDoc} */ - function sql_save($query, $query_result, $ttl) + function sql_save(phpbb_db_driver $db, $query, $query_result, $ttl) { - global $db; - // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); diff --git a/phpBB/includes/cache/driver/interface.php b/phpBB/includes/cache/driver/interface.php index d403bbcd71..53f684d1c8 100644 --- a/phpBB/includes/cache/driver/interface.php +++ b/phpBB/includes/cache/driver/interface.php @@ -85,6 +85,7 @@ interface phpbb_cache_driver_interface * result to persistent storage. In other words, there is no need * to call save() afterwards. * + * @param phpbb_db_driver $db Database connection * @param string $query SQL query, should be used for generating storage key * @param mixed $query_result The result from dbal::sql_query, to be passed to * dbal::sql_fetchrow to get all rows and store them @@ -95,7 +96,7 @@ interface phpbb_cache_driver_interface * representing the query should be returned. Otherwise * the original $query_result should be returned. */ - public function sql_save($query, $query_result, $ttl); + public function sql_save(phpbb_db_driver $db, $query, $query_result, $ttl); /** * Check if result for a given SQL query exists in cache. diff --git a/phpBB/includes/cache/driver/memory.php b/phpBB/includes/cache/driver/memory.php index c39f9f7850..f77a1df316 100644 --- a/phpBB/includes/cache/driver/memory.php +++ b/phpBB/includes/cache/driver/memory.php @@ -283,12 +283,10 @@ abstract class phpbb_cache_driver_memory extends phpbb_cache_driver_base } /** - * Save sql query + * {@inheritDoc} */ - function sql_save($query, $query_result, $ttl) + function sql_save(phpbb_db_driver $db, $query, $query_result, $ttl) { - global $db; - // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); $hash = md5($query); diff --git a/phpBB/includes/cache/driver/null.php b/phpBB/includes/cache/driver/null.php index 687604d14f..2fadc27ba3 100644 --- a/phpBB/includes/cache/driver/null.php +++ b/phpBB/includes/cache/driver/null.php @@ -105,9 +105,9 @@ class phpbb_cache_driver_null extends phpbb_cache_driver_base } /** - * Save sql query + * {@inheritDoc} */ - function sql_save($query, $query_result, $ttl) + function sql_save(phpbb_db_driver $db, $query, $query_result, $ttl) { return $query_result; } diff --git a/phpBB/includes/db/driver/firebird.php b/phpBB/includes/db/driver/firebird.php index a55175c345..4767b29f63 100644 --- a/phpBB/includes/db/driver/firebird.php +++ b/phpBB/includes/db/driver/firebird.php @@ -270,7 +270,7 @@ class phpbb_db_driver_firebird extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/mssql.php b/phpBB/includes/db/driver/mssql.php index ac957e7698..215c6345c6 100644 --- a/phpBB/includes/db/driver/mssql.php +++ b/phpBB/includes/db/driver/mssql.php @@ -168,7 +168,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/mssql_odbc.php b/phpBB/includes/db/driver/mssql_odbc.php index 13e74e66d4..7d93f939a2 100644 --- a/phpBB/includes/db/driver/mssql_odbc.php +++ b/phpBB/includes/db/driver/mssql_odbc.php @@ -197,7 +197,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/mssqlnative.php b/phpBB/includes/db/driver/mssqlnative.php index 4b1639aba2..f88c702d07 100644 --- a/phpBB/includes/db/driver/mssqlnative.php +++ b/phpBB/includes/db/driver/mssqlnative.php @@ -337,7 +337,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/mysql.php b/phpBB/includes/db/driver/mysql.php index 6fc6fab483..30f78c9231 100644 --- a/phpBB/includes/db/driver/mysql.php +++ b/phpBB/includes/db/driver/mysql.php @@ -206,7 +206,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/mysqli.php b/phpBB/includes/db/driver/mysqli.php index be28a95715..4f45c5781c 100644 --- a/phpBB/includes/db/driver/mysqli.php +++ b/phpBB/includes/db/driver/mysqli.php @@ -201,7 +201,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver if ($cache_ttl) { - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } } else if (defined('DEBUG')) diff --git a/phpBB/includes/db/driver/oracle.php b/phpBB/includes/db/driver/oracle.php index 6263ea8414..53f9dd71e0 100644 --- a/phpBB/includes/db/driver/oracle.php +++ b/phpBB/includes/db/driver/oracle.php @@ -446,7 +446,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/postgres.php b/phpBB/includes/db/driver/postgres.php index 147ecd04d9..cca97c9c0e 100644 --- a/phpBB/includes/db/driver/postgres.php +++ b/phpBB/includes/db/driver/postgres.php @@ -211,7 +211,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { diff --git a/phpBB/includes/db/driver/sqlite.php b/phpBB/includes/db/driver/sqlite.php index 6b9cc64d89..155409b665 100644 --- a/phpBB/includes/db/driver/sqlite.php +++ b/phpBB/includes/db/driver/sqlite.php @@ -152,7 +152,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver if ($cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($query, $this->query_result, $cache_ttl); + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } else if (strpos($query, 'SELECT') === 0 && $this->query_result) { -- cgit v1.2.1 From 5c817289834e7a34d47410f89907de1bafefff8a Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 20 Dec 2012 05:10:57 -0500 Subject: [ticket/10758] Add deprecated tags. PHPBB3-10758 --- phpBB/includes/functions_admin.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 496d3eba09..77c70eb6fc 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2477,6 +2477,7 @@ function phpbb_cache_moderators($db, $cache, $auth) * via admin_permissions. Changes of usernames and group names * must be carried through for the moderators table * +* @deprecated 3.1 * @return null */ function cache_moderators() @@ -2879,6 +2880,7 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false) /** * Removes moderators and administrators from foe lists. * +* @deprecated 3.1 * @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore * @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore * @return null -- cgit v1.2.1 From aaaf8a5332aa6679522c687f0c8144d0819c05a5 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 22 Dec 2012 17:40:25 -0500 Subject: [ticket/10758] Yes, only one empty line. PHPBB3-10758 --- phpBB/includes/functions_admin.php | 1 - 1 file changed, 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 77c70eb6fc..22735cf2cd 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2486,7 +2486,6 @@ function cache_moderators() return phpbb_cache_moderators($db, $cache, $auth); } - /** * View log * If $log_count is set to false, we will skip counting all entries in the database. -- cgit v1.2.1 From 496529fa714b6cdc6e8b8ffeb7750fe27907c267 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 22 Dec 2012 17:54:54 -0500 Subject: [ticket/10758] Add periods. PHPBB3-10758 --- phpBB/includes/functions_admin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 22735cf2cd..3864c9de36 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2294,7 +2294,7 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr /** * Cache moderators. Called whenever permissions are changed * via admin_permissions. Changes of usernames and group names -* must be carried through for the moderators table +* must be carried through for the moderators table. * * @param phpbb_db_driver $db Database connection * @param phpbb_cache_driver_interface Cache driver @@ -2475,7 +2475,7 @@ function phpbb_cache_moderators($db, $cache, $auth) /** * Cache moderators. Called whenever permissions are changed * via admin_permissions. Changes of usernames and group names -* must be carried through for the moderators table +* must be carried through for the moderators table. * * @deprecated 3.1 * @return null -- cgit v1.2.1 From cac39360669b10c7a27549ca36865249014e6d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fre=CC=80rejean?= Date: Thu, 20 Dec 2012 16:27:33 +0100 Subject: [ticket/11283] Extension manager follow symlinks. All extensions are located in the `phpBB/ext` directory, however the `phpbb_extension_manager::all_available()` method only looks into actual directories and ignores symlinks. Add the `RecursiveDirectoryIterator::FOLLOW_SYMLINKS` flag to the `new RecursiveDirectoryIterator` call so that you can store extensions in a different location and use symlinks so that phpBB can recognise them. PHPBB3-11283 --- phpBB/includes/extension/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 67cc81e407..de6f364320 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -384,7 +384,7 @@ class phpbb_extension_manager } $iterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/'), + new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/', FilesystemIterator::NEW_CURRENT_AND_KEY | FilesystemIterator::FOLLOW_SYMLINKS), RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $file_info) { -- cgit v1.2.1 From 5056f162351420440bf989d0b1cfc6c325499f7a Mon Sep 17 00:00:00 2001 From: Martin Beckmann Date: Mon, 24 Dec 2012 03:53:54 +0100 Subject: [ticket/11292] Fix: Newlines removed in display of PM reports Report text is run through make_clickable and bbcode_nl2br for PMs just as it is for posts. PHPBB3-11292 --- phpBB/includes/mcp/mcp_pm_reports.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index 72f77fae7c..77bc7680e6 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -123,6 +123,7 @@ class mcp_pm_reports $message = bbcode_nl2br($message); $message = smiley_text($message); + $report['report_text'] = make_clickable(bbcode_nl2br($report['report_text'])); if ($pm_info['message_attachment'] && $auth->acl_get('u_pm_download')) { -- cgit v1.2.1 From 8707a3413504b0cf922086daa6fc497ccf090448 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 24 Dec 2012 15:12:57 -0500 Subject: [ticket/10758] Add return to the other compat function. PHPBB3-10758 --- phpBB/includes/functions_admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 3864c9de36..5529f2af46 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2887,7 +2887,7 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false) function update_foes($group_id = false, $user_id = false) { global $db, $auth; - phpbb_update_foes($db, $auth, $group_id, $user_id); + return phpbb_update_foes($db, $auth, $group_id, $user_id); } /** -- cgit v1.2.1 From 0b47a7823a8c48e31442595d4c802ae7f77096f3 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 24 Dec 2012 15:36:43 -0500 Subject: [ticket/11037] Eliminate globals from cache service. PHPBB3-11037 --- phpBB/includes/cache/service.php | 76 ++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 42 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php index e63ec6e33a..0768236f3d 100644 --- a/phpBB/includes/cache/service.php +++ b/phpBB/includes/cache/service.php @@ -21,16 +21,24 @@ if (!defined('IN_PHPBB')) */ class phpbb_cache_service { - private $driver; + protected $driver; + protected $config; + protected $db; + protected $phpbb_root_path; + protected $php_ext; /** * Creates a cache service around a cache driver * * @param phpbb_cache_driver_interface $driver The cache driver */ - public function __construct(phpbb_cache_driver_interface $driver = null) + public function __construct(phpbb_cache_driver_interface $driver, phpbb_config $config, phpbb_db_driver $db, $phpbb_root_path, $php_ext) { $this->set_driver($driver); + $this->config = $config; + $this->db = $db; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; } /** @@ -64,21 +72,19 @@ class phpbb_cache_service */ function obtain_word_list() { - global $db; - if (($censors = $this->driver->get('_word_censors')) === false) { $sql = 'SELECT word, replacement FROM ' . WORDS_TABLE; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $censors = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $censors['match'][] = get_censor_preg_expression($row['word']); $censors['replace'][] = $row['replacement']; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_word_censors', $censors); } @@ -93,23 +99,21 @@ class phpbb_cache_service { if (($icons = $this->driver->get('_icons')) === false) { - global $db; - // Topic icons $sql = 'SELECT * FROM ' . ICONS_TABLE . ' ORDER BY icons_order'; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $icons = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $icons[$row['icons_id']]['img'] = $row['icons_url']; $icons[$row['icons_id']]['width'] = (int) $row['icons_width']; $icons[$row['icons_id']]['height'] = (int) $row['icons_height']; $icons[$row['icons_id']]['display'] = (bool) $row['display_on_posting']; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_icons', $icons); } @@ -124,15 +128,13 @@ class phpbb_cache_service { if (($ranks = $this->driver->get('_ranks')) === false) { - global $db; - $sql = 'SELECT * FROM ' . RANKS_TABLE . ' ORDER BY rank_min DESC'; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $ranks = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { if ($row['rank_special']) { @@ -150,7 +152,7 @@ class phpbb_cache_service ); } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_ranks', $ranks); } @@ -169,8 +171,6 @@ class phpbb_cache_service { if (($extensions = $this->driver->get('_extensions')) === false) { - global $db; - $extensions = array( '_allowed_post' => array(), '_allowed_pm' => array(), @@ -181,9 +181,9 @@ class phpbb_cache_service FROM ' . EXTENSIONS_TABLE . ' e, ' . EXTENSION_GROUPS_TABLE . ' g WHERE e.group_id = g.group_id AND (g.allow_group = 1 OR g.allow_in_pm = 1)'; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $extension = strtolower(trim($row['extension'])); @@ -210,7 +210,7 @@ class phpbb_cache_service $extensions['_allowed_pm'][$extension] = 0; } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_extensions', $extensions); } @@ -275,9 +275,7 @@ class phpbb_cache_service { if (($bots = $this->driver->get('_bots')) === false) { - global $db; - - switch ($db->sql_layer) + switch ($this->db->sql_layer) { case 'mssql': case 'mssql_odbc': @@ -303,14 +301,14 @@ class phpbb_cache_service ORDER BY LENGTH(bot_agent) DESC'; break; } - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $bots = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $bots[] = $row; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_bots', $bots); } @@ -323,8 +321,6 @@ class phpbb_cache_service */ function obtain_cfg_items($style) { - global $config, $phpbb_root_path; - $parsed_array = $this->driver->get('_cfg_' . $style['style_path']); if ($parsed_array === false) @@ -332,14 +328,14 @@ class phpbb_cache_service $parsed_array = array(); } - $filename = $phpbb_root_path . 'styles/' . $style['style_path'] . '/style.cfg'; + $filename = $this->phpbb_root_path . 'styles/' . $style['style_path'] . '/style.cfg'; if (!file_exists($filename)) { return $parsed_array; } - if (!isset($parsed_array['filetime']) || (($config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) + if (!isset($parsed_array['filetime']) || (($this->config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) { // Re-parse cfg file $parsed_array = parse_cfg_file($filename); @@ -358,18 +354,16 @@ class phpbb_cache_service { if (($usernames = $this->driver->get('_disallowed_usernames')) === false) { - global $db; - $sql = 'SELECT disallow_username FROM ' . DISALLOW_TABLE; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $usernames = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $usernames[] = str_replace('%', '.*?', preg_quote(utf8_clean_string($row['disallow_username']), '#')); } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); $this->driver->put('_disallowed_usernames', $usernames); } @@ -382,22 +376,20 @@ class phpbb_cache_service */ function obtain_hooks() { - global $phpbb_root_path, $phpEx; - if (($hook_files = $this->driver->get('_hooks')) === false) { $hook_files = array(); // Now search for hooks... - $dh = @opendir($phpbb_root_path . 'includes/hooks/'); + $dh = @opendir($this->phpbb_root_path . 'includes/hooks/'); if ($dh) { while (($file = readdir($dh)) !== false) { - if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) + if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($this->php_ext) + 1)) === '.' . $this->php_ext) { - $hook_files[] = substr($file, 0, -(strlen($phpEx) + 1)); + $hook_files[] = substr($file, 0, -(strlen($this->php_ext) + 1)); } } closedir($dh); -- cgit v1.2.1 From 989c4c3e6408e0d53b042161cfb34a0befe2570c Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 25 Dec 2012 00:11:34 -0500 Subject: [ticket/11293] Add a note that mysqli should be in front of mysql. php 5.5 alpha 2 deprecated mysql extension, prefer mysqli if both are available. PHPBB3-11293 --- phpBB/includes/functions_install.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index eae136808c..47f4eac627 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -55,6 +55,8 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'AVAILABLE' => true, '2.0.x' => false, ), + // Note: php 5.5 alpha 2 deprecated mysql. + // Keep mysqli before mysql in this list. 'mysqli' => array( 'LABEL' => 'MySQL with MySQLi Extension', 'SCHEMA' => 'mysql_41', -- cgit v1.2.1 From bad7661ee985e63b8765845d710367e9f4f8260b Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 26 Dec 2012 10:47:03 -0500 Subject: [ticket/11037] Add/update docblocks. PHPBB3-11037 --- phpBB/includes/cache/service.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php index 0768236f3d..8c1e1ea1f8 100644 --- a/phpBB/includes/cache/service.php +++ b/phpBB/includes/cache/service.php @@ -21,16 +21,49 @@ if (!defined('IN_PHPBB')) */ class phpbb_cache_service { + /** + * Cache driver. + * + * @var phpbb_cache_driver_interface + */ protected $driver; + + /** + * The config. + * + * @var phpbb_config + */ protected $config; + + /** + * Database connection. + * + * @var phpbb_db_driver + */ protected $db; + + /** + * Root path. + * + * @var string + */ protected $phpbb_root_path; + + /** + * PHP extension. + * + * @var string + */ protected $php_ext; /** * Creates a cache service around a cache driver * * @param phpbb_cache_driver_interface $driver The cache driver + * @param phpbb_config $config The config + * @param phpbb_db_driver $db Database connection + * @param string $phpbb_root_path Root path + * @param string $php_ext PHP extension */ public function __construct(phpbb_cache_driver_interface $driver, phpbb_config $config, phpbb_db_driver $db, $phpbb_root_path, $php_ext) { -- cgit v1.2.1 From 979edc4113f8b9ecb3aa4e7d445a5b59eefd78ff Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 3 Dec 2012 00:48:19 +0530 Subject: [ticket/11188] add count query to postgres search PHPBB3-11188 --- phpBB/includes/search/fulltext_postgres.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index f22ee2ca16..a9b122931b 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -476,6 +476,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $tmp_sql_match[] = "to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', " . $sql_match_column . ") @@ to_tsquery ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', '" . $this->db->sql_escape($this->tsearch_query) . "')"; } + $this->db->sql_transaction('begin'); $sql = "SELECT $sql_select FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p WHERE (" . implode(' OR ', $tmp_sql_match) . ") @@ -499,7 +500,13 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base // if the total result count is not cached yet, retrieve it from the db if (!$result_count) { - $result_count = sizeof ($id_ary); + $sql_count = "SELECT COUNT(*) as result_count + FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p + WHERE (" . implode(' OR ', $tmp_sql_match) . ") + $sql_where_options"; + $result = $this->db->sql_query($sql_count); + $result_count = (int) $this->db->sql_fetchfield('result_count'); + $this->db->sql_freeresult($result); if (!$result_count) { @@ -507,6 +514,8 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } } + $this->db->sql_transaction('commit'); + // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page $this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir); $id_ary = array_slice($id_ary, 0, (int) $per_page); -- cgit v1.2.1 From 763f2929babcb65b503a60f712bfc552f1e296f9 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 3 Dec 2012 01:07:47 +0530 Subject: [ticket/11188] add result count query for author search PHPBB3-11188 --- phpBB/includes/search/fulltext_postgres.php | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index a9b122931b..7d7b3f6fa8 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -656,6 +656,8 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $field = 'topic_id'; } + $this->db->sql_transaction('begin'); + // Only read one block of posts from the db and then cache it $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); @@ -668,7 +670,35 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base // retrieve the total result count if needed if (!$result_count) { - $result_count = sizeof ($id_ary); + if ($type == 'posts') + { + $sql_count = "SELECT COUNT(*) as result_count + FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . " + WHERE $sql_author + $sql_topic_id + $sql_firstpost + $m_approve_fid_sql + $sql_fora + $sql_sort_join + $sql_time"; + } + else + { + $sql_count = "SELECT COUNT(*) as result_count + FROM " . $sql_sort_table . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p + WHERE $sql_author + $sql_topic_id + $sql_firstpost + $m_approve_fid_sql + $sql_fora + AND t.topic_id = p.topic_id + $sql_sort_join + $sql_time + GROUP BY t.topic_id, $sort_by_sql[$sort_key]"; + } + + $result = $this->db->sql_query($sql_count); + $result_count = (int) $this->db->sql_fetchfield('result_count'); if (!$result_count) { @@ -676,6 +706,8 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } } + $this->db->sql_transaction('commit'); + if (sizeof($id_ary)) { $this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir); -- cgit v1.2.1 From 3d27ed13f5ac960fc24a3f95e39c767be4a48f31 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 29 Dec 2012 19:34:21 -0500 Subject: [ticket/11188] Reduce waste. PHPBB3-11188 --- phpBB/includes/search/fulltext_postgres.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index 7d7b3f6fa8..1475cc31d0 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -477,10 +477,13 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } $this->db->sql_transaction('begin'); + + $sql_from = "FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p"; + $sql_where = "WHERE (" . implode(' OR ', $tmp_sql_match) . ") + $sql_where_options"; $sql = "SELECT $sql_select - FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p - WHERE (" . implode(' OR ', $tmp_sql_match) . ") - $sql_where_options + $sql_from + $sql_where ORDER BY $sql_sort"; $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start); @@ -501,9 +504,8 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base if (!$result_count) { $sql_count = "SELECT COUNT(*) as result_count - FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p - WHERE (" . implode(' OR ', $tmp_sql_match) . ") - $sql_where_options"; + $sql_from + $sql_where"; $result = $this->db->sql_query($sql_count); $result_count = (int) $this->db->sql_fetchfield('result_count'); $this->db->sql_freeresult($result); -- cgit v1.2.1 From ea24de8de3e4f451aa4394f0f46d6955ccb671c2 Mon Sep 17 00:00:00 2001 From: Igor Wiedler Date: Wed, 2 Jan 2013 04:04:01 +0100 Subject: [ticket/11306] Introduce phpbb_create_default_container Extracts default container construction to factory function, removing boilerplate duplication for container construction. PHPBB3-11306 --- phpBB/includes/functions_container.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_container.php b/phpBB/includes/functions_container.php index 8014574443..0634948002 100644 --- a/phpBB/includes/functions_container.php +++ b/phpBB/includes/functions_container.php @@ -135,6 +135,22 @@ function phpbb_create_dumped_container_unless_debug(array $extensions, array $pa return $container_factory($extensions, $passes, $phpbb_root_path, $php_ext); } +function phpbb_create_default_container($phpbb_root_path, $php_ext) +{ + return phpbb_create_dumped_container_unless_debug( + array( + new phpbb_di_extension_config($phpbb_root_path . 'config.' . $php_ext), + new phpbb_di_extension_core($phpbb_root_path), + ), + array( + new phpbb_di_pass_collection_pass(), + new phpbb_di_pass_kernel_pass(), + ), + $phpbb_root_path, + $php_ext + ); +} + function phpbb_container_filename($phpbb_root_path, $php_ext) { $filename = str_replace(array('/', '.'), array('slash', 'dot'), $phpbb_root_path); -- cgit v1.2.1 From 21eb8d842bc634a92f04c37e5de22c4c5692052d Mon Sep 17 00:00:00 2001 From: Igor Wiedler Date: Wed, 2 Jan 2013 06:41:20 +0100 Subject: [ticket/11306] Add docblocks to all container related functions PHPBB3-11306 --- phpBB/includes/functions_container.php | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'phpBB/includes') diff --git a/phpBB/includes/functions_container.php b/phpBB/includes/functions_container.php index 0634948002..a3ed21c35b 100644 --- a/phpBB/includes/functions_container.php +++ b/phpBB/includes/functions_container.php @@ -105,6 +105,15 @@ function phpbb_create_compiled_container(array $extensions, array $passes, $phpb return $container; } +/** +* Create a compiled and dumped ContainerBuilder object +* +* @param array $extensions Array of Container extension objects +* @param array $passes Array of Compiler Pass objects +* @param string $phpbb_root_path Root path +* @param string $php_ext PHP Extension +* @return ContainerBuilder object (compiled) +*/ function phpbb_create_dumped_container(array $extensions, array $passes, $phpbb_root_path, $php_ext) { // Check for our cached container; if it exists, use it @@ -129,12 +138,37 @@ function phpbb_create_dumped_container(array $extensions, array $passes, $phpbb_ return $container; } +/** +* Create an environment-specific ContainerBuilder object +* +* If debug is enabled, the container is re-compiled every time. +* This ensures that the latest changes will always be reflected +* during development. +* +* Otherwise it will get the existing dumped container and use +* that one instead. +* +* @param array $extensions Array of Container extension objects +* @param array $passes Array of Compiler Pass objects +* @param string $phpbb_root_path Root path +* @param string $php_ext PHP Extension +* @return ContainerBuilder object (compiled) +*/ function phpbb_create_dumped_container_unless_debug(array $extensions, array $passes, $phpbb_root_path, $php_ext) { $container_factory = defined('DEBUG') ? 'phpbb_create_compiled_container' : 'phpbb_create_dumped_container'; return $container_factory($extensions, $passes, $phpbb_root_path, $php_ext); } +/** +* Create a default ContainerBuilder object +* +* Contains the default configuration of the phpBB container. +* +* @param array $extensions Array of Container extension objects +* @param array $passes Array of Compiler Pass objects +* @return ContainerBuilder object (compiled) +*/ function phpbb_create_default_container($phpbb_root_path, $php_ext) { return phpbb_create_dumped_container_unless_debug( @@ -151,6 +185,13 @@ function phpbb_create_default_container($phpbb_root_path, $php_ext) ); } +/** +* Get the filename under which the dumped container will be stored. +* +* @param string $phpbb_root_path Root path +* @param string $php_ext PHP Extension +* @return Path for dumped container +*/ function phpbb_container_filename($phpbb_root_path, $php_ext) { $filename = str_replace(array('/', '.'), array('slash', 'dot'), $phpbb_root_path); -- cgit v1.2.1 From 7adae349a96d5dffbd47ea5eca1e6bee481b7ce1 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 1 Jan 2013 20:48:04 -0500 Subject: [ticket/11305] Extract hook finder from cache service. Unlike most other things in cache service, hook finder does not need a database connection. PHPBB3-11305 --- phpBB/includes/cache/service.php | 30 -------------- phpBB/includes/hook/finder.php | 84 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 phpBB/includes/hook/finder.php (limited to 'phpBB/includes') diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php index 8c1e1ea1f8..69c5e0fdd0 100644 --- a/phpBB/includes/cache/service.php +++ b/phpBB/includes/cache/service.php @@ -403,34 +403,4 @@ class phpbb_cache_service return $usernames; } - - /** - * Obtain hooks... - */ - function obtain_hooks() - { - if (($hook_files = $this->driver->get('_hooks')) === false) - { - $hook_files = array(); - - // Now search for hooks... - $dh = @opendir($this->phpbb_root_path . 'includes/hooks/'); - - if ($dh) - { - while (($file = readdir($dh)) !== false) - { - if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($this->php_ext) + 1)) === '.' . $this->php_ext) - { - $hook_files[] = substr($file, 0, -(strlen($this->php_ext) + 1)); - } - } - closedir($dh); - } - - $this->driver->put('_hooks', $hook_files); - } - - return $hook_files; - } } diff --git a/phpBB/includes/hook/finder.php b/phpBB/includes/hook/finder.php new file mode 100644 index 0000000000..065e685514 --- /dev/null +++ b/phpBB/includes/hook/finder.php @@ -0,0 +1,84 @@ +phpbb_root_path = $phpbb_root_path; + $this->cache = $cache; + $this->php_ext = $php_ext; + } + + /** + * Finds all hook files. + * + * @param bool $cache Whether the result should be cached + * @return array An array of paths to found hook files + */ + public function find($cache = true) + { + if (!defined('DEBUG') && $cache && $this->cache) + { + $hook_files = $this->cache->get('_hooks'); + if ($hook_files !== false) + { + return $hook_files; + } + } + + $hook_files = array(); + + // Now search for hooks... + $dh = @opendir($this->phpbb_root_path . 'includes/hooks/'); + + if ($dh) + { + while (($file = readdir($dh)) !== false) + { + if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($this->php_ext) + 1)) === '.' . $this->php_ext) + { + $hook_files[] = substr($file, 0, -(strlen($this->php_ext) + 1)); + } + } + closedir($dh); + } + + if ($cache && $this->cache) + { + $this->cache->put('_hooks', $hook_files); + } + + return $hook_files; + } +} -- cgit v1.2.1 From b94f9ae3029777fa0aba2f3cb52b321925ce7e72 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 1 Jan 2013 20:57:21 -0500 Subject: [ticket/11305] Retrieve cache driver from container rather than cache service. This only covers some of the call sites. PHPBB3-11305 --- phpBB/includes/acp/acp_modules.php | 6 +++--- phpBB/includes/functions_user.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 8528dc91c4..52a82004e8 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -740,15 +740,15 @@ class acp_modules */ function remove_cache_file() { - global $cache; + global $phpbb_container; // Sanitise for future path use, it's escaped as appropriate for queries $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class)); - $cache->destroy('_modules_' . $p_class); + $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class); // Additionally remove sql cache - $cache->destroy('sql', MODULES_TABLE); + $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE); } /** diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index a50d5175fe..6abcdee8f2 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -3463,7 +3463,7 @@ function group_validate_groupname($group_id, $group_name) */ function group_set_user_default($group_id, $user_id_ary, $group_attributes = false, $update_listing = false) { - global $cache, $db, $phpbb_dispatcher; + global $phpbb_container, $db, $phpbb_dispatcher; if (empty($user_id_ary)) { @@ -3579,7 +3579,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal } // Because some tables/caches use usercolour-specific data we need to purge this here. - $cache->destroy('sql', MODERATOR_CACHE_TABLE); + $phpbb_container->get('cache.driver')->destroy('sql', MODERATOR_CACHE_TABLE); } /** -- cgit v1.2.1 From c8c6eb46ec6eefe0e58aebcd44f4c69f5df4b065 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 2 Jan 2013 14:36:14 -0500 Subject: [ticket/11305] Check for $cache being null before using it in db drivers. There is no reason why db drivers must have a cache to work. They query the database, that part works without caches. PHPBB3-11305 --- phpBB/includes/db/driver/driver.php | 4 ++-- phpBB/includes/db/driver/firebird.php | 8 ++++---- phpBB/includes/db/driver/mssql.php | 10 +++++----- phpBB/includes/db/driver/mssql_odbc.php | 8 ++++---- phpBB/includes/db/driver/mssqlnative.php | 2 +- phpBB/includes/db/driver/mysql.php | 10 +++++----- phpBB/includes/db/driver/mysqli.php | 10 +++++----- phpBB/includes/db/driver/oracle.php | 10 +++++----- phpBB/includes/db/driver/postgres.php | 10 +++++----- phpBB/includes/db/driver/sqlite.php | 10 +++++----- 10 files changed, 41 insertions(+), 41 deletions(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/db/driver/driver.php b/phpBB/includes/db/driver/driver.php index 52ac21a79f..8dda94bc2c 100644 --- a/phpBB/includes/db/driver/driver.php +++ b/phpBB/includes/db/driver/driver.php @@ -206,7 +206,7 @@ class phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -256,7 +256,7 @@ class phpbb_db_driver $this->sql_rowseek($rownum, $query_id); } - if (!is_object($query_id) && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_fetchfield($query_id, $field); } diff --git a/phpBB/includes/db/driver/firebird.php b/phpBB/includes/db/driver/firebird.php index 4767b29f63..787c28b812 100644 --- a/phpBB/includes/db/driver/firebird.php +++ b/phpBB/includes/db/driver/firebird.php @@ -154,7 +154,7 @@ class phpbb_db_driver_firebird extends phpbb_db_driver } $this->last_query_text = $query; - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -267,7 +267,7 @@ class phpbb_db_driver_firebird extends phpbb_db_driver } } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -330,7 +330,7 @@ class phpbb_db_driver_firebird extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -396,7 +396,7 @@ class phpbb_db_driver_firebird extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/mssql.php b/phpBB/includes/db/driver/mssql.php index 215c6345c6..89c2c2351b 100644 --- a/phpBB/includes/db/driver/mssql.php +++ b/phpBB/includes/db/driver/mssql.php @@ -150,7 +150,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver $this->sql_report('start', $query); } - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -165,7 +165,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -240,7 +240,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -277,7 +277,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -316,7 +316,7 @@ class phpbb_db_driver_mssql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/mssql_odbc.php b/phpBB/includes/db/driver/mssql_odbc.php index 7d93f939a2..f7834443eb 100644 --- a/phpBB/includes/db/driver/mssql_odbc.php +++ b/phpBB/includes/db/driver/mssql_odbc.php @@ -179,7 +179,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver } $this->last_query_text = $query; - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -194,7 +194,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -270,7 +270,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -311,7 +311,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/mssqlnative.php b/phpBB/includes/db/driver/mssqlnative.php index f88c702d07..656cbd2437 100644 --- a/phpBB/includes/db/driver/mssqlnative.php +++ b/phpBB/includes/db/driver/mssqlnative.php @@ -317,7 +317,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver } $this->last_query_text = $query; - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) diff --git a/phpBB/includes/db/driver/mysql.php b/phpBB/includes/db/driver/mysql.php index 30f78c9231..9de7283a42 100644 --- a/phpBB/includes/db/driver/mysql.php +++ b/phpBB/includes/db/driver/mysql.php @@ -188,7 +188,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver $this->sql_report('start', $query); } - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -203,7 +203,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -265,7 +265,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -286,7 +286,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -314,7 +314,7 @@ class phpbb_db_driver_mysql extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/mysqli.php b/phpBB/includes/db/driver/mysqli.php index 4f45c5781c..7448bf1670 100644 --- a/phpBB/includes/db/driver/mysqli.php +++ b/phpBB/includes/db/driver/mysqli.php @@ -184,7 +184,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver $this->sql_report('start', $query); } - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -199,7 +199,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } @@ -256,7 +256,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver $query_id = $this->query_result; } - if (!is_object($query_id) && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -283,7 +283,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver $query_id = $this->query_result; } - if (!is_object($query_id) && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -311,7 +311,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver $query_id = $this->query_result; } - if (!is_object($query_id) && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/oracle.php b/phpBB/includes/db/driver/oracle.php index 53f9dd71e0..e21e07055d 100644 --- a/phpBB/includes/db/driver/oracle.php +++ b/phpBB/includes/db/driver/oracle.php @@ -267,7 +267,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver } $this->last_query_text = $query; - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -443,7 +443,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -498,7 +498,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -550,7 +550,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -619,7 +619,7 @@ class phpbb_db_driver_oracle extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/postgres.php b/phpBB/includes/db/driver/postgres.php index cca97c9c0e..14854d179d 100644 --- a/phpBB/includes/db/driver/postgres.php +++ b/phpBB/includes/db/driver/postgres.php @@ -193,7 +193,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver } $this->last_query_text = $query; - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -208,7 +208,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -278,7 +278,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -299,7 +299,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -348,7 +348,7 @@ class phpbb_db_driver_postgres extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/includes/db/driver/sqlite.php b/phpBB/includes/db/driver/sqlite.php index 155409b665..7188f0daa2 100644 --- a/phpBB/includes/db/driver/sqlite.php +++ b/phpBB/includes/db/driver/sqlite.php @@ -134,7 +134,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver $this->sql_report('start', $query); } - $this->query_result = ($cache_ttl) ? $cache->sql_load($query) : false; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; $this->sql_add_num_queries($this->query_result); if ($this->query_result === false) @@ -149,7 +149,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver $this->sql_report('stop', $query); } - if ($cache_ttl) + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -210,7 +210,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_fetchrow($query_id); } @@ -231,7 +231,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); } @@ -259,7 +259,7 @@ class phpbb_db_driver_sqlite extends phpbb_db_driver $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } -- cgit v1.2.1 From 68baee4ce2388f9c6233e48ffb4b1223e7671373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fre=CC=80rejean?= Date: Thu, 3 Jan 2013 13:16:38 +0100 Subject: [ticket/11309] phpbb_extension_interface::disable_step correct docblock. The `@return` documentation of the `phpbb_extension_interface::disable_step` method states incorrect that the method returns null, as it returns false or a state. PHPBB3-11309 --- phpBB/includes/extension/interface.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/extension/interface.php b/phpBB/includes/extension/interface.php index 74ecb9b762..7b36a12bf6 100644 --- a/phpBB/includes/extension/interface.php +++ b/phpBB/includes/extension/interface.php @@ -45,7 +45,9 @@ interface phpbb_extension_interface * * @param mixed $old_state The return value of the previous call * of this method, or false on the first call - * @return null + * @return mixed Returns false after last step, otherwise + * temporary state which is passed as an + * argument to the next step */ public function disable_step($old_state); -- cgit v1.2.1 From 24befac7b4879ae02a4416e47ca0deea93766b93 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 8 Jan 2013 23:18:17 +0100 Subject: [ticket/11301] Explicitly cast str offset to int to prevent E_NOTICE on 5.4. PHPBB3-11301 --- phpBB/includes/captcha/captcha_non_gd.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/captcha/captcha_non_gd.php b/phpBB/includes/captcha/captcha_non_gd.php index f82896f628..a823fa4226 100644 --- a/phpBB/includes/captcha/captcha_non_gd.php +++ b/phpBB/includes/captcha/captcha_non_gd.php @@ -119,7 +119,7 @@ class captcha $new_line = ''; $end = strlen($scanline) - ceil($width/2); - for ($i = floor($width/2); $i < $end; $i++) + for ($i = (int) floor($width/2); $i < $end; $i++) { $pixel = ord($scanline{$i}); -- cgit v1.2.1 From 41a07eedeb13349305977bb8882f0bd6429480e3 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 8 Jan 2013 23:20:30 +0100 Subject: [ticket/11301] Guidelines: Add spaces in front and after the / operator. PHPBB3-11301 --- phpBB/includes/captcha/captcha_non_gd.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/includes') diff --git a/phpBB/includes/captcha/captcha_non_gd.php b/phpBB/includes/captcha/captcha_non_gd.php index a823fa4226..2adf909b96 100644 --- a/phpBB/includes/captcha/captcha_non_gd.php +++ b/phpBB/includes/captcha/captcha_non_gd.php @@ -119,7 +119,7 @@ class captcha $new_line = ''; $end = strlen($scanline) - ceil($width/2); - for ($i = (int) floor($width/2); $i < $end; $i++) + for ($i = (int) floor($width / 2); $i < $end; $i++) { $pixel = ord($scanline{$i}); -- cgit v1.2.1