Home » Tips&Tricks » [RAW FIX] – JOOMLA – Errore 500 in “Gestione Media” (com_media)

[RAW FIX] – JOOMLA – Errore 500 in “Gestione Media” (com_media)

Come feci in occasione del problema nell‘upload delle immagini in Virtuemart, questa volta vi illustro un tricks per risolvere un fastidioso problema che si può avere con il Joomla (solo nelle versioni 1.5.x) quando le cartelle “images” e “media” raggiungono una dimensione e un numero di file/cartelle elevato.

Questo CMS di default (personalmente non ne capisco il motivo) ha abilitata la “ricerca ricorsiva” per tutto ciò che riguarda l’elencazione (listing) di file e cartelle di una path. In questo caso in particolare mi riferisco al componente “com_media” che si occupa della gestione dei contenuti multimediali quali foto e video. Nella pagina principale dell’Amministrazione del Joomla andando su “Gestione Media” si accede ad un interfaccia stile “client ftp” che permette di navigare all’interno delle cartelle “images” e “media” ed eseguire le normali operazioni di cancellazione/modifica/etc su file e cartelle in esse contenute.

Il problema sorge quando il numero di file contenuti in queste due cartelle raggiunge dimensioni tali da non rendere possibile il listing di tutto il contenuto nei 120 secondi di Timeout impostati sul Server (tranne servizi dedicati appostivamente al Joomla i normali Hosting Provider impostano il max_execution_time a 120 secondi). Al termine di tale tempo se l’operazione non è completata, a seconda della configurazione e della versione del WebServer, viene mostrato l’errore “500 Internal Server Error” o “504 Gateway Timeout“. Tradotto in parole povere significa che lo script ha provato ad eseguire l’operazione ma il processo era ancora in corso trascorsi 2 minuti e pertanto è stato bloccato.

Per disabilitare la “ricerca ricorsiva”, quindi, è necessario aprire il file “manager.php” presente nella path:

<root_di_Joomla>/administrator/components/com_media/models/manager.php

e successivamente posizionarsi alle Righe 63 e 102 che appariranno così:


$folders = JFolder::folders($base, '.', true, true);


e modificarle variando il 1° true su false come di seguito:


$folders = JFolder::folders($base, '.', false, true);


Di seguito le prime righe della funzione che viene richiamata che dimostrano che il parametro variato va a disabilitare la ricorsione.


	/**
	 * Utility function to read the folders in a folder.
	 *
	 * @param	string	The path of the folder to read.
	 * @param	string	A filter for folder names.
	 * @param	mixed	True to recursively search into sub-folders, or an
	 * integer to specify the maximum depth.
	 * @param	boolean	True to return the full path to the folders.
	 * @param	array	Array with names of folders which should not be shown in
	 * the result.
	 * @return	array	Folders in the given folder.
	 * @since 1.5
	 */
	function folders($path, $filter = '.', $recurse = false, $fullpath = false, $exclude = array('.svn', 'CVS'))
	{
		// Initialize variables
		$arr = array();
 
		// Check to make sure the path valid and clean
		$path = JPath::clean($path);
 
		// Is the path a folder?
		if (!is_dir($path)) {
			JError::raiseWarning(21, 'JFolder::folder: ' . JText::_('Path is not a folder'), 'Path: ' . $path);
			return false;
		}
 
		// read the source directory
		$handle = opendir($path);
		while (($file = readdir($handle)) !== false)
		{
			if (($file != '.') &amp;&amp; ($file != '..') &amp;&amp; (!in_array($file, $exclude))) {
				$dir = $path . DS . $file;
				$isDir = is_dir($dir);
				if ($isDir) {
					// Removes filtered directories
					if (preg_match("/$filter/", $file)) {
						if ($fullpath) {
							$arr[] = $dir;
						} else {
							$arr[] = $file;
						}
					}
					if ($recurse) {
						if (is_integer($recurse)) {
							$arr2 = JFolder::folders($dir, $filter, $recurse - 1, $fullpath);
						} else {
							$arr2 = JFolder::folders($dir, $filter, $recurse, $fullpath);
						}
 
						$arr = array_merge($arr, $arr2);
					}
				}
			}
		}
		closedir($handle);
 
		asort($arr);
		return $arr;
	}


Come spiegato nei commenti della funzione stessa l’impostare su “false” il 3° parametro disabilita la ricorsione evitando il manifestarsi dell’errore di Timeout.
In alternativa è possibile modificare il parametro inserendo un valore numerico intero. Così facendo si indicano quanti livelli deve scendere nella ricerca dei file/cartelle.

Esempio della modifica da apportare se si vuole che la ricerca scenda al massimo di 3 livelli, ossia:

<root_di_Joomla>/images/cartella1/cartella2/cartella3

La riga andrebbe modificata nel seguente modo:


$folders = JFolder::folders($base, '.', 3, true);


Fatto ciò il problema sarò risolto e all’apertura del “com_media” verrà effettuata la ricerca per le sole cartelle “images” e “media” e per il numero di livelli da voi impostato. Tale modifica crea un piccolo problema visivo che, a mio avviso, non è molto rilevante poiché disabilitando la ricorsività dal menu ad albero del “Gestione Media” non si potrà vedere il solito “+” davanti alle cartelle che ne contengono delle altre. Analizzando solo il primo livello delle cartelle non può creare l’albero di navigazione fin da subito e pertanto si aggiornerà man mano che si scende nelle sottocartelle.

Per un problema risolto ritengo sia una piccola perdita.

