From f4038a2160d55a7f519a3b42be1aa96e29e9a908 Mon Sep 17 00:00:00 2001
From: ftimme <ft@falkotimme.com>
Date: Wed, 27 Feb 2013 09:01:40 -0500
Subject: [PATCH] - Fixed "FUNCTION databasename.CONCAT does not exist" error for older MySQL versions.

---
 interface/lib/classes/aps_crawler.inc.php |  150 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 104 insertions(+), 46 deletions(-)

diff --git a/interface/lib/classes/aps_crawler.inc.php b/interface/lib/classes/aps_crawler.inc.php
index 39375f5..00b1d76 100644
--- a/interface/lib/classes/aps_crawler.inc.php
+++ b/interface/lib/classes/aps_crawler.inc.php
@@ -34,6 +34,9 @@
 
 class ApsCrawler extends ApsBase
 {
+   
+   //public $app_download_url_list = array();
+   
    /**
     * Constructor
     *
@@ -51,6 +54,8 @@
      */
     private function checkRequirements()
     {
+        global $app;
+        
         try
         {
             // Check if allow_url_fopen is enabled
@@ -58,7 +63,7 @@
             // Check if the cURL module is available
             if(!function_exists('curl_version')) throw new Exception('cURL is not available');
             
-            // Check if used folders are writable (chmod 777)
+            // Check if used folders are writable
             if($this->interface_mode)
             {
                 if(!is_writable($this->interface_pkg_dir)) 
@@ -74,7 +79,7 @@
         }
         catch(Exception $e)
         {
-            $this->app->log($this->log_prefix.'Aborting execution because '.$e->getMessage(), LOGLEVEL_ERROR);
+            $app->log($this->log_prefix.'Aborting execution because '.$e->getMessage(), LOGLEVEL_ERROR);
             return false;
         }
     }
@@ -93,7 +98,7 @@
             foreach($files as $file)
             {
                 if($file != '.' && $file != '..')
-                    if(filetype($dir.'/'.$file) == 'dir') rrmdir($dir.'/'.$file); 
+                    if(filetype($dir.'/'.$file) == 'dir') $this->removeDirectory($dir.'/'.$file); 
                     else @unlink($dir.'/'.$file);
             }
             reset($files);
@@ -197,11 +202,12 @@
      * A method to build query URLs out of a list of vendors
      *
     */
-    private function formatVendorCallback(&$array_item, $key)
+    private function formatVendorCallback($array_item)
     {
         $array_item = str_replace(' ', '%20', $array_item);
         $array_item = str_replace('http://', '', $array_item);
         $array_item = '/'.$this->aps_version.'.atom?vendor='.$array_item.'&pageSize=100';
+		return($array_item);
     }
     
     /**
@@ -209,6 +215,8 @@
      */    
     public function startCrawler() 
     {
+        global $app;
+
         try
         {
             // Make sure the requirements are given so that this script can execute
@@ -216,7 +224,7 @@
             if(!$req_ret) return false;
             
             // Execute the open task and first fetch all vendors (APS catalog API 1.1, p. 12)
-            $this->app->log($this->log_prefix.'Fetching data from '.$this->fetch_url);
+            $app->log($this->log_prefix.'Fetching data from '.$this->fetch_url);
 
             $vendor_page = $this->fetchPage('/all-app/'); //$vendor_page = $this->fetchPage('/'.$this->aps_version.'/');
             preg_match_all("/\<a href=\"(.+)\/\" class=\"vendor\"/i", $vendor_page, $matches);
@@ -224,7 +232,12 @@
             if(!$vendors) throw new Exception('Unable to fetch vendors. Aborting');
 
             // Format all vendors for further processing (i.e. typo3.org -> /1.atom?vendor=typo3.org&pageSize=100
-            array_walk($vendors, array($this, 'formatVendorCallback'));
+            //array_walk($vendors, array($this, 'formatVendorCallback'));
+			if(is_array($vendors)) {
+				foreach($vendors as $key => $array_item) {
+					$vendors[$key] = $this->formatVendorCallback($array_item);
+				}
+			}
             
             // Process all vendors in chunks of 50 entries
             $vendor_chunks = array_chunk($vendors, 50);
@@ -233,7 +246,7 @@
             // Get all known apps from the database and the highest known version
             // Note: A dirty hack is used for numerical sorting of the VARCHAR field Version: +0 -> cast
             // A longer but typesafe way would be: ORDER BY CAST(REPLACE(Version, '.', '') AS UNSIGNED) DESC
-            $existing_apps = $this->db->queryAllRecords("SELECT * FROM (
+            $existing_apps = $app->db->queryAllRecords("SELECT * FROM (
                 SELECT name AS Name, CONCAT(version, '-', CAST(`release` AS CHAR)) AS CurrentVersion 
                 FROM aps_packages ORDER BY REPLACE(version, '.', '')+0 DESC, `release` DESC
                 ) as Versions GROUP BY name");
@@ -270,27 +283,30 @@
                         
                         // Find out a (possibly) existing package version
                         $ex_ver = '';
+						/*
                         array_walk($existing_apps, 
                             create_function('$v, $k, $ex_ver', 'if($v["Name"] == "'.$app_name.'") $ex_ver = $v["CurrentVersion"];'), &$ex_ver);
-                        
+                        */
+						if(is_array($existing_apps)) {
+							foreach($existing_apps as $k => $v) {
+								if($v["Name"] == $app_name) $ex_ver = $v["CurrentVersion"];
+							}
+						}
+						
                         $new_ver = $app_version.'-'.$app_release;
                         $local_intf_folder = $this->interface_pkg_dir.'/'.$app_name.'-'.$new_ver.'.app.zip/';
 
                         // Proceed if a newer or at least equal version has been found with server mode or 
-                        // interface mode is activated and there's no valid APP-META.xml existing yet
-                        if((!$this->interface_mode && version_compare($new_ver, $ex_ver) >= 0)
-                         || ($this->interface_mode 
-                              && (!file_exists($local_intf_folder.'APP-META.xml') || filesize($local_intf_folder.'APP-META.xml') == 0)
-                            )
-                        )
-                        {
+                        // interface mode is activated and there are no valid APP-META.xml and PKG_URL existing yet
+                        if((!$this->interface_mode && version_compare($new_ver, $ex_ver) >= 0) || ($this->interface_mode && (!file_exists($local_intf_folder.'APP-META.xml') || filesize($local_intf_folder.'APP-META.xml') == 0 || !file_exists($local_intf_folder.'PKG_URL') || filesize($local_intf_folder.'PKG_URL') == 0))){
                             // Check if we already have an old version of this app
                             if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) $apps_updated++; 
 
                             $app_dl = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@href");
                             $app_filesize = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@length");
                             $app_metafile = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='meta']/@href");
-
+							
+							//$this->app_download_url_list[$app_name.'-'.$new_ver.'.app.zip'] = $app_dl;
                             // Skip ASP.net packages because they can't be used at all
                             $asp_handler = parent::getXPathValue($sxe, '//aspnet:handler');
                             $asp_permissions = parent::getXPathValue($sxe, '//aspnet:permissions');
@@ -307,19 +323,22 @@
                                     if(file_exists($old_folder)) $this->removeDirectory($old_folder);
                                     
 									/*
-                                    $this->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_OUTDATED."' WHERE name = '".
-                                        $this->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '".
-                                        $this->db->quote($ex_ver)."';");
+                                    $app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_OUTDATED."' WHERE name = '".
+                                        $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '".
+                                        $app->db->quote($ex_ver)."';");
 									*/
-									$tmp = $this->db->queryOneRecord("SELECT id FROM aps_packages WHERE name = '".
-                                        $this->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '".
-                                        $this->db->quote($ex_ver)."';");
-									$this->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_OUTDATED, 'id', $tmp['id']);
+									$tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE name = '".
+                                        $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '".
+                                        $app->db->quote($ex_ver)."';");
+									$app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_OUTDATED, 'id', $tmp['id']);
 									unset($tmp);
                                 }
                                 
                                 // Create the local folder if not yet existing
                                 if(!file_exists($local_intf_folder)) @mkdir($local_intf_folder, 0777, true);
+								
+								// Save the package URL in an extra file because it's not part of the APP-META.xml file
+								@file_put_contents($local_intf_folder.'PKG_URL', $app_dl);
                                 
                                 // Download the meta file
                                 $local_metafile = $local_intf_folder.'APP-META.xml';
@@ -428,19 +447,19 @@
                     if($apps_to_dl_chunks[$i][$j]['filesize'] != 0 &&
                        $apps_to_dl_chunks[$i][$j]['filesize'] != filesize($apps_to_dl_chunks[$i][$j]['localtarget']))
                     {
-                            $this->app->log($this->log_prefix.' The filesize of the package "'.
+                            $app->log($this->log_prefix.' The filesize of the package "'.
                                 $apps_to_dl_chunks[$i][$j]['name'].'" is wrong. Download failure?', LOGLEVEL_WARN);
                     }
                 }
             }
             
