tangra logo
   
[ class tree: tangra_lib ] [ index: tangra_lib ] [ all elements ]
 

Source for file tangra_module_uninstaller.class.php

Documentation is available at tangra_module_uninstaller.class.php

  1. <?php
  2.  
  3. // *** Tangra framework for php
  4. // $Id$
  5. //
  6.  
  7.  
  8. /**
  9.  * Contains class Tangra_Module_Uninstaller
  10.  *
  11.  * @package  tangra_lib
  12.  * @subpackage  modules_manager
  13.  */
  14.  
  15.  
  16. /**
  17.  *
  18.  */
  19. require_once(TANGRA_MAIN_DIR.'filesystem_toolbox/filesystem_functions.inc.php');
  20.  
  21. /**
  22.  * Tangra_Module_Uninstaller is the base class used by all module installers
  23.  *
  24.  * @package  tangra_lib
  25.  * @subpackage  modules_manager
  26.  */
  27.     private $module_conf_path;
  28.     private $dbc;
  29.     private $site_root_dir = '';
  30.  
  31.  
  32.     /**
  33.      * Constructor
  34.      *
  35.      * Parameter $params is a structured array that must have at least key 'module-conf-path'. Other parameters have to be fed as key-value pairs.
  36.      *
  37.      * Example $params[''module-conf-path'] = '/some/path';
  38.      *
  39.      * @param array $params 
  40.      */
  41.     function __construct($params{
  42.         $this->check_params($params);
  43.         $this->set_module_conf_path($params['module-conf-path']);
  44.         $hidden_start strpos($params['module-conf-path']'hidden/conf');
  45.         if ($hidden_start !== false{
  46.             $this->site_root_dir = substr($params['module-conf-path']0$hidden_start);
  47.         }
  48.         if ($this->is_parameter_present($params'dbc')) {
  49.             $this->set_dbc($params['dbc']);
  50.         }
  51.     }
  52.  
  53.  
  54.     /**
  55.      * Performs uninstall of the module
  56.      *
  57.      * @return array 
  58.      */
  59.     public function uninstall({
  60.         $ret array('ok' => true'removed_files' => array()'removed_db_objects' => array());
  61.  
  62.         if ($this->get_dbc()) {
  63.             $ret['removed_db_objects'$this->remove_db_objects();
  64.         }
  65.         $ret['removed_files'$this->remove_files();
  66.  
  67.         return $ret;
  68.     }
  69.  
  70.  
  71.     /**
  72.      * Checks if parameter is present
  73.      *
  74.      * @param array $params 
  75.      * @param string $parameter Parameter to be checked
  76.      * @return boolean 
  77.      */
  78.     protected function is_parameter_present($params$parameter{
  79.         return array_key_exists($parameter$params);
  80.     }
  81.  
  82.  
  83.     /**
  84.      * Sets module conf path
  85.      *
  86.      * @param string $module_conf_path 
  87.      */
  88.     protected function set_module_conf_path($module_conf_path{
  89.         if (file_exists($module_conf_path&& is_dir($module_conf_path)) {
  90.             $this->module_conf_path = $module_conf_path;
  91.         else {
  92.             throw new TE_TMM_Exception('Path does not exist or it is not a directory: '.$module_conf_path);
  93.         }
  94.     }
  95.  
  96.  
  97.     /**
  98.      * Gets module conf path
  99.      *
  100.      * @return string 
  101.      */
  102.     public function get_module_conf_path({
  103.         return $this->module_conf_path;
  104.     }
  105.  
  106.  
  107.     /**
  108.      * Sets DBC
  109.      *
  110.      * @param DB_Connection $dbc 
  111.      */
  112.     public function set_dbcDB_Connection $dbc{
  113.         $this->dbc = $dbc;
  114.     }
  115.  
  116.  
  117.     /**
  118.      * Gets DBC
  119.      *
  120.      * @return DB_Connection 
  121.      */
  122.     public function get_dbc({
  123.         return $this->dbc;
  124.     }
  125.  
  126.  
  127.     /**
  128.      * Gets site root dir
  129.      *
  130.      * @return string 
  131.      */
  132.     public function get_site_root_dir({
  133.         return $this->site_root_dir;
  134.     }
  135.  
  136.  
  137.     /**
  138.      * Checks if all required parameters are present
  139.      *
  140.      * @param array $params 
  141.      * @throws TE_TMM_Exception
  142.      */
  143.     protected function check_params($params{
  144.         if (array_key_exists('module-conf-path'$params)) {
  145.             if (!$params['module-conf-path']{
  146.                 throw new TE_TMM_Exception('$params[module-conf-path] is empty.');
  147.             }
  148.         else {
  149.             throw new TE_TMM_Exception('$params[module-conf-path] is not passed.');
  150.         }
  151.     }
  152.  
  153.  
  154.     /**
  155.      * Loads files list
  156.      *
  157.      * @return array 
  158.      * @internal
  159.      */
  160.     private function load_files_list({
  161.         $files array();
  162.  
  163.         $module_files_list tangra_normalize_path($this->get_module_conf_path()).'files.list';
  164.         if (file_exists($module_files_list)) {
  165.             $files file($module_files_list);
  166.         }
  167.  
  168.         return $files;
  169.     }
  170.  
  171.  
  172.     /**
  173.      * Prepares list of files to be removed expanding paths to full paths
  174.      *
  175.      * Can handle with files.list with releative paths
  176.      *
  177.      * @param array $files_list 
  178.      * @return array 
  179.      * @internal
  180.      */
  181.     private function prepare_remove_list($files_list{
  182.         $ret array();
  183.  
  184.         $site_dirs $this->load_site_dirs();
  185.         foreach($files_list as $item{
  186.             $item trim($item);
  187.             if (strpos($item'%'!== false{
  188.                 $item str_replace('%HIDDEN%'$site_dirs['hidden']$item);
  189.                 $item str_replace('%HTDOCS%'$site_dirs['htdocs']$item);
  190.                 $item str_replace('%EXT_INC%'$site_dirs['ext_inc']$item);
  191.                 $item str_replace('%SCRATCH%'$site_dirs['scratch']$item);
  192.  
  193.                 $space_pos strpos($item' ');
  194.                 if ($space_pos !== false{
  195.                     $item substr($item0$space_pos);
  196.                 }
  197.                 $ret[$item;
  198.             else {
  199.                 // processing old style files.list (i.e. with full paths or relative without root dir)
  200.  
  201.                 $space_pos strpos($item' ');
  202.                 if ($space_pos !== false{
  203.                     if (substr($item01== '/'{
  204.                         $ret[substr($item0$space_pos);
  205.                     else {
  206.                         $ret[$this->get_site_root_dir().substr($item0$space_pos);
  207.                     }
  208.                 else {
  209.                     if (substr($item01== '/'{
  210.                         $ret[$item;
  211.                     else {
  212.                         $ret[$this->get_site_root_dir().$item;
  213.                     }
  214.                 }
  215.             }
  216.         }
  217.  
  218.         return $ret;
  219.     }
  220.  
  221.  
  222.     /**
  223.      * Removes module's files
  224.      *
  225.      * @return array 
  226.      */
  227.     protected function remove_files({
  228.         $ret['ok'array();
  229.         $ret['err'array();
  230.         $ret['freed'0;
  231.  
  232.         $files_list $this->prepare_remove_list($this->load_files_list());
  233.  
  234.         if ($files_list{
  235.             $files_list array_reverse($files_list);
  236.             $used_space 0;
  237.             foreach($files_list as $item{
  238.                 $rez false;
  239.                 if (file_exists($item)) {
  240.                     if (is_dir($item)) {
  241.                         if (is_dir_empty($item)) {
  242.                             $rez @rmdir($item);
  243.                         }
  244.                     else {
  245.                         if (is_file($item|| is_link($item)) {
  246.                             $used_space += filesize($item);
  247.                             $rez @unlink($item);
  248.                         else {
  249.                             $rez false;
  250.                         }
  251.                     }
  252.                 else {
  253.                     $rez true;
  254.                 }
  255.  
  256.                 if ($rez{
  257.                     $ret['ok'][$item;
  258.                 else {
  259.                     $ret['err'][$item;
  260.                 }
  261.                 $ret['freed'$used_space;
  262.             }
  263.         }
  264.  
  265.  
  266.         return $ret;
  267.     }
  268.  
  269.  
  270.     /**
  271.      * Removes DB objects - tables and/or columns
  272.      *
  273.      * @return array 
  274.      */
  275.     protected function remove_db_objects({
  276.  
  277.         $dbc $this->get_dbc();
  278.         $module_conf_path $this->get_module_conf_path();
  279.  
  280.         $ret['ok'array();
  281.         $ret['err'array();
  282.  
  283.         $file $module_conf_path.'uninstall_db_items.txt';
  284.  
  285.         if (file_exists($file)) {
  286.  
  287.             $arr file($file);
  288.  
  289.             foreach($arr as $row{
  290.                 $pair explode('=='$row);
  291.                 if (count($pair== && trim($pair[1])) {
  292.                     try {
  293.                         switch($pair[0]{
  294.                             case 'drop_table':
  295.                                 $sql 'drop table '.addslashes($pair[1]);
  296.                                 break;
  297.                             case 'drop_column':
  298.                                 $sql $this->generate_drop_columns_sql($pair[1]);
  299.                                 break;
  300.                             case 'sql':
  301.                                 $sql $pair[1];
  302.                                 break;
  303.                             default:
  304.                                 $sql '';
  305.                                 break;
  306.                         }
  307.  
  308.                         if ($sql{
  309.                             $dbc->execute($sql);
  310.                             $ret['ok'][$row;
  311.                         }
  312.                     catch (Exception $e{
  313.                         if ($e instanceof TE_DBC_SQL_Failed{
  314.                             $ret['err'][$row;
  315.                         else {
  316.                             throw $e;
  317.                         }
  318.                     }
  319.                 }
  320.             }
  321.         }
  322.  
  323.         return $ret;
  324.     }
  325.  
  326.  
  327.     /**
  328.      * Generates SQL for drop column
  329.      *
  330.      * @param string $str 
  331.      * @return string SQL Drop column statement
  332.      * @internal
  333.      */
  334.     private function generate_drop_columns_sql($str{
  335.         $ret '';
  336.  
  337.         $tmp explode(':'$str);
  338.         if (count($tmp== 2{
  339.             $table $tmp[0];
  340.             if (trim($tmp[1])) {
  341.                 $column trim($tmp[1]);
  342.                 $ret "ALTER TABLE $table DROP COLUMN '$column'";
  343.             }
  344.         }
  345.  
  346.         return $ret;
  347.     }
  348.  
  349.  
  350.     /**
  351.      * Loads hidden, htdocs, scratch and ext_inc paths and returns them as array
  352.      *
  353.      * @param string $root_dir Path to site's root dir
  354.      * @return array 
  355.      */
  356.     private function load_site_dirs({
  357.         $module_conf_path $this->get_module_conf_path();
  358.         $root_dir substr($module_conf_path0strpos($module_conf_path'hidden/conf/modules/'));
  359.         $root_dir substr($module_conf_path0strpos($module_conf_path'hidden/conf/modules/'))// just in case path is not normalized
  360.  
  361.         $ms_conf $root_dir.'hidden/conf/machine_specific.conf';
  362.  
  363.         $ms_conf $root_dir.'hidden/conf/machine_specific.conf';
  364.         $conf_loader new Config_Loader_File($ms_conf);
  365.         $hidden_dir $conf_loader->get_conf_value('HIDDEN'false);
  366.         if (!$hidden_dir{
  367.             $hidden_dir $root_dir.'hidden/';
  368.         }
  369.  
  370.         $htdocs_dir $conf_loader->get_conf_value('DOCUMENT_ROOT'false);
  371.         if (!$htdocs_dir{
  372.             $htdocs_dir $root_dir.'htdocs/';
  373.         }
  374.  
  375.         $scratch_dir $conf_loader->get_conf_value('SCRATCH'false);
  376.         if (!$scratch_dir{
  377.             $scratch_dir $root_dir.'scratch/';
  378.         }
  379.  
  380.         $ext_inc_dir $conf_loader->get_conf_value('EXT_INC'false);
  381.         if (!$ext_inc_dir{
  382.             $ext_inc_dir $root_dir.'ext_inc/';
  383.         }
  384.  
  385.         return array('hidden' => $hidden_dir'htdocs' => $htdocs_dir'scratch' => $scratch_dir'ext_inc' => $ext_inc_dir);
  386.     }
  387. }