Timeout bei Aufruf der Frontend-Gruppenberechtigungen

Gesperrt
achiboy
Beiträge: 138
Registriert: Do 26. Aug 2004, 05:05
Kontaktdaten:

Timeout bei Aufruf der Frontend-Gruppenberechtigungen

Beitrag von achiboy » Di 5. Aug 2008, 05:24

Hallo

Mit Contenido 4.8.7 kriege ich beim Aufruf der Frontend-Berechtigungen einer Gruppe einen Timeout.

[05-Aug-2008 06:14:49] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /xxx/xxx/xxx/contenido/includes/functions.general.php on line 761

tono
Beiträge: 574
Registriert: Mo 25. Apr 2005, 20:51
Wohnort: Frankfurt am Main
Kontaktdaten:

Beitrag von tono » Di 5. Aug 2008, 10:32

Wieviele Kategorien hast Du?
Wieviele davon sind geschützt?
Tritt das Problem nur mit einer Gruppe auf?
Gibt es Einträge im Errorlog?
Bis dann
Tono

achiboy
Beiträge: 138
Registriert: Do 26. Aug 2004, 05:05
Kontaktdaten:

Beitrag von achiboy » Mi 6. Aug 2008, 08:41

Es sind etwa 60 Kategorien.
Davon sind 10 geschützt.
Das Problem tritt bei allen Gruppen auf
Es gibt keine Errorlog-Einträge ausser der geposteten Fehlermeldung

Das Problem tritt bei all meinen Installationen mit der aktuellsten Version auf.

tono
Beiträge: 574
Registriert: Mo 25. Apr 2005, 20:51
Wohnort: Frankfurt am Main
Kontaktdaten:

Beitrag von tono » Mi 6. Aug 2008, 09:10

Ist die angegebene Datei und Zeilennummer immer gleich? Warscheinlich nicht, oder?

Hast Du mal geschaut, ob irgendwelche Datenbanktabellen optimiert oder repariert werden müssten? (mit phpmyadmin z.B.)
Bis dann
Tono

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 09:47

verschoben

Ich kann das nachvollziehen. Einfacher Test: lokal auf meinem XAMPP mit allen Kategorien des Beispielmandanten geschützt liegt die Ausführungszeit bei über 30 Sekunden.

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 09:49

Habe folgendes gerade im SVN eingecheckt:

Datei "contenido/plugins/frontendlogic/category/category.php" ändern zu:

Code: Alles auswählen

<?php
/**
 * Project: 
 * Contenido Content Management System
 * 
 * Description: 
 * 
 * Requirements: 
 * @con_php_req 5.0
 * 
 *
 * @package    Contenido Backend classes
 * @version    1.1.1
 * @author     Andreas Lindner, Unknown
 * @copyright  four for business AG <www.4fb.de>
 * @license    http://www.contenido.org/license/LIZENZ.txt
 * @link       http://www.4fb.de
 * @link       http://www.contenido.org
 * 
 * {@internal 
 *   created
 *   modified 2008-08-06, Ingo van Peeren - replaced genericdb-code due to performance issues (ticket #)
 *
 *   $Id: 
 * }}
 * 
 */
 
if(!defined('CON_FRAMEWORK')) {
	die('Illegal call');
}

cInclude("classes", "class.frontend.logic.php");

class frontendlogic_category extends FrontendLogic
{
	function getFriendlyName ()
	{
		return i18n("Category", "frontendlogic_category");	
	}
	
	function listActions ()
	{
		$actions = array();
		$actions["access"] = i18n("Access category", "frontendlogic_category");
		
		return ($actions);	
	}
	
	function listItems ()
	{
		global $lang, $db, $cfg;
		
		if (!is_object($db)) {
            $db = new DB_Contenido;
        }
        
        $sSQL = "SELECT
                   b.idcatlang,
                   b.name,
                   c.level
                 FROM
                   ".$cfg['tab']['cat']." AS a,
                   ".$cfg['tab']['cat_lang']." AS b,
                   ".$cfg['tab']['cat_tree']." AS c
                 WHERE
                   a.idcat = b.idcat AND
                   a.idcat = c.idcat AND
                   b.idlang = ".$lang." AND
                   b.public = 0
                 ORDER BY c.idtree ASC";

        $db->query($sSQL);
        while ($db->next_record()) {
            $items[$db->f("idcatlang")] = 
				'<span style="padding-left: '.($db->f("level")*10).'px;">'.htmldecode($db->f("name")).'</span>';
			
        }
		
		return ($items);
	}
}
?>
Gleiche Liste wird bei mir dann in 0,07 Sekunden erzeugt.