-            $this->app->log($this->log_prefix.'Processed '.$apps_in_repo.
+            $app->log($this->log_prefix.'Processed '.$apps_in_repo.
                 ' apps from the repo. Downloaded '.$apps_updated.
                 ' updates, '.$apps_downloaded.' new apps');
         }
         catch(Exception $e)
         {
-            $this->app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR);
+            $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR);
             return false;
         }
     }
@@ -454,9 +473,11 @@
      */
     public function parseFolderToDB()
     {
+        global $app;
+        
         try
         {
-            // This method must be used in server mode
+            // This method must be used in interface mode
             if(!$this->interface_mode) return false; 
             
             $pkg_list = array();
@@ -473,15 +494,16 @@
             
             // Get registered packages and mark non-existant packages with an error code to omit the install
             $existing_packages = array();
-            $path_query = $this->db->queryAllRecords('SELECT path AS Path FROM aps_packages;');
+            $path_query = $app->db->queryAllRecords('SELECT path AS Path FROM aps_packages;');
             foreach($path_query as $path) $existing_packages[] = $path['Path']; 
             $diff = array_diff($existing_packages, $pkg_list);
-            foreach($diff as $todelete)
-                /*$this->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_ERROR_NOMETA."' 
-                    WHERE path = '".$this->db->quote($todelete)."';");*/
-				$tmp = $this->db->queryOneRecord("SELECT id FROM aps_packages WHERE path = '".$this->db->quote($todelete)."';");
-				$this->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_ERROR_NOMETA, 'id', $tmp['id']);
+            foreach($diff as $todelete) {
+                /*$app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_ERROR_NOMETA."' 
+                    WHERE path = '".$app->db->quote($todelete)."';");*/
+				$tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE path = '".$app->db->quote($todelete)."';");
+				$app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_ERROR_NOMETA, 'id', $tmp['id']);
 				unset($tmp);
+			}
             
             // Register all new packages
             $new_packages = array_diff($pkg_list, $existing_packages);
