1.1 --- a/system/classes/listfactory.class.php Sun Oct 25 22:01:38 2009 +0000
1.2 +++ b/system/classes/listfactory.class.php Thu Oct 29 13:01:33 2009 +0100
1.3 @@ -47,15 +47,15 @@
1.4 // Set up the fields that will be seen by the user
1.5 $obj->setField(
1.6 '#', // Title of the field
1.7 - ROW_NUMBER, // The field identifier can be either:
1.8 - // ROW_NUMBER - The number of each row will be displayed
1.9 - // SQL_TITLE - The title given the the SQL query will be displayed
1.10 + LF_ROW_NUMBER, // The field identifier can be either:
1.11 + // LF_ROW_NUMBER - The number of each row will be displayed
1.12 + // LF_SOURCE_TITLE - The title given the the SQL query will be displayed
1.13 // <string> - SQL column name
1.14 true, // Enables the field
1.15 true, // The field can be sorted
1.16 '<b>%d.</b>' // Formats the data
1.17 );
1.18 - $obj->setField('Type', SQL_TITLE, true, true, '<b>%s</b>');
1.19 + $obj->setField('Type', LF_SOURCE_TITLE, true, true, '<b>%s</b>');
1.20 $obj->setField('Title', 'title');
1.21 $obj->setField('Text', 'text');
1.22 $obj->setField('Date', 'date');
1.23 @@ -72,7 +72,7 @@
1.24 // Set up some queries to execute
1.25 $sql = 'SELECT sid AS id, title, introtext AS text, date FROM stories';
1.26 $obj->setQuery(
1.27 - 'Story', // The name given to the query which will be displayed in the SQL_TITLE field (optional)
1.28 + 'Story', // The name given to the query which will be displayed in the LF_SOURCE_TITLE field (optional)
1.29 'story',
1.30 $sql, // The SQL string without the LIMIT or ORDER BY clauses. Notice the column names match the field identifiers
1.31 5 // The rank of the query, 5 highest = more results, 1 lowest = least results
1.32 @@ -84,7 +84,7 @@
1.33 // Note: the array must match the field identifier names stated previously
1.34 $extra_row = array(
1.35 'id' => -1,
1.36 - SQL_TITLE => 'Extra Row',
1.37 + LF_SOURCE_TITLE => 'Extra Row',
1.38 'title' => 'An extra row example',
1.39 'text' => 'With some really really really long text.....<b>and HTML</b>',
1.40 'date' => '2008-07-08 03:00:00'
1.41 @@ -132,7 +132,7 @@
1.42
1.43 // PRIVATE VARIABLES
1.44 var $_fields = array();
1.45 - var $_query_arr = array();
1.46 + var $_sources_arr = array();
1.47 var $_total_rank = 0;
1.48 var $_sort_arr = array();
1.49 var $_def_sort_arr = array();
1.50 @@ -148,7 +148,7 @@
1.51 * Constructor
1.52 *
1.53 * Sets up private url variable and defines the
1.54 - * SQL_TITLE, SQL_NAME and ROW_NUMBER constants.
1.55 + * LF_SOURCE_TITLE, LF_SOURCE_NAME and LF_ROW_NUMBER constants.
1.56 *
1.57 * @access public
1.58 * @param string $url The URL of the page the table appears on
1.59 @@ -171,9 +171,9 @@
1.60 $this->_page_limits = array(10, 15, 20, 25, 30, 35);
1.61 }
1.62
1.63 - define('SQL_TITLE', 0);
1.64 - define('SQL_NAME', 1);
1.65 - define('ROW_NUMBER', 2);
1.66 + define('LF_SOURCE_TITLE', 0);
1.67 + define('LF_SOURCE_NAME', 1);
1.68 + define('LF_ROW_NUMBER', 2);
1.69 }
1.70
1.71 /**
1.72 @@ -191,7 +191,7 @@
1.73 /**
1.74 * Sets a field in the list.
1.75 *
1.76 - * Note: ROW_NUMBER cannot be sorted
1.77 + * Note: LF_ROW_NUMBER cannot be sorted
1.78 *
1.79 * @access public
1.80 * @param string $title The title of the field which is displayed to the user
1.81 @@ -203,7 +203,7 @@
1.82 */
1.83 function setField( $title, $name, $display = true, $sort = true, $format = '%s' )
1.84 {
1.85 - if ($name === ROW_NUMBER) {
1.86 + if ($name === LF_ROW_NUMBER) {
1.87 $sort = false;
1.88 }
1.89 $this->_fields[] = array(
1.90 @@ -227,7 +227,7 @@
1.91 */
1.92 function setQuery( $title, $name, $sql, $rank )
1.93 {
1.94 - $this->_query_arr[] = array(
1.95 + $this->_sources_arr[] = array(
1.96 'type' => 'sql',
1.97 'title' => $title,
1.98 'name' => $name,
1.99 @@ -237,13 +237,30 @@
1.100 $this->_total_rank += $rank;
1.101 }
1.102
1.103 - function setCallback( $title, $name, $function, $rank, $total )
1.104 + /**
1.105 + * Sets a callback function that provides another source for results.
1.106 + *
1.107 + * The function will be passed two parameters, $offset and $limit,
1.108 + * which will determine how many results are requested. The callback
1.109 + * function should then return a multidimensional array containing
1.110 + * the results. This provides an alternative to the setQuery()
1.111 + * function as results can be sourced from anywhere.
1.112 + *
1.113 + * @access public
1.114 + * @param string $title The text that's displayed to the user
1.115 + * @param string $name The local name given to the query
1.116 + * @param string $function Any callable function, method or lambda
1.117 + * @param int $rank The rating that determins how many results will be returned
1.118 + * @param int $total The total number of results that are avaliable
1.119 + *
1.120 + */
1.121 + function setCallback( $title, $name, $callback, $rank, $total )
1.122 {
1.123 - $this->_query_arr[] = array(
1.124 + $this->_sources_arr[] = array(
1.125 'type' => 'callback',
1.126 'title' => $title,
1.127 'name' => $name,
1.128 - 'func' => $function,
1.129 + 'func' => $callback,
1.130 'rank' => $rank,
1.131 'total' => $total
1.132 );
1.133 @@ -251,7 +268,8 @@
1.134 }
1.135
1.136 /**
1.137 - * Sets the callback function that gets called when formatting a row
1.138 + * Sets the callback function thats called on every row for styling
1.139 + * or formatting.
1.140 *
1.141 * @access public
1.142 * @param callback $function Any callable function, method or lambda
1.143 @@ -300,20 +318,21 @@
1.144 }
1.145
1.146 /**
1.147 - * Gets the total number of results from a query
1.148 + * Gets the total number of results from source item, either an sql
1.149 + * query or a callback function.
1.150 *
1.151 * @access private
1.152 - * @param string $sql The query
1.153 + * @param array $source The source we are currently working with
1.154 * @return int Total number of rows
1.155 *
1.156 */
1.157 - function _getTotal( $param )
1.158 + function _getTotal( $source )
1.159 {
1.160 - if ($param['type'] == 'callback') {
1.161 - return $param['total'];
1.162 + if ($source['type'] == 'callback') {
1.163 + return $source['total'];
1.164 }
1.165 else {
1.166 - $sql = $param['sql'];
1.167 + $sql = $source['sql'];
1.168 }
1.169
1.170 if (is_array($sql)) {
1.171 @@ -382,6 +401,42 @@
1.172 }
1.173
1.174 /**
1.175 + * Applies styling to each row and adds extra meta details that are
1.176 + * used else where in the ListFactory.
1.177 + *
1.178 + * @access private
1.179 + * @param array $row_arr A single results row
1.180 + * @param array $source The source we are currently working with
1.181 + * @return array The row with styling applied and extra meta details
1.182 + *
1.183 + */
1.184 + function _fillrow( $row_arr, $source )
1.185 + {
1.186 + $col = array();
1.187 + $col[LF_SOURCE_TITLE] = $source['title'];
1.188 + $col[LF_SOURCE_NAME] = $source['name'];
1.189 +
1.190 + foreach ($this->_fields as $field)
1.191 + {
1.192 + if (!is_numeric($field['name']) && $field['name'][0] != '_') {
1.193 + if (empty($row_arr[ $field['name'] ])) {
1.194 + $col[ $field['name'] ] = 'LF_NULL';
1.195 + } else {
1.196 + $col[ $field['name'] ] = $row_arr[ $field['name'] ];
1.197 + }
1.198 + }
1.199 + }
1.200 +
1.201 + // Need to call the format function before and after
1.202 + // sorting the results.
1.203 + if (is_callable($this->_function)) {
1.204 + $col = call_user_func_array($this->_function, array(true, $col));
1.205 + }
1.206 +
1.207 + return $col;
1.208 + }
1.209 +
1.210 + /**
1.211 * Executes pre set queries
1.212 *
1.213 * @access public
1.214 @@ -400,7 +455,7 @@
1.215 if (is_numeric($this->_sort_arr['field']))
1.216 {
1.217 $ord = $this->_def_sort_arr['field'];
1.218 - $this->_sort_arr['field'] = SQL_TITLE;
1.219 + $this->_sort_arr['field'] = LF_SOURCE_TITLE;
1.220 }
1.221 else
1.222 {
1.223 @@ -424,10 +479,10 @@
1.224 $num_query_results = $this->_per_page - $this->_total_found;
1.225 $pp_total = $this->_total_found;
1.226 $limits = array();
1.227 - for ($i = 0; $i < count($this->_query_arr); $i++)
1.228 + for ($i = 0; $i < count($this->_sources_arr); $i++)
1.229 {
1.230 - $limits[$i]['total'] = $this->_getTotal($this->_query_arr[$i]);
1.231 - $limits[$i]['pp'] = round(($this->_query_arr[$i]['rank'] / $this->_total_rank) * $num_query_results);
1.232 + $limits[$i]['total'] = $this->_getTotal($this->_sources_arr[$i]);
1.233 + $limits[$i]['pp'] = round(($this->_sources_arr[$i]['rank'] / $this->_total_rank) * $num_query_results);
1.234 $this->_total_found += $limits[$i]['total'];
1.235 $pp_total += $limits[$i]['pp'];
1.236 }
1.237 @@ -438,45 +493,30 @@
1.238 }
1.239 $limits = $this->_getLimits($limits);
1.240
1.241 - // Execute each query in turn
1.242 - for ($i = 0; $i < count($this->_query_arr); $i++)
1.243 + // Retrieve the results from each source in turn
1.244 + for ($i = 0; $i < count($this->_sources_arr); $i++)
1.245 {
1.246 if ($limits[$i]['limit'] <= 0) {
1.247 continue;
1.248 }
1.249
1.250 // This is a callback function
1.251 - if ($this->_query_arr[$i]['type'] == 'callback')
1.252 + if ($this->_sources_arr[$i]['type'] == 'callback')
1.253 {
1.254 - if (is_callable($this->_query_arr[$i]['func']))
1.255 + if (is_callable($this->_sources_arr[$i]['func']))
1.256 {
1.257 - $callback_rows = call_user_func_array($this->_query_arr[$i]['func'], array($limits[$i]['offset'], $limits[$i]['limit']));
1.258 + $callback_rows = call_user_func_array(
1.259 + $this->_sources_arr[$i]['func'],
1.260 + array($limits[$i]['offset'],
1.261 + $limits[$i]['limit'])
1.262 + );
1.263
1.264 - foreach ($callback_rows as $row)
1.265 - {
1.266 - $col = array();
1.267 - $col[SQL_TITLE] = $this->_query_arr[$i]['title'];
1.268 - $col[SQL_NAME] = $this->_query_arr[$i]['name'];
1.269 -
1.270 - foreach ($this->_fields as $field)
1.271 - {
1.272 - if (!is_numeric($field['name']) && $field['name'][0] != '_') {
1.273 - if (empty($row[ $field['name'] ])) {
1.274 - $col[ $field['name'] ] = 'LF_NULL';
1.275 - } else {
1.276 - $col[ $field['name'] ] = $row[ $field['name'] ];
1.277 - }
1.278 - }
1.279 - }
1.280 -
1.281 - // Need to call the format function before and after
1.282 - // sorting the results.
1.283 - if (is_callable($this->_function)) {
1.284 - $col = call_user_func_array($this->_function, array(true, $col));
1.285 - }
1.286 -
1.287 - $rows_arr[] = $col;
1.288 + foreach ($callback_rows as $row) {
1.289 + $rows_arr[] = $this->_fillrow($row, $this->_sources_arr[$i]);
1.290 }
1.291 + } else {
1.292 + COM_errorLog('ListFactory: A callback function was set for "'.
1.293 + $this->_sources_arr[$i]['name'].'", but it could not be found.');
1.294 }
1.295 continue;
1.296 }
1.297 @@ -484,42 +524,16 @@
1.298 // This is an SQL query, so execute it and format the results
1.299 $limit_sql = " LIMIT {$limits[$i]['offset']},{$limits[$i]['limit']}";
1.300
1.301 - if (is_array($this->_query_arr[$i]['sql']))
1.302 - {
1.303 - $this->_query_arr[$i]['sql']['mysql'] .= $order_sql . $limit_sql;
1.304 - $this->_query_arr[$i]['sql']['mssql'] .= $order_sql . $limit_sql;
1.305 - }
1.306 - else
1.307 - {
1.308 - $this->_query_arr[$i]['sql'] .= $order_sql . $limit_sql;
1.309 + if (is_array($this->_sources_arr[$i]['sql'])) {
1.310 + $this->_sources_arr[$i]['sql']['mysql'] .= $order_sql . $limit_sql;
1.311 + $this->_sources_arr[$i]['sql']['mssql'] .= $order_sql . $limit_sql;
1.312 + } else {
1.313 + $this->_sources_arr[$i]['sql'] .= $order_sql . $limit_sql;
1.314 }
1.315
1.316 - $result = DB_query($this->_query_arr[$i]['sql']);
1.317 -
1.318 - while ($A = DB_fetchArray($result))
1.319 - {
1.320 - $col = array();
1.321 - $col[SQL_TITLE] = $this->_query_arr[$i]['title'];
1.322 - $col[SQL_NAME] = $this->_query_arr[$i]['name'];
1.323 -
1.324 - foreach ($this->_fields as $field)
1.325 - {
1.326 - if (!is_numeric($field['name']) && $field['name'][0] != '_') {
1.327 - if (empty($A[ $field['name'] ])) {
1.328 - $col[ $field['name'] ] = 'LF_NULL';
1.329 - } else {
1.330 - $col[ $field['name'] ] = $A[ $field['name'] ];
1.331 - }
1.332 - }
1.333 - }
1.334 -
1.335 - // Need to call the format function before and after
1.336 - // sorting the results.
1.337 - if (is_callable($this->_function)) {
1.338 - $col = call_user_func_array($this->_function, array(true, $col));
1.339 - }
1.340 -
1.341 - $rows_arr[] = $col;
1.342 + $result = DB_query($this->_sources_arr[$i]['sql']);
1.343 + while ($A = DB_fetchArray($result)) {
1.344 + $rows_arr[] = $this->_fillrow($A, $this->_sources_arr[$i]);
1.345 }
1.346 }
1.347
1.348 @@ -686,7 +700,7 @@
1.349 if ($field['display'] == true)
1.350 {
1.351 $fieldvalue = '';
1.352 - if ($field['name'] == ROW_NUMBER) {
1.353 + if ($field['name'] == LF_ROW_NUMBER) {
1.354 $fieldvalue = $r + $offset;
1.355 } else if (!empty($row[ $field['name'] ])) {
1.356 $fieldvalue = $row[ $field['name'] ];
1.357 @@ -710,7 +724,8 @@
1.358 }
1.359
1.360 // Print page numbers
1.361 - $page_url = $this->_page_url . 'order=' . $this->_sort_arr['field'] . '&direction=' . $this->_sort_arr['direction'] . '&results=' . $this->_per_page;
1.362 + $page_url = $this->_page_url.'order='.$this->_sort_arr['field'] .
1.363 + '&direction='.$this->_sort_arr['direction'].'&results='.$this->_per_page;
1.364 $num_pages = ceil($this->_total_found / $this->_per_page);
1.365 if ($num_pages > 1) {
1.366 $list_templates->set_var('google_paging', COM_printPageNavigation($page_url, $this->_page, $num_pages, 'page=', false, '', ''));