Source for file CMS3_PackageManager.php

Documentation is available at CMS3_PackageManager.php

  1. <?php     
  2. //          (F)
  3. // CMS3 - A Three Content Management System.
  4. // Copyright (C) 2007  Jop... (Jonas F. Jensen).
  5. // 
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU General Public License
  8. // as published by the Free Software Foundation; either version 2
  9. // of the License, or (at your option) any later version.
  10. // 
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  19.  
  20. /**
  21. *This file defines CMS3_PackageManager
  22. *
  23. @package    System
  24. @author    Jonas F. Jensen <jopsen@gmail.com>
  25. @copyright    2007 Jonas F. Jensen.
  26. @license    http://www.gnu.org/licenses/gpl.txt
  27. */
  28.  
  29. /**
  30.  *PackageManager provides the logic for installation and removal of packages.
  31.  *
  32.  *This plugin doesn't provide any user interface only API interface for package operations.
  33.  */
  34. {
  35.         //Exposed API
  36.  
  37.     
  38.     /**
  39.     *Verifies and installs a package
  40.     */
  41.     public function InstallPackage($PluginID)
  42.     {
  43.         //TODO detect some of the worst errors and log them
  44.  
  45.         //Check to see if the package exists
  46.         $PackagePath $this->Owner->GetCMS3Path("data/PackageManager/packages/" $PluginID ".c3p";
  47.         if(file_exists($PackagePath)){
  48.  
  49.             //make sure theres a temp dir
  50.             if(is_dir("/tmp/C3pkg/")){
  51.                 //If our tmp dir exists clean it
  52.                 shell_exec("rm /tmp/C3pkg/*");
  53.             }else{
  54.                 //if not create it.
  55.                 shell_exec("mkdir /tmp/C3pkg/");                
  56.             }
  57.  
  58.             //copy the package
  59.             shell_exec("cp " $PackagePath " /tmp/" $PluginID ".c3p");            
  60.  
  61.             //Lets extract the package:
  62.             shell_exec("cd /tmp/C3pkg/; tar -xvf ../" $PluginID ".c3p");
  63.  
  64.             //Lets extract the data from package
  65.             $InstalledFiles shell_exec("cd " $this->Owner->GetCMS3Path("; tar -xvf /tmp/C3pkg/data.tar");
  66.  
  67.  
  68.             //Load all of the shared files of the plugin
  69.             if(file_exists($this->Owner->GetCMS3Path("share/" $PluginID "/"))
  70.             {
  71.                 $Shared scandir($this->Owner->GetCMS3Path("share/" $PluginID "/");
  72.                 foreach($Shared as $SharedInterface){
  73.                     if($SharedInterface != "." && $SharedInterface != ".."){
  74.                         //Use output control to avoid problems from bad plugins
  75.                         ob_start();
  76.                         require_once($this->GetCMS3Path("share/"$PluginID ."/" $SharedInterface);
  77.                         ob_end_clean();
  78.                     }
  79.                 }
  80.             }
  81.  
  82.             //Check if the plugin implements IInstall
  83.             $Plugin $this->Owner->LoadPlugin($PluginID);
  84.             $IResult "";
  85.             if(in_array("IInstall",class_implements($Plugin))){
  86.                 $IResult $Plugin->Install("The installations script was succesfully executed.\n" "There was error during execution of the installation script, please take a look at the system log.\n";
  87.             }
  88.  
  89.             return $IResult $InstalledFiles;
  90.         }else{
  91.             //TODO fix this when implementing remote repositories
  92.             return "Package not found.";
  93.         }
  94.     }
  95.  
  96.     /**
  97.     *Verifies the integrity of a (.c3p) package, not installed plugin
  98.     *
  99.     *@param string PluginID PluginID of the package to be verify
  100.     *@return bool True if signature is correct.
  101.     */
  102.     public function VerifyPackage($PluginID)
  103.     {
  104.         //TODO detect some of the worst errors and log them
  105.         //Check to see if the package exists
  106.         $PackagePath $this->Owner->GetCMS3Path("data/PackageManager/packages/" $PluginID ".c3p";
  107.         if(file_exists($PackagePath)){
  108.  
  109.             //make sure theres a temp dir
  110.             if(is_dir("/tmp/C3pkg/")){
  111.                 //If our tmp dir exists clean it
  112.                 shell_exec("rm /tmp/C3pkg/*");
  113.             }else{
  114.                 //if not create it.
  115.                 shell_exec("mkdir /tmp/C3pkg/");                
  116.             }
  117.  
  118.             //copy the package
  119.             shell_exec("cp " $PackagePath " /tmp/" $PluginID ".c3p");            
  120.  
  121.             //Lets extract the package:
  122.             shell_exec("cd /tmp/C3pkg/; tar -xvf ../" $PluginID ".c3p");
  123.  
  124.             //Lets verify the signature
  125.             system("gpg --verify /tmp/C3pkg/data.tar.sig"$out)//Out is an output variable
  126.             
  127.             //We have to use a little more direct system commands here, since gpg isn't very happy about the this kind of interaction
  128.             //It would be better to bind into a gpg library
  129.  
  130.  
  131.             /*
  132.             It seams gpg won't give you the commandline result text result, which mean that we have to rely on the program return.
  133.             The message printed in commandline ends up in php's log file, this could probably be done more nicely, perhaps detect how signed it
  134.             But for now it's okay that we just receive a boolean result... More advanced features would probably require a C wrapper application...
  135.             */
  136.  
  137.             //return the result
  138.             return $out == 0;
  139.             //TODO interact more with GPG, but for now this is find, since complete GPG, signature import etc. is a big task
  140.         }else{
  141.             //TODO fix this when implementing remote repositories
  142.             return false;
  143.         }
  144.     }
  145.  
  146.     /**
  147.     *Verify the integrity of an installed plugin
  148.     *
  149.     *@param string PluginID Id of the plugin you wish to verify
  150.     *@return string Returns a sha1sum result, or false if master signature was invalid.
  151.     */
  152.     public function VerifyPlugin($PluginID)    
  153.     {
  154.         //Check to see if the plugin is installed
  155.         $CkPath $this->Owner->GetCMS3Path("data/PackageManager/checksums/" $PluginID;
  156.         $SigPath $this->Owner->GetCMS3Path("data/PackageManager/checksums/" $PluginID .  ".sig";
  157.         if(file_exists($CkPath&& file_exists($SigPath)){
  158.             system("gpg --verify " $SigPath$out)//Out is an output variable
  159.             //TODO analyze output from sha1sum
  160.             return $out == shell_exec("cd " $this->Owner->GetCMS3Path("; sha1sum --check " $CkPathfalse;
  161.         }else{
  162.             return "Plugin not found.";
  163.         }
  164.     }
  165.  
  166.     /**
  167.     *Remove an installed plugin
  168.     *
  169.     *Note: if this one returns false, you can't be sure that haft of the package is removed or system perhaps broken.
  170.     *
  171.     *@param string PluginID PluginID of the package to remove
  172.     *@return bool True if package removed correctly
  173.     */
  174.     public function RemovePlugin($PluginID)
  175.     {
  176.         //Get paths of PackageManager files:
  177.         $CkPath $this->Owner->GetCMS3Path("data/PackageManager/checksums/" $PluginID;
  178.         $SigPath $this->Owner->GetCMS3Path("data/PackageManager/checksums/" $PluginID ".sig";
  179.  
  180.         if(file_exists($CkPath))
  181.         {
  182.             //Test if the plugin implements IRemove
  183.             $Plugin $this->Owner->GetPlugin($PluginID);
  184.             if(in_array("IRemove",class_implements($Plugin))){
  185.                 $Plugin->Remove();
  186.             }
  187.  
  188.             /*
  189.             this part of the PackageManager isn't very strong, it can only handle packages that comply with standarts
  190.             */
  191.  
  192.  
  193.             //execute the deletion of the plugin
  194.             $cmd "cd " $this->Owner->GetCMS3Path("; rm -R */" $PluginID "/ " $CkPath " " $SigPath;
  195.             system($cmd $out);
  196.  
  197.             //Log any errors, system might be broke on next http request
  198.             if($out != 0)
  199.                 $this->Owner->Log($this->GetPluginID()"Could not remove plugin:" $PluginID " error while removing files with following command:\n" $cmd);
  200.  
  201.             //Return true/false
  202.             return $out == 0;
  203.         }else{
  204.             //Log an return false
  205.             $this->Owner->Log($this->GetPluginID()"Could not remove plugin:" $PluginID " it wasn't installed by package manager.");
  206.             return false;
  207.         }
  208.     }
  209.  
  210.     /**
  211.     *Upload a third party package to local repository
  212.     */
  213.     public function UploadPackage($PackagePath$PackageName)
  214.     {
  215.         //Set destination
  216.         $Dest $this->Owner->GetCMS3Path("data/PackageManager/packages/" $PackageName ".c3p";
  217.         //Check if the file is uploaded or stored otherwise
  218.         if(is_uploaded_file($PackagePath)){
  219.             return move_uploaded_file($PackagePath$Dest);
  220.         }else{
  221.             return copy($PackagePath$Dest);
  222.         }
  223.     }
  224.  
  225.     /**
  226.     *List all the installed plugins that can be deleted or verified
  227.     */
  228.     public function ListPlugins()
  229.     {
  230.         $Plugins array();
  231.         $InChecksum scandir($this->Owner->GetCMS3Path("data/PackageManager/checksums/");
  232.         foreach($InChecksum as $Checksum){
  233.             if($Checksum != "." && $Checksum != ".." && substr($Checksum4!= ".sig"){
  234.                 $Plugins[$Checksum;
  235.             }
  236.         }
  237.         return $Plugins;
  238.     }
  239.  
  240.     /**
  241.     *List all the packages that are available for installation in local package repository
  242.     */
  243.     public function ListPackages()
  244.     {
  245.         //Don't list plugins already installed
  246.         $InstalledPlugins $this->ListPlugins();
  247.         $Packages array();
  248.         $InChecksum scandir($this->Owner->GetCMS3Path("data/PackageManager/packages/");
  249.         foreach($InChecksum as $Checksum){
  250.             if($Checksum != "." && $Checksum != ".." && !in_array($Checksum,$InstalledPlugins)){
  251.                 $Packages[substr($Checksum-4);
  252.             }
  253.         }
  254.         return $Packages;
  255.     }
  256.  
  257.  
  258.         //Implementation of IPlugin
  259.  
  260.     
  261.     /**
  262.      * Gets the pluginID of the plugin.
  263.      *
  264.      * @return string 
  265.      * @access public
  266.      */
  267.     public function GetPluginID)
  268.     {
  269.         return "PackageManager";
  270.     }
  271.  
  272. // end of CMS3_PackageManager
  273. ?>

Documentation generated on Mon, 30 Apr 2007 01:59:05 +0200 by phpDocumentor 1.3.1