@@ -491,7 +513,7 @@
                 $metafile = $this->interface_pkg_dir.'/'.$pkg.'/APP-META.xml';
                 if(!file_exists($metafile)) 
                 {
-                    $this->app->log($this->log_prefix.'Cannot read metadata from '.$pkg, LOGLEVEL_ERROR);
+                    $app->log($this->log_prefix.'Cannot read metadata from '.$pkg, LOGLEVEL_ERROR);
                     continue;
                 }
         
@@ -506,27 +528,63 @@
                 $pkg_category = parent::getXPathValue($sxe, '//category');
                 $pkg_version = parent::getXPathValue($sxe, 'version');
                 $pkg_release = parent::getXPathValue($sxe, 'release');
+				//$pkg_url = $this->app_download_url_list[$pkg];
+				$pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$pkg.'/PKG_URL');
                 
 				/*
-                $this->db->query("INSERT INTO `aps_packages` 
+                $app->db->query("INSERT INTO `aps_packages` 
                     (`path`, `name`, `category`, `version`, `release`, `package_status`) VALUES 
-                    ('".$this->db->quote($pkg)."', '".$this->db->quote($pkg_name)."',
-                    '".$this->db->quote($pkg_category)."', '".$this->db->quote($pkg_version)."',
-                    ".$this->db->quote($pkg_release).", ".PACKAGE_ENABLED.");");
+                    ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."',
+                    '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."',
+                    ".$app->db->quote($pkg_release).", ".PACKAGE_ENABLED.");");
 				*/
+				// Insert only if data is complete
+				if($pkg != '' && $pkg_name != '' && $pkg_category != '' && $pkg_version != '' && $pkg_release != '' && $pkg_url){
+					$insert_data = "(`path`, `name`, `category`, `version`, `release`, `package_url`, `package_status`) VALUES 
+                    ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."',
+                    '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."',
+                    ".$app->db->quote($pkg_release).", '".$app->db->quote($pkg_url)."', ".PACKAGE_ENABLED.");";
 				
-				$insert_data = "(`path`, `name`, `category`, `version`, `release`, `package_status`) VALUES 
-                    ('".$this->db->quote($pkg)."', '".$this->db->quote($pkg_name)."',
-                    '".$this->db->quote($pkg_category)."', '".$this->db->quote($pkg_version)."',
-                    ".$this->db->quote($pkg_release).", ".PACKAGE_ENABLED.");";
-				
-				$this->app->db->datalogInsert('aps_packages', $insert_data, 'id');
+					$app->db->datalogInsert('aps_packages', $insert_data, 'id');
+				} else {
+					if(file_exists($this->interface_pkg_dir.'/'.$pkg)) $this->removeDirectory($this->interface_pkg_dir.'/'.$pkg);
+				}
             }
         }
         catch(Exception $e)
         {
-            $this->app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR);
-			$this->app->error($e->getMessage());
+            $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR);
+			$app->error($e->getMessage());
+            return false;
+        }
+    }
+	
+	/**
+     * Add missing package URLs to database
+     */
+    public function fixURLs()
+    {
+        global $app;
+        
+        try
+        {
+            // This method must be used in interface mode
+            if(!$this->interface_mode) return false; 
+            
+            $incomplete_pkgs = $app->db->queryAllRecords("SELECT * FROM aps_packages WHERE package_url = ''");
+			if(is_array($incomplete_pkgs) && !empty($incomplete_pkgs)){
+				foreach($incomplete_pkgs as $incomplete_pkg){
+					$pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$incomplete_pkg['path'].'/PKG_URL');
+					if($pkg_url != ''){
+						$app->db->datalogUpdate('aps_packages', "package_url = '".$pkg_url."'", 'id', $incomplete_pkg['id']);
+					}
+				}
+			}
+        }
+        catch(Exception $e)
+        {
+            $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR);
+			$app->error($e->getMessage());
             return false;
         }
     }

--
Gitblit v1.9.1