tono
Beiträge: 574
Registriert: Mo 25. Apr 2005, 20:51
Wohnort: Frankfurt am Main
Kontaktdaten:

Beitrag von tono » Mi 6. Aug 2008, 10:22

Ich konnte das Problem nicht reproduzieren.
Von > 30 sec. auf 0,7 nur durch weglassen der genericdb?? Da steckt doch garantiert ein Bug drin. Soviel Overhead produziert das auch wieder nicht.
Bis dann
Tono

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 10:45

Ich habe einfach mit dem Beispielmandanten lokal auf XAMPP getestet. Mit einer geschützten Kategorie lag ich bei ca. 1 Sekunde. Je weiterer Kategorie kommt nochmal dasselbe hinzu.
Das lässt sich auch auf meinem Webserver reproduzieren. Dort zurzeit mit ca. 1,9 Sekunden je Kategorie.

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 11:05

Das Problem tritt anscheinend durch das Hinzufügen des 2. JOIN auf:

Code: Alles auswählen

$cApiCategoryCollection->link("cApiCategoryTreeCollection");

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 11:26

OK, fieser Bug. Aber wo ganz anders: "contenido/classes/drivers/mysql/class.gdb.mysql.php".

Die Methode "buildJoinQuery" macht folgendes:

Code: Alles auswählen

$join   = "LEFT JOIN $destinationTable AS $destinationClass ON " . Contenido_Security::toInteger($sourceClass.$primaryKey) . " = " . Contenido_Security::toInteger($destinationClass.$primaryKey);
Das ist resultiert dann in einem

Code: Alles auswählen

ON 0 = 0

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Mi 6. Aug 2008, 12:01

OK, sehe gerade, das ist im SVN schon gefixt.

"contenido/classes/drivers/mysql/class.gdb.mysql.php" ändern in:

Code: Alles auswählen

<?php
/**
 * Project: 
 * Contenido Content Management System
 * 
 * Description: 
 * MySQL Driver for GenericDB 
 * 
 * Requirements: 
 * @con_php_req 5.0
 * 
 *
 * @package    Contenido Backend classes
 * @version    1.12
 * @author     Bjoern Behrens
 * @copyright  four for business AG <www.4fb.de>
 * @license    http://www.contenido.org/license/LIZENZ.txt
 * @link       http://www.4fb.de
 * @link       http://www.contenido.org
 * 
 * {@internal 
 *   created 2006-05-10
 *   modified 2008-05-23 Added Debug_DevNull and Debug_VisibleAdv
 *   
 *   $Id: class.gdb.mysql.php 659 2008-08-04 22:17:55Z HerrB $
 * }}
 * 
 */

if(!defined('CON_FRAMEWORK')) {
	die('Illegal call');
}


cInclude("classes", 'drivers/class.gdb.driver.php');
cInclude("classes", "class.security.php");

class gdbMySQL extends gdbDriver
{
	function buildJoinQuery ($destinationTable, $destinationClass, $destinationPrimaryKey, $sourceClass, $primaryKey)
	{
		// Build a regular LEFT JOIN
		$field  = "$destinationClass.$destinationPrimaryKey";
		$tables = "";
		$join   = "LEFT JOIN $destinationTable AS $destinationClass ON " . 
					Contenido_Security::toString($sourceClass . "." . $primaryKey) . " = " .  
					Contenido_Security::toString($destinationClass . "." . $primaryKey);
		$where  = "";
		
		return array("field" => $field, "table" => $tables, "join" => $join, "where" => $where);
	}
	
