* eTemplate/all apps: (silently) limit number of links shown to 1000 newest, to not run into memory_limit or max_execution_time and assuming noone will scroll further down anyway

This commit is contained in:
Ralf Becker 2013-07-26 09:38:38 +00:00
parent d483b2a564
commit 200a8860bf
3 changed files with 64 additions and 23 deletions

View File

@ -89,6 +89,11 @@ class link_widget
*/ */
const AJAX_NEED_ONCHANGE = 987; const AJAX_NEED_ONCHANGE = 987;
/**
* Limit display of links to given number to not run into memory_limit for huge number of links
*/
const LIMIT_LINKS = 1000;
/** /**
* Constructor of the extension * Constructor of the extension
* *
@ -206,7 +211,8 @@ class link_widget
} }
if ($value['to_id'] && $value['to_app']) if ($value['to_id'] && $value['to_app'])
{ {
$value = egw_link::get_links($value['to_app'],$value['to_id'],$only_app = $value['only_app'],'link_lastmod DESC',true, $value['show_deleted']); $value = egw_link::get_links($value['to_app'], $value['to_id'], $only_app = $value['only_app'],
'link_lastmod DESC', true, $value['show_deleted'], self::LIMIT_LINKS);
if ($only_app) if ($only_app)
{ {
foreach($value as $key => $id) foreach($value as $key => $id)
@ -283,7 +289,7 @@ class link_widget
{ {
$value['title'] = egw_link::title($app,$id); $value['title'] = egw_link::title($app,$id);
} }
$links = egw_link::get_links($app,$id,'','link_lastmod DESC',true, $value['show_deleted']); $links = egw_link::get_links($app, $id, '', 'link_lastmod DESC', true, $value['show_deleted'], self::LIMIT_LINKS);
$value['anz_links'] = count($links); $value['anz_links'] = count($links);
$extension_data = $value; $extension_data = $value;

View File

@ -8,7 +8,7 @@
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright 2001-2011 by RalfBecker@outdoor-training.de * @copyright 2001-2013 by RalfBecker@outdoor-training.de
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api * @package api
* @subpackage link * @subpackage link
@ -370,15 +370,16 @@ class egw_link extends solink
* returns array of links to $app,$id (reimplemented to deal with not yet created items) * returns array of links to $app,$id (reimplemented to deal with not yet created items)
* *
* @param string $app appname * @param string $app appname
* @param string/array $id id of entry in $app or array of links if entry not yet created * @param string|array $id id(s) in $app
* @param string $only_app if set return only links from $only_app (eg. only addressbook-entries) or NOT from if $only_app[0]=='!' * @param string $only_app='' if set return only links from $only_app (eg. only addressbook-entries) or NOT from if $only_app[0]=='!'
* @param string $order='link_lastmod DESC' defaults to newest links first * @param string $order='link_lastmod DESC' defaults to newest links first
* @param boolean $cache_titles=false should all titles be queryed and cached (allows to query each link app only once!) * @param boolean $cache_titles=false should all titles be queryed and cached (allows to query each link app only once!)
* This option also removes links not viewable by current user from the result! * This option also removes links not viewable by current user from the result!
* @param boolean $deleted Include links that have been flagged as deleted, waiting for purge. * @param boolean $deleted=false Include links that have been flagged as deleted, waiting for purge of linked record.
* @return array of links or empty array if no matching links found * @param int $limit=null number of entries to return, only affects links, attachments are allways reported!
* @return array id => links pairs if $id is an array or just the links (only_app: ids) or empty array if no matching links found
*/ */
static function get_links( $app,$id,$only_app='',$order='link_lastmod DESC',$cache_titles=false,$deleted=false ) static function get_links($app, $id, $only_app='', $order='link_lastmod DESC',$cache_titles=false, $deleted=false, $limit=null)
{ {
if (self::DEBUG) echo "<p>egw_link::get_links(app='$app',id='$id',only_app='$only_app',order='$order',deleted='$deleted')</p>\n"; if (self::DEBUG) echo "<p>egw_link::get_links(app='$app',id='$id',only_app='$only_app',order='$order',deleted='$deleted')</p>\n";
@ -402,7 +403,7 @@ class egw_link extends solink
} }
return $ids; return $ids;
} }
$ids = solink::get_links($app,$id,$only_app,$order,$deleted); $ids = solink::get_links($app, $id, $only_app, $order, $deleted, $limit);
if (empty($only_app) || $only_app == self::VFS_APPNAME || if (empty($only_app) || $only_app == self::VFS_APPNAME ||
($only_app[0] == '!' && $only_app != '!'.self::VFS_APPNAME)) ($only_app[0] == '!' && $only_app != '!'.self::VFS_APPNAME))
{ {

View File

@ -8,7 +8,7 @@
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright 2001-2008 by RalfBecker@outdoor-training.de * @copyright 2001-2013 by RalfBecker@outdoor-training.de
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api * @package api
* @subpackage link * @subpackage link
@ -44,6 +44,10 @@ class solink
* @var int * @var int
*/ */
protected static $user; protected static $user;
/**
* True if call to get_links or get_3links exceeded limit (contains not all rows)
*/
public static $limit_exceeded = false;
/** /**
* creats a link between $app1,$id1 and $app2,$id2 * creats a link between $app1,$id1 and $app2,$id2
@ -113,13 +117,14 @@ class solink
* returns array of links to $app,$id * returns array of links to $app,$id
* *
* @param string $app appname * @param string $app appname
* @param string/array $id id(s) in $app * @param string|array $id id(s) in $app
* @param string $only_app if set return only links from $only_app (eg. only addressbook-entries) or NOT from if $only_app[0]=='!' * @param string $only_app='' if set return only links from $only_app (eg. only addressbook-entries) or NOT from if $only_app[0]=='!'
* @param string $order defaults to newest links first * @param string $order='link_lastmod DESC' defaults to newest links first
* @param boolean $deleted Include links that have been flagged as deleted, waiting for purge of linked record. * @param boolean $deleted=false Include links that have been flagged as deleted, waiting for purge of linked record.
* @param int|array $limit=null number of entries to return, default null = all or array(offset, num_rows) to return num_rows starting from offset
* @return array id => links pairs if $id is an array or just the links (only_app: ids) or empty array if no matching links found * @return array id => links pairs if $id is an array or just the links (only_app: ids) or empty array if no matching links found
*/ */
static function get_links( $app,$id,$only_app='',$order='link_lastmod DESC',$deleted=false ) static function get_links($app, $id, $only_app='', $order='link_lastmod DESC', $deleted=false, $limit=null)
{ {
if (self::DEBUG) if (self::DEBUG)
{ {
@ -129,7 +134,17 @@ class solink
{ {
$only_app = substr($only_app,1); $only_app = substr($only_app,1);
} }
#var_dump($not_only);echo "$only_app<br>";
$offset = false;
if (is_array($limit))
{
list($offset, $limit) = $limit;
}
elseif($limit)
{
$offset = 0;
}
$links = array(); $links = array();
foreach(self::$db->select(self::TABLE, '*', self::$db->expression(self::TABLE, '((', array( foreach(self::$db->select(self::TABLE, '*', self::$db->expression(self::TABLE, '((', array(
'link_app1' => $app, 'link_app1' => $app,
@ -139,7 +154,7 @@ class solink
'link_id2' => $id, 'link_id2' => $id,
),'))', ),'))',
$deleted ? '' : ' AND deleted IS NULL' $deleted ? '' : ' AND deleted IS NULL'
),__LINE__,__FILE__,False,$order ? " ORDER BY $order" : '') as $row) ), __LINE__, __FILE__, $offset, $order ? " ORDER BY $order" : '', 'phpgwapi', $limit) as $row)
{ {
// check if left side (1) is one of our targets --> add it // check if left side (1) is one of our targets --> add it
if ($row['link_app1'] == $app && in_array($row['link_id1'],(array)$id)) if ($row['link_app1'] == $app && in_array($row['link_id1'],(array)$id))
@ -152,6 +167,9 @@ class solink
self::_add2links($row,false,$only_app,$not_only,$links); self::_add2links($row,false,$only_app,$not_only,$links);
} }
} }
// if query returns exactly limit rows, we assume there are more and therefore set self::$limit_exceeded
self::$limit_exceeded = $offset !== false && count(is_array($id) ? $links : $links[$id]) == $limit;
return is_array($id) ? $links : ($links[$id] ? $links[$id] : array()); return is_array($id) ? $links : ($links[$id] ? $links[$id] : array());
} }
@ -361,16 +379,18 @@ class solink
* ^ ^ * ^ ^
* +---------------------------c-----------------------------------------+ * +---------------------------c-----------------------------------------+
* *
* bolink::get_3links('timesheet','projectmanager',$pm_id) returns the links (c) between the timesheet and the project, * egw_link::get_3links('timesheet','projectmanager',$pm_id) returns the links (c) between the timesheet and the project,
* plus the other app/id in the keys 'app3' and 'id3' * plus the other app/id in the keys 'app3' and 'id3'
* *
* @param string $app app the returned links are linked on one side (atm. this must be link_app1!) * @param string $app app the returned links are linked on one side (atm. this must be link_app1!)
* @param string $target_app app the returned links other side link also to * @param string $target_app app the returned links other side link also to
* @param string/array $target_id=null id(s) the returned links other side link also to * @param string|array $target_id=null id(s) the returned links other side link also to
* @param boolean $just_app_ids=false return array with link_id => app_id pairs, not the full link record * @param boolean $just_app_ids=false return array with link_id => app_id pairs, not the full link record
* @param string $order='link_lastmod DESC' defaults to newest links first
* @param int|array $limit=null number of entries to return, default null = all or array(offset, num_rows) to return num_rows starting from offset
* @return array with links from entries from $app to $target_app/$target_id plus the other (b) link_id/app/id in the keys 'link3'/'app3'/'id3' * @return array with links from entries from $app to $target_app/$target_id plus the other (b) link_id/app/id in the keys 'link3'/'app3'/'id3'
*/ */
static function get_3links($app,$target_app,$target_id=null,$just_app_ids=false) static function get_3links($app, $target_app, $target_id=null, $just_app_ids=false, $order='link_lastmod DESC', $limit=null)
{ {
$table = self::TABLE; $table = self::TABLE;
$arrayofselects=array( $arrayofselects=array(
@ -402,8 +422,19 @@ class solink
JOIN $table c ON a.link_id2=c.link_id2 AND a.link_app2=c.link_app2 AND a.link_id!=c.link_id AND c.link_app1=b.link_app1 AND c.link_id1=b.link_id1", JOIN $table c ON a.link_id2=c.link_id2 AND a.link_app2=c.link_app2 AND a.link_id!=c.link_id AND c.link_app1=b.link_app1 AND c.link_id1=b.link_id1",
), ),
); );
$offset = false;
if (is_array($limit))
{
list($offset, $limit) = $limit;
}
elseif($limit)
{
$offset = 0;
}
$links = array(); $links = array();
foreach(self::$db->union($arrayofselects,__LINE__,__FILE__) as $row) foreach(self::$db->union($arrayofselects, __LINE__, __FILE__, $order, $offset, $limit) as $row)
{ {
if ($just_app_ids) if ($just_app_ids)
{ {
@ -421,6 +452,9 @@ class solink
$links[] = egw_db::strip_array_keys($row,'link_'); $links[] = egw_db::strip_array_keys($row,'link_');
} }
} }
// if query returns exactly limit rows, we assume there are more and therefore set self::$limit_exceeded
self::$limit_exceeded = $offset !== false && count($links) == $limit;
return $links; return $links;
} }