Ti è stato utile? Votalo!
[Voti: 0    Media Voto: 0/5]
  • Andrea Pisanu

    Salve, a me questa soluzione non da risultati :/ Nel mio caso non riesco a fare l’upload di immagini che richiedono più di 120 secondi di tempo per essere caricate. Si tratta di immagini di inserzioni con Adsmanager. Riesco solo con linee veloci in upload, altrimenti “Error 500”, soluzioni? Ringrazio.

    • Ciao Andrea,

      la patch è del 2009 quindi credo che ormai sia obsoleta visto che era per joomla 1.5 se non erro.

      Se l’upload richiede più di 120 secondi mi viene da pensare che le immagini sono veramente grandi. Non so se Joomla applica un resize in automatico ma se così fosse potrebbe trattarsi di un problema di memoria (il resize delle immagini è molto esoso in termini di ram).
      Se puoi prova ad alzare il memory limit o a controllare i file di log

  • m.cecili

    immagino che passare dalla 1.0 alla 1.5.x non sia proprio indolore..

    • con jupgrade si riesce a fare.
      Visto che comunque va fatto.. dal mio punto di vista i siti con 1.0.x di Joomla hanno le ore contate perché comunque prima o poi arriverà qualcuno che proverà a sfruttare una delle numerose falle che ha.

      Passare alla 1.5.x non ha senso perché verrà abbandonata prossimamente e anche questa ha i suoi problemi.

      Dato che dovrai fare l’upgrade vale la pena passare a 1.7.3 anche perché stando alla roadmap dei ragazzi di Joomla le altre versioni prima o poi verranno abbandonate.

      ciao

  • m.cecili

    Ho provato anche io la tua modifica e funziona correttamente.
    Avevo pensato anche io di aggiornare la versione di joomla, gestisco infatti un altro sito con la versione 1.5.9 e non ho di questi problemi, a parte un problema secondo me molto simile con il componente phoca gallery, con il quale devo fare lo stesso gioco di rinominare le cartelle per poter acceddere senza errore di timeout alla pagine delle immagini per poter fare upload massivi, anche in questo caso dovrei aggiornare phoca gallery all’ultima versione che credo risolva il problema..
    Tornando sul pezzo: Quanto è rischioso / complicato aggiornare “a caldo” una versione di joomla?

    • ciao,
      son contento che abbia funzionato 😉

      Per quanto riguarda l’aggiornamento di Joomla tra versioni della stessa famiglia da 1.5.x a 1.5.xx non è molto rischioso.
      Non avvengono modifiche sostanziali al Db e l’upgrade consiste nel sovrascrivere i file precedenti con i nuovi quasi sempre.

      Le migrazioni invece ossia passare da 1.5.x a 1.7.x per esempio, sono un po più complicate in quanto eseguono varie operazioni a livello di Database dato che devono importare i dati della precedente versione nella nuova struttura.

      Anceh in questo caso, però, l’operazione si riesce a fare senza troppi problemi.

      Il componente jUpgrade permette di farlo in modalità quasi innocua creando un nuovo sito con la versione nuova e i tuoi precedenti dati evitando, così, che i dati originali vengano in qualche modo alterati.

      ciao

  • m.cecili

    Esiste una soluzione simile per joomla 1.0?
    Ho lo stesso problema ed al momento l’unica soluzione è rinominare images in _images, fare le modifiche agli articoli. Al terminare rinominare la cartella in images.
    In joomla 1.0 il codice di ricorsiva si trova nel file
    miosito/administrator/components/com_media/admin.media.php

    /**
    * Show media manager
    * @param string The image directory to display
    */
    function showMedia($listdir) {
    global $mosConfig_live_site;

    // get list of directories
    $imgFiles = recursive_listdir( COM_MEDIA_BASE );
    $images = array();
    $folders = array();
    $folders[] = mosHTML::makeOption( “/” );

    $len = strlen( COM_MEDIA_BASE );
    foreach ($imgFiles as $file) {
    $folders[] = mosHTML::makeOption( substr( $file, $len ) );
    }
    if (is_array( $folders )) {
    sort( $folders );
    }
    // create folder selectlist
    $dirPath = mosHTML::selectList( $folders, ‘dirPath’, “class=\”inputbox\” size=\”1\” onchange=\”goUpDir()\” “, ‘value’, ‘text’, $listdir );

    HTML_Media::showMedia( $dirPath, $listdir );
    }

    Come la modificheresti?

    • ciao,
      in primi ti direi di aggiornare quanto prima alle versioni più recenti dato che le vulnerabilità note per quella versione non si contano.
      Detto questo ho dato un’occhiata veloce ai file della versione 1.0.15 e l’unica cosa che mi viene in mente che puoi tentare è quella di commentare la riga 225 del file: components/com_media/admin.media.php.

      Dovresti trovare questo codice:

      function recursive_listdir( $base ) {
      static $filelist = array();
      static $dirlist = array();

      if(is_dir($base)) {
      $dh = opendir($base);
      while (false !== ($dir = readdir($dh))) {
      if ($dir !== ‘.’ && $dir !== ‘..’ && is_dir($base .’/’. $dir) && strtolower($dir) !== ‘cvs’ && strtolower($d
      ir) !== ‘.svn’) {
      $subbase = $base .’/’. $dir;
      $dirlist[] = $subbase;
      $subdirlist = recursive_listdir($subbase);
      }
      }
      closedir($dh);
      }
      return $dirlist;
      }

      Proverei a togliere la riga seguente o a mettere il cancelletto davanti alla stessa per commenarlo:

      #$subdirlist = recursive_listdir($subbase);

      Fammi sapere se risolvi.

      Buona giornata

      capn3m0

  • Giuseppe

    Grazie mille! Mi è stato utilissimo per risolvere il fastidioso errore “504 Gateway Timeout”.

Altro... com_media, internal server error
Chiudi