	function buildOperator ($sField, $sOperator, $sRestriction)
	{
		$sOperator = strtolower($sOperator);
		
		$sWhereStatement = "";
		
		switch ($sOperator)
		{
			case "matchbool":
				$sqlStatement = "MATCH (%s) AGAINST ('%s' IN BOOLEAN MODE)";
				$sWhereStatement = sprintf($sqlStatement, $sField, $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "match":
				$sqlStatement = "MATCH (%s) AGAINST ('%s')";
				$sWhereStatement = sprintf($sqlStatement, $sField, $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "like":
				$sqlStatement = "%s LIKE '%%%s%%'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "likeleft":
				$sqlStatement = "%s LIKE '%s%%'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "likeright":
				$sqlStatement = "%s LIKE '%%%s'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "notlike":
				$sqlStatement = "%s NOT LIKE '%%%s%%'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "notlikeleft":
				$sqlStatement = "%s NOT LIKE '%s%%'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;
			case "notlikeright":
				$sqlStatement = "%s NOT LIKE '%%%s'";
				$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
				break;				
			case "diacritics":
				cInclude("classes", "class.chartable.php");
				if (!is_object($GLOBALS["_cCharTable"]))
				{
					$GLOBALS["_cCharTable"] = new cCharacterConverter;
				}

				$aliasSearch = array ();

				$metaCharacters = array ("*", "[", "]", "^", '$', "\\", "*", "'", '"', '+');

				for ($i = 0; $i < strlen($sRestriction); $i ++)
				{
					$char = substr($sRestriction, $i, 1);

					$aliases = array ();

					$aliases = array_merge($aliases, $GLOBALS["_cCharTable"]->fetchDiacriticCharactersForNormalizedChar($this->_sEncoding, $char));
					$normalizedChars = $GLOBALS["_cCharTable"]->fetchNormalizedCharsForDiacriticCharacter($this->_sEncoding, $char);

					foreach ($normalizedChars as $normalizedChar)
					{
						$aliases = array_merge($aliases, $GLOBALS["_cCharTable"]->fetchDiacriticCharactersForNormalizedChar($this->_sEncoding, $normalizedChar));
					}

					$aliases = array_merge($aliases, $normalizedChars);

					if (count($aliases) > 0)
					{
						$aliases[] = $char;
						$allAliases = array ();

						foreach ($aliases as $alias)
						{
							$alias1 = $this->_oItemClassInstance->_inFilter($alias);
							$allAliases[] = $alias1;
							$allAliases[] = $alias;
						}

						$allAliases = array_unique($allAliases);
						$aliasSearch[] = "(".implode("|", $allAliases).")";

					} else
					{
						$addChars = array();
						
						
                        
						if (in_array($char, $metaCharacters))
						{
							$addChars[] = "\\\\".$char;
						} else
						{
                            $addChars[] = $char;
                            
							$vChar = $this->_oItemClassInstance->_inFilter($char);
                            
                            if ($char != $vChar)
                            {
                                if (in_array($vChar, $metaCharacters))
                                {
                                    $addChars[] = "\\\\".$vChar;
                                } else {
                                    $addChars[] = $vChar;	
                                }
                            }
						}
                        
                        $aliasSearch[] = "(".implode("|", $addChars).")";
					}
				}

				$restriction = "'".implode("", $aliasSearch)."'";
				$sWhereStatement = implode(" ", array ($sField, "REGEXP", $restriction));

				break;
			case "fulltext":
				
				break;
			case "in":
				if (is_array($sRestriction))
				{
					$items = array();
					
					foreach ($sRestriction as $key => $sRestrictionItem)
					{
						$items[] = "'".$this->_oItemClassInstance->_inFilter($sRestrictionItem)."'";
					}
					
					$sRestriction = implode(", ", $items);
				} else {
					$sRestriction = "'" . $sRestriction ."'";	
				}
				
				$sWhereStatement = implode(" ", array($sField, "IN (", $sRestriction, ")"));
				break; 
			default :
				$sRestriction = "'".$this->_oItemClassInstance->_inFilter($sRestriction)."'";
				
				$sWhereStatement = implode(" ", array ($sField, $sOperator, $sRestriction));
				
		}
		
		return $sWhereStatement;
		
	}	
}
?>

tono
Beiträge: 574
Registriert: Mo 25. Apr 2005, 20:51
Wohnort: Frankfurt am Main
Kontaktdaten:

Beitrag von tono » Mi 6. Aug 2008, 14:57

Dodger77 hat geschrieben:OK, sehe gerade, das ist im SVN schon gefixt.
Dann ist das auch der Grund warum der Fehler bei mir nicht reproduzierbar war.
Bis dann
Tono

achiboy
Beiträge: 138
Registriert: Do 26. Aug 2004, 05:05
Kontaktdaten:

Beitrag von achiboy » Fr 8. Aug 2008, 05:42

muss ich die erste Änderung in der Datei "contenido/plugins/frontendlogic/category/category.php" rückgängig machen?

Dodger77
Beiträge: 3626
Registriert: Di 12. Okt 2004, 20:00
Wohnort: Voerde (Niederrhein)
Kontaktdaten:

Beitrag von Dodger77 » Fr 8. Aug 2008, 06:22

Die kannst du auch problemlos so lassen.

achiboy
Beiträge: 138
Registriert: Do 26. Aug 2004, 05:05
Kontaktdaten:

Beitrag von achiboy » Fr 8. Aug 2008, 06:23

besten Dank für eure Hilfe.

Gesperrt