MagentoInstaller - Version 0.1.0

Version Notes

0.1.0

Download this release

Release Info

Developer Magento Core Team
Extension MagentoInstaller
Version 0.1.0
Comparing to
See all releases


Version 0.1.0

Files changed (28) hide show
  1. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Files.php +18 -0
  2. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Files/Grid.php +73 -0
  3. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller.php +15 -0
  4. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit.php +32 -0
  5. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Form.php +19 -0
  6. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Tab/Form.php +20 -0
  7. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Tabs.php +24 -0
  8. app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Grid.php +93 -0
  9. app/code/community/Magestore/Mageinstaller/Helper/Data.php +23 -0
  10. app/code/community/Magestore/Mageinstaller/Model/Extension.php +36 -0
  11. app/code/community/Magestore/Mageinstaller/Model/File.php +21 -0
  12. app/code/community/Magestore/Mageinstaller/Model/Gzipper.php +25 -0
  13. app/code/community/Magestore/Mageinstaller/Model/Installer.php +169 -0
  14. app/code/community/Magestore/Mageinstaller/Model/Mysql4/Extension.php +10 -0
  15. app/code/community/Magestore/Mageinstaller/Model/Mysql4/Extension/Collection.php +10 -0
  16. app/code/community/Magestore/Mageinstaller/Model/Mysql4/File.php +10 -0
  17. app/code/community/Magestore/Mageinstaller/Model/Mysql4/File/Collection.php +10 -0
  18. app/code/community/Magestore/Mageinstaller/Model/Status.php +15 -0
  19. app/code/community/Magestore/Mageinstaller/Model/Zipper.php +48 -0
  20. app/code/community/Magestore/Mageinstaller/controllers/Adminhtml/FilesController.php +52 -0
  21. app/code/community/Magestore/Mageinstaller/controllers/Adminhtml/MageinstallerController.php +135 -0
  22. app/code/community/Magestore/Mageinstaller/controllers/IndexController.php +47 -0
  23. app/code/community/Magestore/Mageinstaller/etc/config.xml +107 -0
  24. app/code/community/Magestore/Mageinstaller/sql/mageinstaller_setup/mysql4-install-0.1.0.php +30 -0
  25. app/design/adminhtml/default/default/layout/mageinstaller.xml +15 -0
  26. app/etc/modules/Magestore_Mageinstaller.xml +9 -0
  27. lib/PEAR/Archive_Tar.php +1663 -0
  28. package.xml +18 -0
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Files.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Magestore_Mageinstaller_Block_Adminhtml_Files extends Mage_Adminhtml_Block_Widget_Grid_Container
3
+ {
4
+ public function __construct()
5
+ {
6
+ $this->_controller = 'adminhtml_files';
7
+ $this->_blockGroup = 'mageinstaller';
8
+ $this->_headerText = Mage::helper('mageinstaller')->__('Files Information');
9
+ parent::__construct();
10
+ $this->_removeButton('add');
11
+
12
+ $this->_addButton('back', array(
13
+ 'label' => Mage::helper('adminhtml')->__('BACK'),
14
+ 'onclick' => 'location.href=\''. $this->getUrl('mageinstaller/adminhtml_mageinstaller/index',array()) . "'",
15
+ 'class' => 'back',
16
+ ), -100);
17
+ }
18
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Files/Grid.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Files_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('filesGrid');
9
+ $this->setDefaultSort('extensionfile_id');
10
+ $this->setDefaultDir('ASC');
11
+ $this->setSaveParametersInSession(true);
12
+ }
13
+
14
+ protected function _prepareCollection()
15
+ {
16
+ $collection = Mage::getModel('mageinstaller/file')->getCollection()
17
+ ->addFieldToFilter('extension_id',$this->getRequest()->getParam('extension_id'));
18
+ $this->setCollection($collection);
19
+ return parent::_prepareCollection();
20
+ }
21
+
22
+ protected function _prepareColumns()
23
+ {
24
+ $this->addColumn('extensionfile_id', array(
25
+ 'header' => Mage::helper('mageinstaller')->__('ID'),
26
+ 'align' =>'right',
27
+ 'width' => '50px',
28
+ 'index' => 'extensionfile_id',
29
+ ));
30
+
31
+ $this->addColumn('title', array(
32
+ 'header' => Mage::helper('mageinstaller')->__('Name'),
33
+ 'align' =>'left',
34
+ 'index' => 'title',
35
+ ));
36
+
37
+ $this->addColumn('extension_id', array(
38
+ 'header' => Mage::helper('mageinstaller')->__('Package'),
39
+ 'align' =>'left',
40
+ 'index' => 'extension_id',
41
+ 'type' => 'options',
42
+ 'options' => Mage::helper('mageinstaller')->getListExtension(),
43
+ ));
44
+
45
+ $this->addColumn('size', array(
46
+ 'header' => Mage::helper('mageinstaller')->__('Size'),
47
+ 'align' =>'left',
48
+ 'index' => 'size',
49
+ ));
50
+
51
+ $this->addColumn('path', array(
52
+ 'header' => Mage::helper('mageinstaller')->__('Path'),
53
+ 'align' =>'left',
54
+ 'index' => 'path',
55
+ ));
56
+
57
+ $this->addExportType('*/*/exportCsv', Mage::helper('mageinstaller')->__('CSV'));
58
+ $this->addExportType('*/*/exportXml', Mage::helper('mageinstaller')->__('XML'));
59
+
60
+ return parent::_prepareColumns();
61
+ }
62
+
63
+ protected function _prepareMassaction()
64
+ {
65
+ return $this;
66
+ }
67
+
68
+ public function getRowUrl($row)
69
+ {
70
+ return null;
71
+ }
72
+
73
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller extends Mage_Adminhtml_Block_Widget_Grid_Container
3
+ {
4
+ public function __construct()
5
+ {
6
+ $this->_controller = 'adminhtml_mageinstaller';
7
+ $this->_blockGroup = 'mageinstaller';
8
+ $this->_headerText = Mage::helper('mageinstaller')->__('Package Manager');
9
+
10
+ parent::__construct();
11
+
12
+ $this->_updateButton('add', 'label', Mage::helper('mageinstaller')->__('New Install'));
13
+
14
+ }
15
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
4
+ {
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+
9
+ $this->_objectId = 'id';
10
+ $this->_blockGroup = 'mageinstaller';
11
+ $this->_controller = 'adminhtml_mageinstaller';
12
+
13
+ $this->_updateButton('save', 'label', Mage::helper('mageinstaller')->__('Install'));
14
+
15
+ $this->_removeButton('delete');
16
+ $this->_removeButton('reset');
17
+
18
+ $this->_formScripts[] = "
19
+ function toggleEditor() {
20
+ if (tinyMCE.getInstanceById('mageinstaller_content') == null) {
21
+ tinyMCE.execCommand('mceAddControl', false, 'mageinstaller_content');
22
+ } else {
23
+ tinyMCE.execCommand('mceRemoveControl', false, 'mageinstaller_content');
24
+ }
25
+ ";
26
+ }
27
+
28
+ public function getHeaderText()
29
+ {
30
+ return Mage::helper('mageinstaller')->__('Mageinstaller');
31
+ }
32
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Form.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+ protected function _prepareForm()
6
+ {
7
+ $form = new Varien_Data_Form(array(
8
+ 'id' => 'edit_form',
9
+ 'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
10
+ 'method' => 'post',
11
+ 'enctype' => 'multipart/form-data'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+ $this->setForm($form);
17
+ return parent::_prepareForm();
18
+ }
19
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Tab/Form.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+ protected function _prepareForm()
6
+ {
7
+ $form = new Varien_Data_Form();
8
+ $this->setForm($form);
9
+ $fieldset = $form->addFieldset('mageinstaller_form', array('legend'=>Mage::helper('mageinstaller')->__('Install information')));
10
+
11
+
12
+ $fieldset->addField('install_file', 'file', array(
13
+ 'label' => Mage::helper('mageinstaller')->__('Install File'),
14
+ 'required' => true,
15
+ 'name' => 'install_file',
16
+ ));
17
+
18
+ return parent::_prepareForm();
19
+ }
20
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Edit/Tabs.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('mageinstaller_tabs');
10
+ $this->setDestElementId('edit_form');
11
+ $this->setTitle(Mage::helper('mageinstaller')->__('Install Information'));
12
+ }
13
+
14
+ protected function _beforeToHtml()
15
+ {
16
+ $this->addTab('form_section', array(
17
+ 'label' => Mage::helper('mageinstaller')->__('Install Information'),
18
+ 'title' => Mage::helper('mageinstaller')->__('Install Information'),
19
+ 'content' => $this->getLayout()->createBlock('mageinstaller/adminhtml_mageinstaller_edit_tab_form')->toHtml(),
20
+ ));
21
+
22
+ return parent::_beforeToHtml();
23
+ }
24
+ }
app/code/community/Magestore/Mageinstaller/Block/Adminhtml/Mageinstaller/Grid.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Block_Adminhtml_Mageinstaller_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+ public function __construct()
6
+ {
7
+ parent::__construct();
8
+ $this->setId('extensionGrid');
9
+ $this->setDefaultSort('extension_id');
10
+ $this->setDefaultDir('ASC');
11
+ $this->setSaveParametersInSession(true);
12
+ }
13
+
14
+ protected function _prepareCollection()
15
+ {
16
+ $collection = Mage::getModel('mageinstaller/extension')->getCollection();
17
+ $this->setCollection($collection);
18
+ return parent::_prepareCollection();
19
+ }
20
+
21
+ protected function _prepareColumns()
22
+ {
23
+ $this->addColumn('extension_id', array(
24
+ 'header' => Mage::helper('mageinstaller')->__('ID'),
25
+ 'align' =>'right',
26
+ 'width' => '50px',
27
+ 'index' => 'extension_id',
28
+ ));
29
+
30
+ $this->addColumn('title', array(
31
+ 'header' => Mage::helper('mageinstaller')->__('Package'),
32
+ 'align' =>'left',
33
+ 'index' => 'title',
34
+ ));
35
+
36
+ $this->addColumn('total_file', array(
37
+ 'header' => Mage::helper('mageinstaller')->__('Total Files'),
38
+ 'align' =>'left',
39
+ 'index' => 'total_file',
40
+ ));
41
+
42
+ $this->addColumn('added_date', array(
43
+ 'header' => Mage::helper('mageinstaller')->__('Install Date'),
44
+ 'align' =>'left',
45
+ 'index' => 'added_date',
46
+ 'type' => 'date',
47
+ ));
48
+
49
+
50
+ $this->addColumn('action',
51
+ array(
52
+ 'header' => Mage::helper('mageinstaller')->__('Action'),
53
+ 'width' => '100',
54
+ 'type' => 'action',
55
+ 'getter' => 'getId',
56
+ 'actions' => array(
57
+ array(
58
+ 'caption' => Mage::helper('mageinstaller')->__('Files'),
59
+ 'url' => array('base'=> '*/adminhtml_files/index'),
60
+ 'field' => 'extension_id'
61
+ )
62
+ ),
63
+ 'filter' => false,
64
+ 'sortable' => false,
65
+ 'index' => 'stores',
66
+ 'is_system' => true,
67
+ ));
68
+
69
+ $this->addExportType('*/*/exportCsv', Mage::helper('mageinstaller')->__('CSV'));
70
+ $this->addExportType('*/*/exportXml', Mage::helper('mageinstaller')->__('XML'));
71
+
72
+ return parent::_prepareColumns();
73
+ }
74
+
75
+ protected function _prepareMassaction()
76
+ {
77
+ $this->setMassactionIdField('extenstion_id');
78
+ $this->getMassactionBlock()->setFormFieldName('mageinstaller');
79
+
80
+ $this->getMassactionBlock()->addItem('delete', array(
81
+ 'label' => Mage::helper('mageinstaller')->__('Remove'),
82
+ 'url' => $this->getUrl('*/*/massDelete'),
83
+ 'confirm' => Mage::helper('mageinstaller')->__('Are you sure?')
84
+ ));
85
+ return $this;
86
+ }
87
+
88
+ public function getRowUrl($row)
89
+ {
90
+ return $this->getUrl('*/adminhtml_files/index', array('extension_id' => $row->getId()));
91
+ }
92
+
93
+ }
app/code/community/Magestore/Mageinstaller/Helper/Data.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ Class Magestore_Mageinstaller_Helper_Data extends Mage_Core_Helper_Abstract{
4
+
5
+ public function getListExtension()
6
+ {
7
+ $listExtension = array();
8
+
9
+ $collection = Mage::getResourceModel('mageinstaller/extension_collection');
10
+
11
+ if(count($collection))
12
+ {
13
+ foreach($collection as $item)
14
+ {
15
+ $listExtension[$item->getId()] = $item->getTitle();
16
+ }
17
+ }
18
+
19
+ return $listExtension;
20
+ }
21
+ }
22
+
23
+ ?>
app/code/community/Magestore/Mageinstaller/Model/Extension.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Extension extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('mageinstaller/extension');
9
+ }
10
+
11
+ public function delete()
12
+ {
13
+ $collection = Mage::getResourceModel('mageinstaller/file_collection')
14
+ ->addFieldToFilter('extension_id',$this->getId());
15
+
16
+ if(count($collection))
17
+ {
18
+ $root_path = Mage::getBaseDir();
19
+
20
+ foreach($collection as $exfile)
21
+ {
22
+ if($exfile->getTotalPath() == 1)
23
+ {
24
+ if(file_exists($root_path . DS . $exfile->getPath()))
25
+ {
26
+ unlink($exfile->getPath());
27
+ }
28
+ }
29
+
30
+ $exfile->delete();
31
+ }
32
+ }
33
+
34
+ return parent::delete();
35
+ }
36
+ }
app/code/community/Magestore/Mageinstaller/Model/File.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_File extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('mageinstaller/file');
9
+ }
10
+
11
+ public function getTotalPath()
12
+ {
13
+ if(! $this->getPath())
14
+ return 0;
15
+
16
+ $collection = $this->getCollection()
17
+ ->addFieldToFilter('path',$this->getPath());
18
+
19
+ return count($collection);
20
+ }
21
+ }
app/code/community/Magestore/Mageinstaller/Model/Gzipper.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ include(Mage::getBaseDir('lib') . DS .'PEAR'. DS .'Archive_Tar.php');
4
+
5
+ class Magestore_Mageinstaller_Model_Gzipper
6
+ {
7
+ function advExtract($install_file,$path)
8
+ {
9
+ if(file_exists($install_file))
10
+ {
11
+ $gzip = new Archive_Tar($install_file,'gz');
12
+
13
+ $gzip->extract($path);
14
+
15
+ return $gzip->listContent();
16
+
17
+ } else {
18
+
19
+ Mage::getSingleton('core/session')->addError('Not existed archive');
20
+
21
+ return false;
22
+ }
23
+ }
24
+
25
+ }
app/code/community/Magestore/Mageinstaller/Model/Installer.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Installer {
4
+
5
+ // File Object
6
+ var $_file;
7
+ //file name
8
+ var $_filename;
9
+ //ext file
10
+ var $_extfile;
11
+ //path to zipfile
12
+ var $_filePath;
13
+
14
+ public function install($install_file)
15
+ {
16
+ //upload file
17
+ $this->uploadZipFile($install_file);
18
+
19
+ //check file
20
+ if(is_null($this->_file)|| is_null($this->_filePath))
21
+ {
22
+ Mage::getSingleton('core/session')->addError('Could not found zip/gz file');
23
+
24
+ return;
25
+ }
26
+ //extract file
27
+ $extract_path = Mage::getBaseDir();
28
+
29
+ switch($this->_extfile)
30
+ {
31
+ case 'zip':
32
+ $zip = Mage::getModel('mageinstaller/zipper') ;
33
+ $extract_info = $zip->advExtract($this->_filePath,$extract_path);
34
+ break;
35
+
36
+ case 'gz':
37
+ $gzip = Mage::getModel('mageinstaller/gzipper') ;
38
+ $extract_info = $gzip->advExtract($this->_filePath,$extract_path);
39
+ break;
40
+ }
41
+
42
+ if(isset($extract_info) && count($extract_info))
43
+ {
44
+ $extension = Mage::getModel('mageinstaller/extension');
45
+ $exfile = Mage::getModel('mageinstaller/file');
46
+
47
+ $timestamp = Mage::getModel('core/date')->timestamp(time());
48
+ $date = date('Y-m-d H:i:s',$timestamp);
49
+
50
+ $extension->setData('title',$this->_filename);
51
+ $extension->setData('added_date',$date);
52
+
53
+ try{
54
+ $extension->save();
55
+
56
+ $total_files = 0;
57
+ foreach($extract_info as $file_info)
58
+ {
59
+ if($file_info['size'] > 0)
60
+ {
61
+ //save file info
62
+ switch($this->_extfile)
63
+ {
64
+ case 'zip':
65
+ $filename = $file_info['name'];
66
+ break;
67
+
68
+ case 'gz':
69
+ $filename = $file_info['filename'];
70
+ break;
71
+ }
72
+ $exfile->setData('title',$this->getFileName($filename));
73
+ $exfile->setData('path',$filename);
74
+ $exfile->setData('size',$file_info['size']);
75
+ $exfile->setData('extension_id',$extension->getId());
76
+ $exfile->save();
77
+ $exfile->setId(null);
78
+
79
+ $total_files++;
80
+ }
81
+ }
82
+
83
+ $extension->setTotalFile($total_files);
84
+ $extension->save();
85
+
86
+ return true;
87
+
88
+ } catch(Exception $e) {
89
+ Mage::getSingleton('core/session')->addError($e->getMessage());
90
+ return false;
91
+ }
92
+ }
93
+
94
+ return false;
95
+ }
96
+
97
+ public function uploadZipFile($zip_file)
98
+ {
99
+ $path = $this->createFolder();
100
+
101
+ if(! $path)
102
+ return false;
103
+
104
+ if(isset($zip_file['name']) && ($zip_file['name'] != ''))
105
+ {
106
+ try {
107
+ $file_name = $zip_file['name'];
108
+
109
+ $this->_filename = $file_name;
110
+
111
+ $oFile = new Varien_File_Object($zip_file['tmp_name']);
112
+
113
+ $this->_file = $oFile;
114
+ $this->_extfile = $oFile->getExt($zip_file['name']);
115
+
116
+ if($this->_extfile != 'zip' && $this->_extfile != 'gz')
117
+ {
118
+ Mage::getSingleton('core/session')->addError('Not zip/gz file');
119
+ return;
120
+ }
121
+
122
+ /* Starting upload */
123
+ move_uploaded_file($zip_file['tmp_name'],$path . DS . $zip_file['name']);
124
+
125
+ $this->_filePath = $path .DS . $file_name;
126
+
127
+ return $this->_filePath;
128
+
129
+ } catch(Exception $e){
130
+
131
+ Mage::getSingleton('core/session')->addError($e->getMessage());
132
+
133
+ return false;
134
+ }
135
+ }
136
+ }
137
+
138
+ private function createFolder()
139
+ {
140
+ $path = Mage::getBaseDir('media') . DS . 'Mageinstaller';
141
+
142
+ if(! is_dir($path))
143
+ {
144
+ try{
145
+ chmod(Mage::getBaseDir('media'),755);
146
+
147
+ mkdir($path);
148
+
149
+ chmod($path,755);
150
+ return $path;
151
+
152
+ } catch(Exception $e){
153
+ Mage::getSingleton('core/session')->addError($e->getMessage());
154
+ return false;
155
+ }
156
+ }
157
+
158
+ return $path;
159
+ }
160
+
161
+ public function getFileName($path)
162
+ {
163
+ $pos = strrpos($path,'/');
164
+
165
+ return substr($path,$pos+1,strlen($path));
166
+ }
167
+ }
168
+
169
+ ?>
app/code/community/Magestore/Mageinstaller/Model/Mysql4/Extension.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Mysql4_Extension extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ // Note that the mageinstaller_id refers to the key field in your database table.
8
+ $this->_init('mageinstaller/extension', 'extension_id');
9
+ }
10
+ }
app/code/community/Magestore/Mageinstaller/Model/Mysql4/Extension/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Mysql4_Extension_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('mageinstaller/extension');
9
+ }
10
+ }
app/code/community/Magestore/Mageinstaller/Model/Mysql4/File.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Mysql4_File extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ // Note that the mageinstaller_id refers to the key field in your database table.
8
+ $this->_init('mageinstaller/file', 'extensionfile_id');
9
+ }
10
+ }
app/code/community/Magestore/Mageinstaller/Model/Mysql4/File/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Mysql4_File_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('mageinstaller/file');
9
+ }
10
+ }
app/code/community/Magestore/Mageinstaller/Model/Status.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Status extends Varien_Object
4
+ {
5
+ const STATUS_ENABLED = 1;
6
+ const STATUS_DISABLED = 2;
7
+
8
+ static public function getOptionArray()
9
+ {
10
+ return array(
11
+ self::STATUS_ENABLED => Mage::helper('mageinstaller')->__('Enabled'),
12
+ self::STATUS_DISABLED => Mage::helper('mageinstaller')->__('Disabled')
13
+ );
14
+ }
15
+ }
app/code/community/Magestore/Mageinstaller/Model/Zipper.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Model_Zipper
4
+ {
5
+ function advExtract($zipfile,$path)
6
+ {
7
+ if(file_exists($zipfile))
8
+ {
9
+ $zip = new ZipArchive;
10
+
11
+ if ($zip->open($zipfile) === true)
12
+ {
13
+ $extract_info = array();
14
+
15
+ for($i = 0; $i < $zip->numFiles; $i++)
16
+ {
17
+ $extract_info[] = $zip->statIndex($i);
18
+ }
19
+
20
+
21
+ if ($zip->extractTo($path) == true)
22
+ {
23
+ return $extract_info;
24
+
25
+ } else {
26
+
27
+ Mage::getSingleton('core/session')->addError('Could not extract archive');
28
+
29
+ return false;
30
+ }
31
+
32
+ $zip->close();
33
+
34
+ } else {
35
+
36
+ Mage::getSingleton('core/session')->addError('Could not open archive');
37
+
38
+ return false;
39
+ }
40
+ } else {
41
+
42
+ Mage::getSingleton('core/session')->addError('Not existed archive');
43
+
44
+ return false;
45
+ }
46
+ }
47
+
48
+ }
app/code/community/Magestore/Mageinstaller/controllers/Adminhtml/FilesController.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Adminhtml_FilesController extends Mage_Adminhtml_Controller_Action
4
+ {
5
+
6
+ protected function _initAction() {
7
+ $this->loadLayout()
8
+ ->_setActiveMenu('system/extensions')
9
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Extension Files Manager'), Mage::helper('adminhtml')->__('Extension Files Manager'));
10
+
11
+ return $this;
12
+ }
13
+
14
+ public function indexAction() {
15
+ $this->_initAction()
16
+ ->renderLayout();
17
+ }
18
+
19
+ public function exportCsvAction()
20
+ {
21
+ $fileName = 'files.csv';
22
+ $content = $this->getLayout()->createBlock('mageinstaller/adminhtml_files_grid')
23
+ ->getCsv();
24
+
25
+ $this->_sendUploadResponse($fileName, $content);
26
+ }
27
+
28
+ public function exportXmlAction()
29
+ {
30
+ $fileName = 'files.xml';
31
+ $content = $this->getLayout()->createBlock('mageinstaller/adminhtml_files_grid')
32
+ ->getXml();
33
+
34
+ $this->_sendUploadResponse($fileName, $content);
35
+ }
36
+
37
+ protected function _sendUploadResponse($fileName, $content, $contentType='application/octet-stream')
38
+ {
39
+ $response = $this->getResponse();
40
+ $response->setHeader('HTTP/1.1 200 OK','');
41
+ $response->setHeader('Pragma', 'public', true);
42
+ $response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
43
+ $response->setHeader('Content-Disposition', 'attachment; filename='.$fileName);
44
+ $response->setHeader('Last-Modified', date('r'));
45
+ $response->setHeader('Accept-Ranges', 'bytes');
46
+ $response->setHeader('Content-Length', strlen($content));
47
+ $response->setHeader('Content-type', $contentType);
48
+ $response->setBody($content);
49
+ $response->sendResponse();
50
+ die;
51
+ }
52
+ }
app/code/community/Magestore/Mageinstaller/controllers/Adminhtml/MageinstallerController.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Magestore_Mageinstaller_Adminhtml_MageinstallerController extends Mage_Adminhtml_Controller_Action
4
+ {
5
+
6
+ protected function _initAction() {
7
+ $this->loadLayout()
8
+ ->_setActiveMenu('system/extensions')
9
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Package Manager'), Mage::helper('adminhtml')->__('Package Manager'));
10
+
11
+ return $this;
12
+ }
13
+
14
+ public function indexAction() {
15
+ $this->_initAction()
16
+ ->renderLayout();
17
+ }
18
+
19
+ public function newAction() {
20
+
21
+ $this->loadLayout();
22
+ $this->_setActiveMenu('system/extensions');
23
+
24
+ $this->_addBreadcrumb(Mage::helper('adminhtml')->__('New Install'), Mage::helper('adminhtml')->__('New Install'));
25
+
26
+ $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
27
+
28
+ $this->_addContent($this->getLayout()->createBlock('mageinstaller/adminhtml_mageinstaller_edit'))
29
+ ->_addLeft($this->getLayout()->createBlock('mageinstaller/adminhtml_mageinstaller_edit_tabs'));
30
+
31
+ $this->renderLayout();
32
+ }
33
+
34
+ public function saveAction()
35
+ {
36
+ if(isset($_FILES['install_file']) && $_FILES['install_file']['name'])
37
+ {
38
+ $installer = Mage::getModel('mageinstaller/installer');
39
+
40
+ $extract_info = $installer->install($_FILES['install_file']);
41
+
42
+ if($extract_info)
43
+ {
44
+ Mage::getSingleton('core/session')->addSuccess('Installed Module Sucessful');
45
+
46
+ $this->_redirect('*/*/index',array());
47
+
48
+ return true;
49
+
50
+ } else {
51
+
52
+ Mage::getSingleton('core/session')->addError('Installed Module Faild');
53
+
54
+ $this->_redirect('*/*/new',array());
55
+
56
+ return false;
57
+ }
58
+ }
59
+ }
60
+
61
+ public function deleteAction() {
62
+ if( $this->getRequest()->getParam('id') > 0 ) {
63
+ try {
64
+ $model = Mage::getModel('mageinstaller/extension');
65
+
66
+ $model->setId($this->getRequest()->getParam('id'))
67
+ ->delete();
68
+
69
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Package was successfully deleted'));
70
+ $this->_redirect('*/*/');
71
+ } catch (Exception $e) {
72
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
73
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
74
+ }
75
+ }
76
+ $this->_redirect('*/*/');
77
+ }
78
+
79
+ public function massDeleteAction() {
80
+ $mageinstallerIds = $this->getRequest()->getParam('mageinstaller');
81
+ if(!is_array($mageinstallerIds)) {
82
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Please select Package(s)'));
83
+ } else {
84
+ try {
85
+ foreach ($mageinstallerIds as $mageinstallerId) {
86
+ $mageinstaller = Mage::getModel('mageinstaller/extension')->load($mageinstallerId);
87
+ $mageinstaller->delete();
88
+ }
89
+ Mage::getSingleton('adminhtml/session')->addSuccess(
90
+ Mage::helper('adminhtml')->__(
91
+ 'Total of %d record(s) were successfully deleted', count($mageinstallerIds)
92
+ )
93
+ );
94
+ } catch (Exception $e) {
95
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
96
+ }
97
+ }
98
+ $this->_redirect('*/*/index');
99
+ }
100
+
101
+
102
+ public function exportCsvAction()
103
+ {
104
+ $fileName = 'package.csv';
105
+ $content = $this->getLayout()->createBlock('mageinstaller/adminhtml_mageinstaller_grid')
106
+ ->getCsv();
107
+
108
+ $this->_sendUploadResponse($fileName, $content);
109
+ }
110
+
111
+ public function exportXmlAction()
112
+ {
113
+ $fileName = 'package.xml';
114
+ $content = $this->getLayout()->createBlock('mageinstaller/adminhtml_mageinstaller_grid')
115
+ ->getXml();
116
+
117
+ $this->_sendUploadResponse($fileName, $content);
118
+ }
119
+
120
+ protected function _sendUploadResponse($fileName, $content, $contentType='application/octet-stream')
121
+ {
122
+ $response = $this->getResponse();
123
+ $response->setHeader('HTTP/1.1 200 OK','');
124
+ $response->setHeader('Pragma', 'public', true);
125
+ $response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
126
+ $response->setHeader('Content-Disposition', 'attachment; filename='.$fileName);
127
+ $response->setHeader('Last-Modified', date('r'));
128
+ $response->setHeader('Accept-Ranges', 'bytes');
129
+ $response->setHeader('Content-Length', strlen($content));
130
+ $response->setHeader('Content-type', $contentType);
131
+ $response->setBody($content);
132
+ $response->sendResponse();
133
+ die;
134
+ }
135
+ }
app/code/community/Magestore/Mageinstaller/controllers/IndexController.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Magestore_Mageinstaller_IndexController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ public function indexAction()
5
+ {
6
+
7
+ /*
8
+ * Load an object by id
9
+ * Request looking like:
10
+ * http://site.com/mageinstaller?id=15
11
+ * or
12
+ * http://site.com/mageinstaller/id/15
13
+ */
14
+ /*
15
+ $mageinstaller_id = $this->getRequest()->getParam('id');
16
+
17
+ if($mageinstaller_id != null && $mageinstaller_id != '') {
18
+ $mageinstaller = Mage::getModel('mageinstaller/mageinstaller')->load($mageinstaller_id)->getData();
19
+ } else {
20
+ $mageinstaller = null;
21
+ }
22
+ */
23
+
24
+ /*
25
+ * If no param we load a the last created item
26
+ */
27
+ /*
28
+ if($mageinstaller == null) {
29
+ $resource = Mage::getSingleton('core/resource');
30
+ $read= $resource->getConnection('core_read');
31
+ $mageinstallerTable = $resource->getTableName('mageinstaller');
32
+
33
+ $select = $read->select()
34
+ ->from($mageinstallerTable,array('mageinstaller_id','title','content','status'))
35
+ ->where('status',1)
36
+ ->order('created_time DESC') ;
37
+
38
+ $mageinstaller = $read->fetchRow($select);
39
+ }
40
+ Mage::register('mageinstaller', $mageinstaller);
41
+ */
42
+
43
+
44
+ $this->loadLayout();
45
+ $this->renderLayout();
46
+ }
47
+ }
app/code/community/Magestore/Mageinstaller/etc/config.xml ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Magestore_Mageinstaller>
5
+ <version>0.1.0</version>
6
+ </Magestore_Mageinstaller>
7
+ </modules>
8
+
9
+ <admin>
10
+ <routers>
11
+ <mageinstaller>
12
+ <use>admin</use>
13
+ <args>
14
+ <module>Magestore_Mageinstaller</module>
15
+ <frontName>mageinstaller</frontName>
16
+ </args>
17
+ </mageinstaller>
18
+ </routers>
19
+ </admin>
20
+
21
+ <adminhtml>
22
+ <menu>
23
+ <system>
24
+ <children>
25
+ <mageinstaller module="mageinstaller">
26
+ <title>Mage Installer</title>
27
+ <sort_order>100</sort_order>
28
+ <action>mageinstaller/adminhtml_mageinstaller</action>
29
+ </mageinstaller>
30
+ </children>
31
+ </system>
32
+ </menu>
33
+ <acl>
34
+ <resources>
35
+ <all>
36
+ <title>Allow Everything</title>
37
+ </all>
38
+ <admin>
39
+ <children>
40
+ <Magestore_Mageinstaller>
41
+ <title>Mageinstaller Module</title>
42
+ <sort_order>10</sort_order>
43
+ </Magestore_Mageinstaller>
44
+ </children>
45
+ </admin>
46
+ </resources>
47
+ </acl>
48
+ <layout>
49
+ <updates>
50
+ <mageinstaller>
51
+ <file>mageinstaller.xml</file>
52
+ </mageinstaller>
53
+ </updates>
54
+ </layout>
55
+ </adminhtml>
56
+
57
+ <global>
58
+ <models>
59
+ <mageinstaller>
60
+ <class>Magestore_Mageinstaller_Model</class>
61
+ <resourceModel>mageinstaller_mysql4</resourceModel>
62
+ </mageinstaller>
63
+ <mageinstaller_mysql4>
64
+ <class>Magestore_Mageinstaller_Model_Mysql4</class>
65
+ <entities>
66
+ <extension>
67
+ <table>mageinstaller_extension</table>
68
+ </extension>
69
+ <file>
70
+ <table>mageinstaller_extension_file</table>
71
+ </file>
72
+ </entities>
73
+ </mageinstaller_mysql4>
74
+ </models>
75
+ <resources>
76
+ <mageinstaller_setup>
77
+ <setup>
78
+ <module>Magestore_Mageinstaller</module>
79
+ </setup>
80
+ <connection>
81
+ <use>core_setup</use>
82
+ </connection>
83
+ </mageinstaller_setup>
84
+ <mageinstaller_write>
85
+ <connection>
86
+ <use>core_write</use>
87
+ </connection>
88
+ </mageinstaller_write>
89
+ <mageinstaller_read>
90
+ <connection>
91
+ <use>core_read</use>
92
+ </connection>
93
+ </mageinstaller_read>
94
+ </resources>
95
+ <blocks>
96
+ <mageinstaller>
97
+ <class>Magestore_Mageinstaller_Block</class>
98
+ </mageinstaller>
99
+ </blocks>
100
+ <helpers>
101
+ <mageinstaller>
102
+ <class>Magestore_Mageinstaller_Helper</class>
103
+ </mageinstaller>
104
+ </helpers>
105
+ </global>
106
+
107
+ </config>
app/code/community/Magestore/Mageinstaller/sql/mageinstaller_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+
9
+ DROP TABLE IF EXISTS {$this->getTable('mageinstaller_extension')};
10
+ CREATE TABLE {$this->getTable('mageinstaller_extension')} (
11
+ `extension_id` int(11) unsigned NOT NULL auto_increment,
12
+ `title` varchar(255) NOT NULL default '',
13
+ `total_file` smallint(6) NOT NULL default '0',
14
+ `added_date` datetime NULL,
15
+ PRIMARY KEY (`extension_id`)
16
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
17
+
18
+ DROP TABLE IF EXISTS {$this->getTable('mageinstaller_extension_file')};
19
+ CREATE TABLE {$this->getTable('mageinstaller_extension_file')} (
20
+ `extensionfile_id` int(11) unsigned NOT NULL auto_increment,
21
+ `extension_id` int(11) unsigned NOT NULL,
22
+ `title` varchar(255) NOT NULL default '',
23
+ `path` varchar(255) NOT NULL default '',
24
+ `size` int(11) unsigned,
25
+ PRIMARY KEY (`extensionfile_id`)
26
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
27
+
28
+ ");
29
+
30
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/mageinstaller.xml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <mageinstaller_adminhtml_mageinstaller_index>
4
+ <reference name="content">
5
+ <block type="mageinstaller/adminhtml_mageinstaller" name="mageinstaller" />
6
+ </reference>
7
+ </mageinstaller_adminhtml_mageinstaller_index>
8
+
9
+ <mageinstaller_adminhtml_files_index>
10
+ <reference name="content">
11
+ <block type="mageinstaller/adminhtml_files" name="mageinstaller" />
12
+ </reference>
13
+ </mageinstaller_adminhtml_files_index>
14
+
15
+ </layout>
app/etc/modules/Magestore_Mageinstaller.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Magestore_Mageinstaller>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Magestore_Mageinstaller>
8
+ </modules>
9
+ </config>
lib/PEAR/Archive_Tar.php ADDED
@@ -0,0 +1,1663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set ts=4 sw=4: */
3
+ // +----------------------------------------------------------------------+
4
+ // | PHP Version 4 |
5
+ // +----------------------------------------------------------------------+
6
+ // | Copyright (c) 1997-2003 The PHP Group |
7
+ // +----------------------------------------------------------------------+
8
+ // | This source file is subject to version 3.0 of the PHP license, |
9
+ // | that is bundled with this package in the file LICENSE, and is |
10
+ // | available through the world-wide-web at the following url: |
11
+ // | http://www.php.net/license/3_0.txt. |
12
+ // | If you did not receive a copy of the PHP license and are unable to |
13
+ // | obtain it through the world-wide-web, please send a note to |
14
+ // | license@php.net so we can mail you a copy immediately. |
15
+ // +----------------------------------------------------------------------+
16
+ // | Author: Vincent Blavet <vincent@blavet.net> |
17
+ // +----------------------------------------------------------------------+
18
+ //
19
+ // $Id: Tar.php 6474 2007-02-03 10:47:26Z pasamio $
20
+
21
+ // Check to ensure this file is within the rest of the framework
22
+
23
+ include('PEAR.php');
24
+
25
+ define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001);
26
+
27
+ /**
28
+ * Creates a (compressed) Tar archive
29
+ *
30
+ * @author Vincent Blavet <vincent@blavet.net>
31
+ * @version $Revision: 47 $
32
+ * @package Archive
33
+ */
34
+ class Archive_Tar extends PEAR
35
+ {
36
+ /**
37
+ * @var string Name of the Tar
38
+ */
39
+ var $_tarname='';
40
+
41
+ /**
42
+ * @var boolean if true, the Tar file will be gzipped
43
+ */
44
+ var $_compress=false;
45
+
46
+ /**
47
+ * @var string Type of compression : 'none', 'gz' or 'bz2'
48
+ */
49
+ var $_compress_type='none';
50
+
51
+ /**
52
+ * @var string Explode separator
53
+ */
54
+ var $_separator=' ';
55
+
56
+ /**
57
+ * @var file descriptor
58
+ */
59
+ var $_file=0;
60
+
61
+ /**
62
+ * @var string Local Tar name of a remote Tar (http:// or ftp://)
63
+ */
64
+ var $_temp_tarname='';
65
+
66
+ // {{{ constructor
67
+ /**
68
+ * Archive_Tar Class constructor. This flavour of the constructor only
69
+ * declare a new Archive_Tar object, identifying it by the name of the
70
+ * tar file.
71
+ * If the compress argument is set the tar will be read or created as a
72
+ * gzip or bz2 compressed TAR file.
73
+ *
74
+ * @param string $p_tarname The name of the tar archive to create
75
+ * @param string $p_compress can be null, 'gz' or 'bz2'. This
76
+ * parameter indicates if gzip or bz2 compression
77
+ * is required. For compatibility reason the
78
+ * boolean value 'true' means 'gz'.
79
+ * @access public
80
+ */
81
+ function Archive_Tar($p_tarname, $p_compress = null)
82
+ {
83
+ $this->PEAR();
84
+ $this->_compress = false;
85
+ $this->_compress_type = 'none';
86
+ if ($p_compress === null) {
87
+ if (@file_exists($p_tarname)) {
88
+ if ($fp = @fopen($p_tarname, "rb")) {
89
+ // look for gzip magic cookie
90
+ $data = fread($fp, 2);
91
+ fclose($fp);
92
+ if ($data == "\37\213") {
93
+ $this->_compress = true;
94
+ $this->_compress_type = 'gz';
95
+ // No sure it's enought for a magic code ....
96
+ } elseif ($data == "BZ") {
97
+ $this->_compress = true;
98
+ $this->_compress_type = 'bz2';
99
+ }
100
+ }
101
+ } else {
102
+ // probably a remote file or some file accessible
103
+ // through a stream interface
104
+ if (substr($p_tarname, -2) == 'gz') {
105
+ $this->_compress = true;
106
+ $this->_compress_type = 'gz';
107
+ } elseif ((substr($p_tarname, -3) == 'bz2') ||
108
+ (substr($p_tarname, -2) == 'bz')) {
109
+ $this->_compress = true;
110
+ $this->_compress_type = 'bz2';
111
+ }
112
+ }
113
+ } else {
114
+ if (($p_compress === true) || ($p_compress == 'gz')) {
115
+ $this->_compress = true;
116
+ $this->_compress_type = 'gz';
117
+ } else if ($p_compress == 'bz2') {
118
+ $this->_compress = true;
119
+ $this->_compress_type = 'bz2';
120
+ }
121
+ }
122
+ $this->_tarname = $p_tarname;
123
+ if ($this->_compress) { // assert zlib or bz2 extension support
124
+ if ($this->_compress_type == 'gz')
125
+ $extname = 'zlib';
126
+ else if ($this->_compress_type == 'bz2')
127
+ $extname = 'bz2';
128
+
129
+ if (!extension_loaded($extname)) {
130
+ PEAR::loadExtension($extname);
131
+ }
132
+ if (!extension_loaded($extname)) {
133
+ die("The extension '$extname' couldn't be found.\n".
134
+ "Please make sure your version of PHP was built ".
135
+ "with '$extname' support.\n");
136
+ return false;
137
+ }
138
+ }
139
+ }
140
+ // }}}
141
+
142
+ // {{{ destructor
143
+ function _Archive_Tar()
144
+ {
145
+ $this->_close();
146
+ // ----- Look for a local copy to delete
147
+ if ($this->_temp_tarname != '')
148
+ @unlink($this->_temp_tarname);
149
+ $this->_PEAR();
150
+ }
151
+ // }}}
152
+
153
+ // {{{ create()
154
+ /**
155
+ * This method creates the archive file and add the files / directories
156
+ * that are listed in $p_filelist.
157
+ * If a file with the same name exist and is writable, it is replaced
158
+ * by the new tar.
159
+ * The method return false and a PEAR error text.
160
+ * The $p_filelist parameter can be an array of string, each string
161
+ * representing a filename or a directory name with their path if
162
+ * needed. It can also be a single string with names separated by a
163
+ * single blank.
164
+ * For each directory added in the archive, the files and
165
+ * sub-directories are also added.
166
+ * See also createModify() method for more details.
167
+ *
168
+ * @param array $p_filelist An array of filenames and directory names, or a single
169
+ * string with names separated by a single blank space.
170
+ * @return true on success, false on error.
171
+ * @see createModify()
172
+ * @access public
173
+ */
174
+ function create($p_filelist)
175
+ {
176
+ return $this->createModify($p_filelist, '', '');
177
+ }
178
+ // }}}
179
+
180
+ // {{{ add()
181
+ /**
182
+ * This method add the files / directories that are listed in $p_filelist in
183
+ * the archive. If the archive does not exist it is created.
184
+ * The method return false and a PEAR error text.
185
+ * The files and directories listed are only added at the end of the archive,
186
+ * even if a file with the same name is already archived.
187
+ * See also createModify() method for more details.
188
+ *
189
+ * @param array $p_filelist An array of filenames and directory names, or a single
190
+ * string with names separated by a single blank space.
191
+ * @return true on success, false on error.
192
+ * @see createModify()
193
+ * @access public
194
+ */
195
+ function add($p_filelist)
196
+ {
197
+ return $this->addModify($p_filelist, '', '');
198
+ }
199
+ // }}}
200
+
201
+ // {{{ extract()
202
+ function extract($p_path='')
203
+ {
204
+ return $this->extractModify($p_path, '');
205
+ }
206
+ // }}}
207
+
208
+ // {{{ listContent()
209
+ function listContent()
210
+ {
211
+ $v_list_detail = array();
212
+
213
+ if ($this->_openRead()) {
214
+ if (!$this->_extractList('', $v_list_detail, "list", '', '')) {
215
+ unset($v_list_detail);
216
+ $v_list_detail = 0;
217
+ }
218
+ $this->_close();
219
+ }
220
+
221
+ return $v_list_detail;
222
+ }
223
+ // }}}
224
+
225
+ // {{{ createModify()
226
+ /**
227
+ * This method creates the archive file and add the files / directories
228
+ * that are listed in $p_filelist.
229
+ * If the file already exists and is writable, it is replaced by the
230
+ * new tar. It is a create and not an add. If the file exists and is
231
+ * read-only or is a directory it is not replaced. The method return
232
+ * false and a PEAR error text.
233
+ * The $p_filelist parameter can be an array of string, each string
234
+ * representing a filename or a directory name with their path if
235
+ * needed. It can also be a single string with names separated by a
236
+ * single blank.
237
+ * The path indicated in $p_remove_dir will be removed from the
238
+ * memorized path of each file / directory listed when this path
239
+ * exists. By default nothing is removed (empty path '')
240
+ * The path indicated in $p_add_dir will be added at the beginning of
241
+ * the memorized path of each file / directory listed. However it can
242
+ * be set to empty ''. The adding of a path is done after the removing
243
+ * of path.
244
+ * The path add/remove ability enables the user to prepare an archive
245
+ * for extraction in a different path than the origin files are.
246
+ * See also addModify() method for file adding properties.
247
+ *
248
+ * @param array $p_filelist An array of filenames and directory names, or a single
249
+ * string with names separated by a single blank space.
250
+ * @param string $p_add_dir A string which contains a path to be added to the
251
+ * memorized path of each element in the list.
252
+ * @param string $p_remove_dir A string which contains a path to be removed from
253
+ * the memorized path of each element in the list, when
254
+ * relevant.
255
+ * @return boolean true on success, false on error.
256
+ * @access public
257
+ * @see addModify()
258
+ */
259
+ function createModify($p_filelist, $p_add_dir, $p_remove_dir='')
260
+ {
261
+ $v_result = true;
262
+
263
+ if (!$this->_openWrite())
264
+ return false;
265
+
266
+ if ($p_filelist != '') {
267
+ if (is_array($p_filelist))
268
+ $v_list = $p_filelist;
269
+ elseif (is_string($p_filelist))
270
+ $v_list = explode($this->_separator, $p_filelist);
271
+ else {
272
+ $this->_cleanFile();
273
+ $this->_error('Invalid file list');
274
+ return false;
275
+ }
276
+
277
+ $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir);
278
+ }
279
+
280
+ if ($v_result) {
281
+ $this->_writeFooter();
282
+ $this->_close();
283
+ } else
284
+ $this->_cleanFile();
285
+
286
+ return $v_result;
287
+ }
288
+ // }}}
289
+
290
+ // {{{ addModify()
291
+ /**
292
+ * This method add the files / directories listed in $p_filelist at the
293
+ * end of the existing archive. If the archive does not yet exists it
294
+ * is created.
295
+ * The $p_filelist parameter can be an array of string, each string
296
+ * representing a filename or a directory name with their path if
297
+ * needed. It can also be a single string with names separated by a
298
+ * single blank.
299
+ * The path indicated in $p_remove_dir will be removed from the
300
+ * memorized path of each file / directory listed when this path
301
+ * exists. By default nothing is removed (empty path '')
302
+ * The path indicated in $p_add_dir will be added at the beginning of
303
+ * the memorized path of each file / directory listed. However it can
304
+ * be set to empty ''. The adding of a path is done after the removing
305
+ * of path.
306
+ * The path add/remove ability enables the user to prepare an archive
307
+ * for extraction in a different path than the origin files are.
308
+ * If a file/dir is already in the archive it will only be added at the
309
+ * end of the archive. There is no update of the existing archived
310
+ * file/dir. However while extracting the archive, the last file will
311
+ * replace the first one. This results in a none optimization of the
312
+ * archive size.
313
+ * If a file/dir does not exist the file/dir is ignored. However an
314
+ * error text is send to PEAR error.
315
+ * If a file/dir is not readable the file/dir is ignored. However an
316
+ * error text is send to PEAR error.
317
+ *
318
+ * @param array $p_filelist An array of filenames and directory names, or a single
319
+ * string with names separated by a single blank space.
320
+ * @param string $p_add_dir A string which contains a path to be added to the
321
+ * memorized path of each element in the list.
322
+ * @param string $p_remove_dir A string which contains a path to be removed from
323
+ * the memorized path of each element in the list, when
324
+ * relevant.
325
+ * @return true on success, false on error.
326
+ * @access public
327
+ */
328
+ function addModify($p_filelist, $p_add_dir, $p_remove_dir='')
329
+ {
330
+ $v_result = true;
331
+
332
+ if (!@is_file($this->_tarname))
333
+ $v_result = $this->createModify($p_filelist, $p_add_dir, $p_remove_dir);
334
+ else {
335
+ if (is_array($p_filelist))
336
+ $v_list = $p_filelist;
337
+ elseif (is_string($p_filelist))
338
+ $v_list = explode($this->_separator, $p_filelist);
339
+ else {
340
+ $this->_error('Invalid file list');
341
+ return false;
342
+ }
343
+
344
+ $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir);
345
+ }
346
+
347
+ return $v_result;
348
+ }
349
+ // }}}
350
+
351
+ // {{{ addString()
352
+ /**
353
+ * This method add a single string as a file at the
354
+ * end of the existing archive. If the archive does not yet exists it
355
+ * is created.
356
+ *
357
+ * @param string $p_filename A string which contains the full filename path
358
+ * that will be associated with the string.
359
+ * @param string $p_string The content of the file added in the archive.
360
+ * @return true on success, false on error.
361
+ * @access public
362
+ */
363
+ function addString($p_filename, $p_string)
364
+ {
365
+ $v_result = true;
366
+
367
+ if (!@is_file($this->_tarname)) {
368
+ if (!$this->_openWrite()) {
369
+ return false;
370
+ }
371
+ $this->_close();
372
+ }
373
+
374
+ if (!$this->_openAppend())
375
+ return false;
376
+
377
+ // Need to check the get back to the temporary file ? ....
378
+ $v_result = $this->_addString($p_filename, $p_string);
379
+
380
+ $this->_writeFooter();
381
+
382
+ $this->_close();
383
+
384
+ return $v_result;
385
+ }
386
+ // }}}
387
+
388
+ // {{{ extractModify()
389
+ /**
390
+ * This method extract all the content of the archive in the directory
391
+ * indicated by $p_path. When relevant the memorized path of the
392
+ * files/dir can be modified by removing the $p_remove_path path at the
393
+ * beginning of the file/dir path.
394
+ * While extracting a file, if the directory path does not exists it is
395
+ * created.
396
+ * While extracting a file, if the file already exists it is replaced
397
+ * without looking for last modification date.
398
+ * While extracting a file, if the file already exists and is write
399
+ * protected, the extraction is aborted.
400
+ * While extracting a file, if a directory with the same name already
401
+ * exists, the extraction is aborted.
402
+ * While extracting a directory, if a file with the same name already
403
+ * exists, the extraction is aborted.
404
+ * While extracting a file/directory if the destination directory exist
405
+ * and is write protected, or does not exist but can not be created,
406
+ * the extraction is aborted.
407
+ * If after extraction an extracted file does not show the correct
408
+ * stored file size, the extraction is aborted.
409
+ * When the extraction is aborted, a PEAR error text is set and false
410
+ * is returned. However the result can be a partial extraction that may
411
+ * need to be manually cleaned.
412
+ *
413
+ * @param string $p_path The path of the directory where the files/dir need to by
414
+ * extracted.
415
+ * @param string $p_remove_path Part of the memorized path that can be removed if
416
+ * present at the beginning of the file/dir path.
417
+ * @return boolean true on success, false on error.
418
+ * @access public
419
+ * @see extractList()
420
+ */
421
+ function extractModify($p_path, $p_remove_path)
422
+ {
423
+ $v_result = true;
424
+ $v_list_detail = array();
425
+
426
+ if ($v_result = $this->_openRead()) {
427
+ $v_result = $this->_extractList($p_path, $v_list_detail, "complete", 0, $p_remove_path);
428
+ $this->_close();
429
+ }
430
+
431
+ return $v_result;
432
+ }
433
+ // }}}
434
+
435
+ // {{{ extractInString()
436
+ /**
437
+ * This method extract from the archive one file identified by $p_filename.
438
+ * The return value is a string with the file content, or NULL on error.
439
+ * @param string $p_filename The path of the file to extract in a string.
440
+ * @return a string with the file content or NULL.
441
+ * @access public
442
+ */
443
+ function extractInString($p_filename)
444
+ {
445
+ if ($this->_openRead()) {
446
+ $v_result = $this->_extractInString($p_filename);
447
+ $this->_close();
448
+ } else {
449
+ $v_result = NULL;
450
+ }
451
+
452
+ return $v_result;
453
+ }
454
+ // }}}
455
+
456
+ // {{{ extractList()
457
+ /**
458
+ * This method extract from the archive only the files indicated in the
459
+ * $p_filelist. These files are extracted in the current directory or
460
+ * in the directory indicated by the optional $p_path parameter.
461
+ * If indicated the $p_remove_path can be used in the same way as it is
462
+ * used in extractModify() method.
463
+ * @param array $p_filelist An array of filenames and directory names, or a single
464
+ * string with names separated by a single blank space.
465
+ * @param string $p_path The path of the directory where the files/dir need to by
466
+ * extracted.
467
+ * @param string $p_remove_path Part of the memorized path that can be removed if
468
+ * present at the beginning of the file/dir path.
469
+ * @return true on success, false on error.
470
+ * @access public
471
+ * @see extractModify()
472
+ */
473
+ function extractList($p_filelist, $p_path='', $p_remove_path='')
474
+ {
475
+ $v_result = true;
476
+ $v_list_detail = array();
477
+
478
+ if (is_array($p_filelist))
479
+ $v_list = $p_filelist;
480
+ elseif (is_string($p_filelist))
481
+ $v_list = explode($this->_separator, $p_filelist);
482
+ else {
483
+ $this->_error('Invalid string list');
484
+ return false;
485
+ }
486
+
487
+ if ($v_result = $this->_openRead()) {
488
+ $v_result = $this->_extractList($p_path, $v_list_detail, "partial", $v_list, $p_remove_path);
489
+ $this->_close();
490
+ }
491
+
492
+ return $v_result;
493
+ }
494
+ // }}}
495
+
496
+ // {{{ setAttribute()
497
+ /**
498
+ * This method set specific attributes of the archive. It uses a variable
499
+ * list of parameters, in the format attribute code + attribute values :
500
+ * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ',');
501
+ * @param mixed $argv variable list of attributes and values
502
+ * @return true on success, false on error.
503
+ * @access public
504
+ */
505
+ function setAttribute()
506
+ {
507
+ $v_result = true;
508
+
509
+ // ----- Get the number of variable list of arguments
510
+ if (($v_size = func_num_args()) == 0) {
511
+ return true;
512
+ }
513
+
514
+ // ----- Get the arguments
515
+ $v_att_list = &func_get_args();
516
+
517
+ // ----- Read the attributes
518
+ $i=0;
519
+ while ($i<$v_size) {
520
+
521
+ // ----- Look for next option
522
+ switch ($v_att_list[$i]) {
523
+ // ----- Look for options that request a string value
524
+ case ARCHIVE_TAR_ATT_SEPARATOR :
525
+ // ----- Check the number of parameters
526
+ if (($i+1) >= $v_size) {
527
+ $this->_error('Invalid number of parameters for attribute ARCHIVE_TAR_ATT_SEPARATOR');
528
+ return false;
529
+ }
530
+
531
+ // ----- Get the value
532
+ $this->_separator = $v_att_list[$i+1];
533
+ $i++;
534
+ break;
535
+
536
+ default :
537
+ $this->_error('Unknow attribute code '.$v_att_list[$i].'');
538
+ return false;
539
+ }
540
+
541
+ // ----- Next attribute
542
+ $i++;
543
+ }
544
+
545
+ return $v_result;
546
+ }
547
+ // }}}
548
+
549
+ // {{{ _error()
550
+ function _error($p_message)
551
+ {
552
+ // ----- To be completed
553
+ $this->raiseError($p_message);
554
+ }
555
+ // }}}
556
+
557
+ // {{{ _warning()
558
+ function _warning($p_message)
559
+ {
560
+ // ----- To be completed
561
+ $this->raiseError($p_message);
562
+ }
563
+ // }}}
564
+
565
+ // {{{ _openWrite()
566
+ function _openWrite()
567
+ {
568
+ if ($this->_compress_type == 'gz')
569
+ $this->_file = @gzopen($this->_tarname, "wb");
570
+ else if ($this->_compress_type == 'bz2')
571
+ $this->_file = @bzopen($this->_tarname, "wb");
572
+ else if ($this->_compress_type == 'none')
573
+ $this->_file = @fopen($this->_tarname, "wb");
574
+ else
575
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
576
+
577
+ if ($this->_file == 0) {
578
+ $this->_error('Unable to open in write mode \''.$this->_tarname.'\'');
579
+ return false;
580
+ }
581
+
582
+ return true;
583
+ }
584
+ // }}}
585
+
586
+ // {{{ _openRead()
587
+ function _openRead()
588
+ {
589
+ if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') {
590
+
591
+ // ----- Look if a local copy need to be done
592
+ if ($this->_temp_tarname == '') {
593
+ $this->_temp_tarname = uniqid('tar').'.tmp';
594
+ if (!$v_file_from = @fopen($this->_tarname, 'rb')) {
595
+ $this->_error('Unable to open in read mode \''.$this->_tarname.'\'');
596
+ $this->_temp_tarname = '';
597
+ return false;
598
+ }
599
+ if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) {
600
+ $this->_error('Unable to open in write mode \''.$this->_temp_tarname.'\'');
601
+ $this->_temp_tarname = '';
602
+ return false;
603
+ }
604
+ while ($v_data = @fread($v_file_from, 1024))
605
+ @fwrite($v_file_to, $v_data);
606
+ @fclose($v_file_from);
607
+ @fclose($v_file_to);
608
+ }
609
+
610
+ // ----- File to open if the local copy
611
+ $v_filename = $this->_temp_tarname;
612
+
613
+ } else
614
+ // ----- File to open if the normal Tar file
615
+ $v_filename = $this->_tarname;
616
+
617
+ if ($this->_compress_type == 'gz')
618
+ $this->_file = @gzopen($v_filename, "rb");
619
+ else if ($this->_compress_type == 'bz2')
620
+ $this->_file = @bzopen($v_filename, "rb");
621
+ else if ($this->_compress_type == 'none')
622
+ $this->_file = @fopen($v_filename, "rb");
623
+ else
624
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
625
+
626
+ if ($this->_file == 0) {
627
+ $this->_error('Unable to open in read mode \''.$v_filename.'\'');
628
+ return false;
629
+ }
630
+
631
+ return true;
632
+ }
633
+ // }}}
634
+
635
+ // {{{ _openReadWrite()
636
+ function _openReadWrite()
637
+ {
638
+ if ($this->_compress_type == 'gz')
639
+ $this->_file = @gzopen($this->_tarname, "r+b");
640
+ else if ($this->_compress_type == 'bz2')
641
+ $this->_file = @bzopen($this->_tarname, "r+b");
642
+ else if ($this->_compress_type == 'none')
643
+ $this->_file = @fopen($this->_tarname, "r+b");
644
+ else
645
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
646
+
647
+ if ($this->_file == 0) {
648
+ $this->_error('Unable to open in read/write mode \''.$this->_tarname.'\'');
649
+ return false;
650
+ }
651
+
652
+ return true;
653
+ }
654
+ // }}}
655
+
656
+ // {{{ _close()
657
+ function _close()
658
+ {
659
+ //if (isset($this->_file)) {
660
+ if (is_resource($this->_file)) {
661
+ if ($this->_compress_type == 'gz')
662
+ @gzclose($this->_file);
663
+ else if ($this->_compress_type == 'bz2')
664
+ @bzclose($this->_file);
665
+ else if ($this->_compress_type == 'none')
666
+ @fclose($this->_file);
667
+ else
668
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
669
+
670
+ $this->_file = 0;
671
+ }
672
+
673
+ // ----- Look if a local copy need to be erase
674
+ // Note that it might be interesting to keep the url for a time : ToDo
675
+ if ($this->_temp_tarname != '') {
676
+ @unlink($this->_temp_tarname);
677
+ $this->_temp_tarname = '';
678
+ }
679
+
680
+ return true;
681
+ }
682
+ // }}}
683
+
684
+ // {{{ _cleanFile()
685
+ function _cleanFile()
686
+ {
687
+ $this->_close();
688
+
689
+ // ----- Look for a local copy
690
+ if ($this->_temp_tarname != '') {
691
+ // ----- Remove the local copy but not the remote tarname
692
+ @unlink($this->_temp_tarname);
693
+ $this->_temp_tarname = '';
694
+ } else {
695
+ // ----- Remove the local tarname file
696
+ @unlink($this->_tarname);
697
+ }
698
+ $this->_tarname = '';
699
+
700
+ return true;
701
+ }
702
+ // }}}
703
+
704
+ // {{{ _writeBlock()
705
+ function _writeBlock($p_binary_data, $p_len=null)
706
+ {
707
+ if (is_resource($this->_file)) {
708
+ if ($p_len === null) {
709
+ if ($this->_compress_type == 'gz')
710
+ @gzputs($this->_file, $p_binary_data);
711
+ else if ($this->_compress_type == 'bz2')
712
+ @bzwrite($this->_file, $p_binary_data);
713
+ else if ($this->_compress_type == 'none')
714
+ @fputs($this->_file, $p_binary_data);
715
+ else
716
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
717
+ } else {
718
+ if ($this->_compress_type == 'gz')
719
+ @gzputs($this->_file, $p_binary_data, $p_len);
720
+ else if ($this->_compress_type == 'bz2')
721
+ @bzwrite($this->_file, $p_binary_data, $p_len);
722
+ else if ($this->_compress_type == 'none')
723
+ @fputs($this->_file, $p_binary_data, $p_len);
724
+ else
725
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
726
+
727
+ }
728
+ }
729
+ return true;
730
+ }
731
+ // }}}
732
+
733
+ // {{{ _readBlock()
734
+ function _readBlock($p_len=null)
735
+ {
736
+ $v_block = null;
737
+ if (is_resource($this->_file)) {
738
+ if ($p_len === null)
739
+ $p_len = 512;
740
+
741
+ if ($this->_compress_type == 'gz')
742
+ $v_block = @gzread($this->_file, 512);
743
+ else if ($this->_compress_type == 'bz2')
744
+ $v_block = @bzread($this->_file, 512);
745
+ else if ($this->_compress_type == 'none')
746
+ $v_block = @fread($this->_file, 512);
747
+ else
748
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
749
+
750
+ }
751
+ return $v_block;
752
+ }
753
+ // }}}
754
+
755
+ // {{{ _jumpBlock()
756
+ function _jumpBlock($p_len=null)
757
+ {
758
+ if (is_resource($this->_file)) {
759
+ if ($p_len === null)
760
+ $p_len = 1;
761
+
762
+ if ($this->_compress_type == 'gz')
763
+ @gzseek($this->_file, @gztell($this->_file)+($p_len*512));
764
+ else if ($this->_compress_type == 'bz2') {
765
+ // ----- Replace missing bztell() and bzseek()
766
+ for ($i=0; $i<$p_len; $i++)
767
+ $this->_readBlock();
768
+ } else if ($this->_compress_type == 'none')
769
+ @fseek($this->_file, @ftell($this->_file)+($p_len*512));
770
+ else
771
+ $this->_error('Unknown or missing compression type ('.$this->_compress_type.')');
772
+
773
+ }
774
+ return true;
775
+ }
776
+ // }}}
777
+
778
+ // {{{ _writeFooter()
779
+ function _writeFooter()
780
+ {
781
+ if (is_resource($this->_file)) {
782
+ // ----- Write the last 0 filled block for end of archive
783
+ $v_binary_data = pack("a512", '');
784
+ $this->_writeBlock($v_binary_data);
785
+ }
786
+ return true;
787
+ }
788
+ // }}}
789
+
790
+ // {{{ _addList()
791
+ function _addList($p_list, $p_add_dir, $p_remove_dir)
792
+ {
793
+ $v_result=true;
794
+ $v_header = array();
795
+
796
+ // ----- Remove potential windows directory separator
797
+ $p_add_dir = $this->_translateWinPath($p_add_dir);
798
+ $p_remove_dir = $this->_translateWinPath($p_remove_dir, false);
799
+
800
+ if (!$this->_file) {
801
+ $this->_error('Invalid file descriptor');
802
+ return false;
803
+ }
804
+
805
+ if (sizeof($p_list) == 0)
806
+ return true;
807
+
808
+ for ($j=0; ($j<count($p_list)) && ($v_result); $j++) {
809
+ $v_filename = $p_list[$j];
810
+
811
+ // ----- Skip the current tar name
812
+ if ($v_filename == $this->_tarname)
813
+ continue;
814
+
815
+ if ($v_filename == '')
816
+ continue;
817
+
818
+ if (!file_exists($v_filename)) {
819
+ $this->_warning("File '$v_filename' does not exist");
820
+ continue;
821
+ }
822
+
823
+ // ----- Add the file or directory header
824
+ if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir))
825
+ return false;
826
+
827
+ if (@is_dir($v_filename)) {
828
+ if (!($p_hdir = opendir($v_filename))) {
829
+ $this->_warning("Directory '$v_filename' can not be read");
830
+ continue;
831
+ }
832
+ $p_hitem = readdir($p_hdir); // '.' directory
833
+ $p_hitem = readdir($p_hdir); // '..' directory
834
+ while (false !== ($p_hitem = readdir($p_hdir))) {
835
+ if ($v_filename != ".")
836
+ $p_temp_list[0] = $v_filename.'/'.$p_hitem;
837
+ else
838
+ $p_temp_list[0] = $p_hitem;
839
+
840
+ $v_result = $this->_addList($p_temp_list, $p_add_dir, $p_remove_dir);
841
+ }
842
+
843
+ unset($p_temp_list);
844
+ unset($p_hdir);
845
+ unset($p_hitem);
846
+ }
847
+ }
848
+
849
+ return $v_result;
850
+ }
851
+ // }}}
852
+
853
+ // {{{ _addFile()
854
+ function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir)
855
+ {
856
+ if (!$this->_file) {
857
+ $this->_error('Invalid file descriptor');
858
+ return false;
859
+ }
860
+
861
+ if ($p_filename == '') {
862
+ $this->_error('Invalid file name');
863
+ return false;
864
+ }
865
+
866
+ // ----- Calculate the stored filename
867
+ $p_filename = $this->_translateWinPath($p_filename, false);;
868
+ $v_stored_filename = $p_filename;
869
+ if (strcmp($p_filename, $p_remove_dir) == 0) {
870
+ return true;
871
+ }
872
+ if ($p_remove_dir != '') {
873
+ if (substr($p_remove_dir, -1) != '/')
874
+ $p_remove_dir .= '/';
875
+
876
+ if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
877
+ $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
878
+ }
879
+ $v_stored_filename = $this->_translateWinPath($v_stored_filename);
880
+ if ($p_add_dir != '') {
881
+ if (substr($p_add_dir, -1) == '/')
882
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
883
+ else
884
+ $v_stored_filename = $p_add_dir.'/'.$v_stored_filename;
885
+ }
886
+
887
+ $v_stored_filename = $this->_pathReduction($v_stored_filename);
888
+
889
+ if (is_file($p_filename)) {
890
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
891
+ $this->_warning("Unable to open file '$p_filename' in binary read mode");
892
+ return true;
893
+ }
894
+
895
+ if (!$this->_writeHeader($p_filename, $v_stored_filename))
896
+ return false;
897
+
898
+ while (($v_buffer = fread($v_file, 512)) != '') {
899
+ $v_binary_data = pack("a512", "$v_buffer");
900
+ $this->_writeBlock($v_binary_data);
901
+ }
902
+
903
+ fclose($v_file);
904
+
905
+ } else {
906
+ // ----- Only header for dir
907
+ if (!$this->_writeHeader($p_filename, $v_stored_filename))
908
+ return false;
909
+ }
910
+
911
+ return true;
912
+ }
913
+ // }}}
914
+
915
+ // {{{ _addString()
916
+ function _addString($p_filename, $p_string)
917
+ {
918
+ if (!$this->_file) {
919
+ $this->_error('Invalid file descriptor');
920
+ return false;
921
+ }
922
+
923
+ if ($p_filename == '') {
924
+ $this->_error('Invalid file name');
925
+ return false;
926
+ }
927
+
928
+ // ----- Calculate the stored filename
929
+ $p_filename = $this->_translateWinPath($p_filename, false);;
930
+
931
+ if (!$this->_writeHeaderBlock($p_filename, strlen($p_string), 0, 0, "", 0, 0))
932
+ return false;
933
+
934
+ $i=0;
935
+ while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') {
936
+ $v_binary_data = pack("a512", $v_buffer);
937
+ $this->_writeBlock($v_binary_data);
938
+ }
939
+
940
+ return true;
941
+ }
942
+ // }}}
943
+
944
+ // {{{ _writeHeader()
945
+ function _writeHeader($p_filename, $p_stored_filename)
946
+ {
947
+ if ($p_stored_filename == '')
948
+ $p_stored_filename = $p_filename;
949
+ $v_reduce_filename = $this->_pathReduction($p_stored_filename);
950
+
951
+ if (strlen($v_reduce_filename) > 99) {
952
+ if (!$this->_writeLongHeader($v_reduce_filename))
953
+ return false;
954
+ }
955
+
956
+ $v_info = stat($p_filename);
957
+ $v_uid = sprintf("%6s ", DecOct($v_info[4]));
958
+ $v_gid = sprintf("%6s ", DecOct($v_info[5]));
959
+ $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
960
+
961
+ $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename)));
962
+
963
+ if (@is_dir($p_filename)) {
964
+ $v_typeflag = "5";
965
+ $v_size = sprintf("%11s ", DecOct(0));
966
+ } else {
967
+ $v_typeflag = '';
968
+ clearstatcache();
969
+ $v_size = sprintf("%11s ", DecOct(filesize($p_filename)));
970
+ }
971
+
972
+ $v_linkname = '';
973
+
974
+ $v_magic = '';
975
+
976
+ $v_version = '';
977
+
978
+ $v_uname = '';
979
+
980
+ $v_gname = '';
981
+
982
+ $v_devmajor = '';
983
+
984
+ $v_devminor = '';
985
+
986
+ $v_prefix = '';
987
+
988
+ $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime);
989
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '');
990
+
991
+ // ----- Calculate the checksum
992
+ $v_checksum = 0;
993
+ // ..... First part of the header
994
+ for ($i=0; $i<148; $i++)
995
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
996
+ // ..... Ignore the checksum value and replace it by ' ' (space)
997
+ for ($i=148; $i<156; $i++)
998
+ $v_checksum += ord(' ');
999
+ // ..... Last part of the header
1000
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1001
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1002
+
1003
+ // ----- Write the first 148 bytes of the header in the archive
1004
+ $this->_writeBlock($v_binary_data_first, 148);
1005
+
1006
+ // ----- Write the calculated checksum
1007
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1008
+ $v_binary_data = pack("a8", $v_checksum);
1009
+ $this->_writeBlock($v_binary_data, 8);
1010
+
1011
+ // ----- Write the last 356 bytes of the header in the archive
1012
+ $this->_writeBlock($v_binary_data_last, 356);
1013
+
1014
+ return true;
1015
+ }
1016
+ // }}}
1017
+
1018
+ // {{{ _writeHeaderBlock()
1019
+ function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0, $p_type='', $p_uid=0, $p_gid=0)
1020
+ {
1021
+ $p_filename = $this->_pathReduction($p_filename);
1022
+
1023
+ if (strlen($p_filename) > 99) {
1024
+ if (!$this->_writeLongHeader($p_filename))
1025
+ return false;
1026
+ }
1027
+
1028
+ if ($p_type == "5") {
1029
+ $v_size = sprintf("%11s ", DecOct(0));
1030
+ } else {
1031
+ $v_size = sprintf("%11s ", DecOct($p_size));
1032
+ }
1033
+
1034
+ $v_uid = sprintf("%6s ", DecOct($p_uid));
1035
+ $v_gid = sprintf("%6s ", DecOct($p_gid));
1036
+ $v_perms = sprintf("%6s ", DecOct($p_perms));
1037
+
1038
+ $v_mtime = sprintf("%11s", DecOct($p_mtime));
1039
+
1040
+ $v_linkname = '';
1041
+
1042
+ $v_magic = '';
1043
+
1044
+ $v_version = '';
1045
+
1046
+ $v_uname = '';
1047
+
1048
+ $v_gname = '';
1049
+
1050
+ $v_devmajor = '';
1051
+
1052
+ $v_devminor = '';
1053
+
1054
+ $v_prefix = '';
1055
+
1056
+ $v_binary_data_first = pack("a100a8a8a8a12A12", $p_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime);
1057
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $p_type, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '');
1058
+
1059
+ // ----- Calculate the checksum
1060
+ $v_checksum = 0;
1061
+ // ..... First part of the header
1062
+ for ($i=0; $i<148; $i++)
1063
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
1064
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1065
+ for ($i=148; $i<156; $i++)
1066
+ $v_checksum += ord(' ');
1067
+ // ..... Last part of the header
1068
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1069
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1070
+
1071
+ // ----- Write the first 148 bytes of the header in the archive
1072
+ $this->_writeBlock($v_binary_data_first, 148);
1073
+
1074
+ // ----- Write the calculated checksum
1075
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1076
+ $v_binary_data = pack("a8", $v_checksum);
1077
+ $this->_writeBlock($v_binary_data, 8);
1078
+
1079
+ // ----- Write the last 356 bytes of the header in the archive
1080
+ $this->_writeBlock($v_binary_data_last, 356);
1081
+
1082
+ return true;
1083
+ }
1084
+ // }}}
1085
+
1086
+ // {{{ _writeLongHeader()
1087
+ function _writeLongHeader($p_filename)
1088
+ {
1089
+ $v_size = sprintf("%11s ", DecOct(strlen($p_filename)));
1090
+
1091
+ $v_typeflag = 'L';
1092
+
1093
+ $v_linkname = '';
1094
+
1095
+ $v_magic = '';
1096
+
1097
+ $v_version = '';
1098
+
1099
+ $v_uname = '';
1100
+
1101
+ $v_gname = '';
1102
+
1103
+ $v_devmajor = '';
1104
+
1105
+ $v_devminor = '';
1106
+
1107
+ $v_prefix = '';
1108
+
1109
+ $v_binary_data_first = pack("a100a8a8a8a12A12", '././@LongLink', 0, 0, 0, $v_size, 0);
1110
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '');
1111
+
1112
+ // ----- Calculate the checksum
1113
+ $v_checksum = 0;
1114
+ // ..... First part of the header
1115
+ for ($i=0; $i<148; $i++)
1116
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
1117
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1118
+ for ($i=148; $i<156; $i++)
1119
+ $v_checksum += ord(' ');
1120
+ // ..... Last part of the header
1121
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1122
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1123
+
1124
+ // ----- Write the first 148 bytes of the header in the archive
1125
+ $this->_writeBlock($v_binary_data_first, 148);
1126
+
1127
+ // ----- Write the calculated checksum
1128
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1129
+ $v_binary_data = pack("a8", $v_checksum);
1130
+ $this->_writeBlock($v_binary_data, 8);
1131
+
1132
+ // ----- Write the last 356 bytes of the header in the archive
1133
+ $this->_writeBlock($v_binary_data_last, 356);
1134
+
1135
+ // ----- Write the filename as content of the block
1136
+ $i=0;
1137
+ while (($v_buffer = substr($p_filename, (($i++)*512), 512)) != '') {
1138
+ $v_binary_data = pack("a512", "$v_buffer");
1139
+ $this->_writeBlock($v_binary_data);
1140
+ }
1141
+
1142
+ return true;
1143
+ }
1144
+ // }}}
1145
+
1146
+ // {{{ _readHeader()
1147
+ function _readHeader($v_binary_data, &$v_header)
1148
+ {
1149
+ if (strlen($v_binary_data)==0) {
1150
+ $v_header['filename'] = '';
1151
+ return true;
1152
+ }
1153
+
1154
+ if (strlen($v_binary_data) != 512) {
1155
+ $v_header['filename'] = '';
1156
+ $this->_error('Invalid block size : '.strlen($v_binary_data));
1157
+ return false;
1158
+ }
1159
+
1160
+ // ----- Calculate the checksum
1161
+ $v_checksum = 0;
1162
+ // ..... First part of the header
1163
+ for ($i=0; $i<148; $i++)
1164
+ $v_checksum+=ord(substr($v_binary_data,$i,1));
1165
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1166
+ for ($i=148; $i<156; $i++)
1167
+ $v_checksum += ord(' ');
1168
+ // ..... Last part of the header
1169
+ for ($i=156; $i<512; $i++)
1170
+ $v_checksum+=ord(substr($v_binary_data,$i,1));
1171
+
1172
+ $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data);
1173
+
1174
+ // ----- Extract the checksum
1175
+ $v_header['checksum'] = OctDec(trim($v_data['checksum']));
1176
+ if ($v_header['checksum'] != $v_checksum) {
1177
+ $v_header['filename'] = '';
1178
+
1179
+ // ----- Look for last block (empty block)
1180
+ if (($v_checksum == 256) && ($v_header['checksum'] == 0))
1181
+ return true;
1182
+
1183
+ $this->_error('Invalid checksum for file "'.$v_data['filename'].'" : '.$v_checksum.' calculated, '.$v_header['checksum'].' expected');
1184
+ return false;
1185
+ }
1186
+
1187
+ // ----- Extract the properties
1188
+ $v_header['filename'] = trim($v_data['filename']);
1189
+ $v_header['mode'] = OctDec(trim($v_data['mode']));
1190
+ $v_header['uid'] = OctDec(trim($v_data['uid']));
1191
+ $v_header['gid'] = OctDec(trim($v_data['gid']));
1192
+ $v_header['size'] = OctDec(trim($v_data['size']));
1193
+ $v_header['mtime'] = OctDec(trim($v_data['mtime']));
1194
+ if (($v_header['typeflag'] = $v_data['typeflag']) == "5") {
1195
+ $v_header['size'] = 0;
1196
+ }
1197
+ /* ----- All these fields are removed form the header because they do not carry interesting info
1198
+ $v_header[link] = trim($v_data[link]);
1199
+ $v_header[magic] = trim($v_data[magic]);
1200
+ $v_header[version] = trim($v_data[version]);
1201
+ $v_header[uname] = trim($v_data[uname]);
1202
+ $v_header[gname] = trim($v_data[gname]);
1203
+ $v_header[devmajor] = trim($v_data[devmajor]);
1204
+ $v_header[devminor] = trim($v_data[devminor]);
1205
+ */
1206
+
1207
+ return true;
1208
+ }
1209
+ // }}}
1210
+
1211
+ // {{{ _readLongHeader()
1212
+ function _readLongHeader(&$v_header)
1213
+ {
1214
+ $v_filename = '';
1215
+ $n = floor($v_header['size']/512);
1216
+ for ($i=0; $i<$n; $i++) {
1217
+ $v_content = $this->_readBlock();
1218
+ $v_filename .= $v_content;
1219
+ }
1220
+ if (($v_header['size'] % 512) != 0) {
1221
+ $v_content = $this->_readBlock();
1222
+ $v_filename .= $v_content;
1223
+ }
1224
+
1225
+ // ----- Read the next header
1226
+ $v_binary_data = $this->_readBlock();
1227
+
1228
+ if (!$this->_readHeader($v_binary_data, $v_header))
1229
+ return false;
1230
+
1231
+ $v_header['filename'] = $v_filename;
1232
+
1233
+ return true;
1234
+ }
1235
+ // }}}
1236
+
1237
+ // {{{ _extractInString()
1238
+ /**
1239
+ * This method extract from the archive one file identified by $p_filename.
1240
+ * The return value is a string with the file content, or NULL on error.
1241
+ * @param string $p_filename The path of the file to extract in a string.
1242
+ * @return a string with the file content or NULL.
1243
+ * @access private
1244
+ */
1245
+ function _extractInString($p_filename)
1246
+ {
1247
+ $v_result_str = "";
1248
+ $v_header = array();
1249
+
1250
+ While (strlen($v_binary_data = $this->_readBlock()) != 0)
1251
+ {
1252
+ if (!$this->_readHeader($v_binary_data, $v_header))
1253
+ return NULL;
1254
+
1255
+ if ($v_header['filename'] == '')
1256
+ continue;
1257
+
1258
+ // ----- Look for long filename
1259
+ if ($v_header['typeflag'] == 'L') {
1260
+ if (!$this->_readLongHeader($v_header))
1261
+ return NULL;
1262
+ }
1263
+
1264
+ if ($v_header['filename'] == $p_filename) {
1265
+ if ($v_header['typeflag'] == "5") {
1266
+ $this->_error('Unable to extract in string a directory entry {'.$v_header['filename'].'}');
1267
+ return NULL;
1268
+ } else {
1269
+ $n = floor($v_header['size']/512);
1270
+ for ($i=0; $i<$n; $i++) {
1271
+ $v_result_str .= $this->_readBlock();
1272
+ }
1273
+ if (($v_header['size'] % 512) != 0) {
1274
+ $v_content = $this->_readBlock();
1275
+ $v_result_str .= substr($v_content, 0, ($v_header['size'] % 512));
1276
+ }
1277
+ return $v_result_str;
1278
+ }
1279
+ } else {
1280
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1281
+ }
1282
+ }
1283
+
1284
+ return NULL;
1285
+ }
1286
+ // }}}
1287
+
1288
+ // {{{ _extractList()
1289
+ function _extractList($p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path)
1290
+ {
1291
+ $v_result=true;
1292
+ $v_nb = 0;
1293
+ $v_extract_all = true;
1294
+ $v_listing = false;
1295
+
1296
+ $p_path = $this->_translateWinPath($p_path, false);
1297
+ if ($p_path == '' || (substr($p_path, 0, 1) != '/' && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) {
1298
+ $p_path = "./".$p_path;
1299
+ }
1300
+ $p_remove_path = $this->_translateWinPath($p_remove_path);
1301
+
1302
+ // ----- Look for path to remove format (should end by /)
1303
+ if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/'))
1304
+ $p_remove_path .= '/';
1305
+ $p_remove_path_size = strlen($p_remove_path);
1306
+
1307
+ switch ($p_mode) {
1308
+ case "complete" :
1309
+ $v_extract_all = TRUE;
1310
+ $v_listing = FALSE;
1311
+ break;
1312
+ case "partial" :
1313
+ $v_extract_all = FALSE;
1314
+ $v_listing = FALSE;
1315
+ break;
1316
+ case "list" :
1317
+ $v_extract_all = FALSE;
1318
+ $v_listing = TRUE;
1319
+ break;
1320
+ default :
1321
+ $this->_error('Invalid extract mode ('.$p_mode.')');
1322
+ return false;
1323
+ }
1324
+
1325
+ clearstatcache();
1326
+
1327
+ $v_header = array();
1328
+ While (strlen($v_binary_data = $this->_readBlock()) != 0)
1329
+ {
1330
+ $v_extract_file = FALSE;
1331
+ $v_extraction_stopped = 0;
1332
+
1333
+ if (!$this->_readHeader($v_binary_data, $v_header))
1334
+ return false;
1335
+
1336
+ if ($v_header['filename'] == '')
1337
+ continue;
1338
+
1339
+ // ----- Look for long filename
1340
+ if ($v_header['typeflag'] == 'L') {
1341
+ if (!$this->_readLongHeader($v_header))
1342
+ return false;
1343
+ }
1344
+
1345
+ if ((!$v_extract_all) && (is_array($p_file_list))) {
1346
+ // ----- By default no unzip if the file is not found
1347
+ $v_extract_file = false;
1348
+
1349
+ for ($i=0; $i<sizeof($p_file_list); $i++) {
1350
+ // ----- Look if it is a directory
1351
+ if (substr($p_file_list[$i], -1) == '/') {
1352
+ // ----- Look if the directory is in the filename path
1353
+ if ((strlen($v_header['filename']) > strlen($p_file_list[$i])) && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) == $p_file_list[$i])) {
1354
+ $v_extract_file = TRUE;
1355
+ break;
1356
+ }
1357
+ }
1358
+
1359
+ // ----- It is a file, so compare the file names
1360
+ elseif ($p_file_list[$i] == $v_header['filename']) {
1361
+ $v_extract_file = TRUE;
1362
+ break;
1363
+ }
1364
+ }
1365
+ } else {
1366
+ $v_extract_file = TRUE;
1367
+ }
1368
+
1369
+ // ----- Look if this file need to be extracted
1370
+ if (($v_extract_file) && (!$v_listing))
1371
+ {
1372
+ if (($p_remove_path != '')
1373
+ && (substr($v_header['filename'], 0, $p_remove_path_size) == $p_remove_path))
1374
+ $v_header['filename'] = substr($v_header['filename'], $p_remove_path_size);
1375
+ if (($p_path != './') && ($p_path != '/')) {
1376
+ while (substr($p_path, -1) == '/')
1377
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
1378
+
1379
+ if (substr($v_header['filename'], 0, 1) == '/')
1380
+ $v_header['filename'] = $p_path.$v_header['filename'];
1381
+ else
1382
+ $v_header['filename'] = $p_path.'/'.$v_header['filename'];
1383
+ }
1384
+ if (file_exists($v_header['filename'])) {
1385
+ if ((@is_dir($v_header['filename'])) && ($v_header['typeflag'] == '')) {
1386
+ $this->_error('File '.$v_header['filename'].' already exists as a directory');
1387
+ return false;
1388
+ }
1389
+ if ((is_file($v_header['filename'])) && ($v_header['typeflag'] == "5")) {
1390
+ $this->_error('Directory '.$v_header['filename'].' already exists as a file');
1391
+ return false;
1392
+ }
1393
+ if (!is_writeable($v_header['filename'])) {
1394
+ $this->_error('File '.$v_header['filename'].' already exists and is write protected');
1395
+ return false;
1396
+ }
1397
+ if (filemtime($v_header['filename']) > $v_header['mtime']) {
1398
+ // To be completed : An error or silent no replace ?
1399
+ }
1400
+ }
1401
+
1402
+ // ----- Check the directory availability and create it if necessary
1403
+ elseif (($v_result = $this->_dirCheck(($v_header['typeflag'] == "5"?$v_header['filename']:dirname($v_header['filename'])))) != 1) {
1404
+ $this->_error('Unable to create path for '.$v_header['filename']);
1405
+ return false;
1406
+ }
1407
+
1408
+ if ($v_extract_file) {
1409
+ if ($v_header['typeflag'] == "5") {
1410
+ if (!@file_exists($v_header['filename'])) {
1411
+ if (!@mkdir($v_header['filename'], 0777)) {
1412
+ $this->_error('Unable to create directory {'.$v_header['filename'].'}');
1413
+ return false;
1414
+ }
1415
+ }
1416
+ } else {
1417
+ if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) {
1418
+ $this->_error('Error while opening {'.$v_header['filename'].'} in write binary mode');
1419
+ return false;
1420
+ } else {
1421
+ $n = floor($v_header['size']/512);
1422
+ for ($i=0; $i<$n; $i++) {
1423
+ $v_content = $this->_readBlock();
1424
+ fwrite($v_dest_file, $v_content, 512);
1425
+ }
1426
+ if (($v_header['size'] % 512) != 0) {
1427
+ $v_content = $this->_readBlock();
1428
+ fwrite($v_dest_file, $v_content, ($v_header['size'] % 512));
1429
+ }
1430
+
1431
+ @fclose($v_dest_file);
1432
+
1433
+ // ----- Change the file mode, mtime
1434
+ @touch($v_header['filename'], $v_header['mtime']);
1435
+ // To be completed
1436
+ //chmod($v_header[filename], DecOct($v_header[mode]));
1437
+ }
1438
+
1439
+ // ----- Check the file size
1440
+ clearstatcache();
1441
+ if (filesize($v_header['filename']) != $v_header['size']) {
1442
+ $this->_error('Extracted file '.$v_header['filename'].' does not have the correct file size \''.filesize($v_header['filename']).'\' ('.$v_header['size'].' expected). Archive may be corrupted.');
1443
+ return false;
1444
+ }
1445
+ }
1446
+ } else {
1447
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1448
+ }
1449
+ } else {
1450
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1451
+ }
1452
+
1453
+ /* TBC : Seems to be unused ...
1454
+ if ($this->_compress)
1455
+ $v_end_of_file = @gzeof($this->_file);
1456
+ else
1457
+ $v_end_of_file = @feof($this->_file);
1458
+ */
1459
+
1460
+ if ($v_listing || $v_extract_file || $v_extraction_stopped) {
1461
+ // ----- Log extracted files
1462
+ if (($v_file_dir = dirname($v_header['filename'])) == $v_header['filename'])
1463
+ $v_file_dir = '';
1464
+ if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == ''))
1465
+ $v_file_dir = '/';
1466
+
1467
+ $p_list_detail[$v_nb++] = $v_header;
1468
+ }
1469
+ }
1470
+
1471
+ return true;
1472
+ }
1473
+ // }}}
1474
+
1475
+ // {{{ _openAppend()
1476
+ function _openAppend()
1477
+ {
1478
+ if (filesize($this->_tarname) == 0)
1479
+ return $this->_openWrite();
1480
+
1481
+ if ($this->_compress) {
1482
+ $this->_close();
1483
+
1484
+ if (!@rename($this->_tarname, $this->_tarname.".tmp")) {
1485
+ $this->_error('Error while renaming \''.$this->_tarname.'\' to temporary file \''.$this->_tarname.'.tmp\'');
1486
+ return false;
1487
+ }
1488
+
1489
+ if ($this->_compress_type == 'gz')
1490
+ $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb");
1491
+ elseif ($this->_compress_type == 'bz2')
1492
+ $v_temp_tar = @bzopen($this->_tarname.".tmp", "rb");
1493
+
1494
+ if ($v_temp_tar == 0) {
1495
+ $this->_error('Unable to open file \''.$this->_tarname.'.tmp\' in binary read mode');
1496
+ @rename($this->_tarname.".tmp", $this->_tarname);
1497
+ return false;
1498
+ }
1499
+
1500
+ if (!$this->_openWrite()) {
1501
+ @rename($this->_tarname.".tmp", $this->_tarname);
1502
+ return false;
1503
+ }
1504
+
1505
+ if ($this->_compress_type == 'gz') {
1506
+ $v_buffer = @gzread($v_temp_tar, 512);
1507
+
1508
+ // ----- Read the following blocks but not the last one
1509
+ if (!@gzeof($v_temp_tar)) {
1510
+ do{
1511
+ $v_binary_data = pack("a512", $v_buffer);
1512
+ $this->_writeBlock($v_binary_data);
1513
+ $v_buffer = @gzread($v_temp_tar, 512);
1514
+
1515
+ } while (!@gzeof($v_temp_tar));
1516
+ }
1517
+
1518
+ @gzclose($v_temp_tar);
1519
+ }
1520
+ elseif ($this->_compress_type == 'bz2') {
1521
+ $v_buffered_lines = array();
1522
+ $v_buffered_lines[] = @bzread($v_temp_tar, 512);
1523
+
1524
+ // ----- Read the following blocks but not the last one
1525
+ while (strlen($v_buffered_lines[] = @bzread($v_temp_tar, 512)) > 0) {
1526
+ $v_binary_data = pack("a512", array_shift($v_buffered_lines));
1527
+ $this->_writeBlock($v_binary_data);
1528
+ }
1529
+
1530
+ @bzclose($v_temp_tar);
1531
+ }
1532
+
1533
+ if (!@unlink($this->_tarname.".tmp")) {
1534
+ $this->_error('Error while deleting temporary file \''.$this->_tarname.'.tmp\'');
1535
+ }
1536
+
1537
+ } else {
1538
+ // ----- For not compressed tar, just add files before the last 512 bytes block
1539
+ if (!$this->_openReadWrite())
1540
+ return false;
1541
+
1542
+ clearstatcache();
1543
+ $v_size = filesize($this->_tarname);
1544
+ fseek($this->_file, $v_size-512);
1545
+ }
1546
+
1547
+ return true;
1548
+ }
1549
+ // }}}
1550
+
1551
+ // {{{ _append()
1552
+ function _append($p_filelist, $p_add_dir='', $p_remove_dir='')
1553
+ {
1554
+ if (!$this->_openAppend())
1555
+ return false;
1556
+
1557
+ if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir))
1558
+ $this->_writeFooter();
1559
+
1560
+ $this->_close();
1561
+
1562
+ return true;
1563
+ }
1564
+ // }}}
1565
+
1566
+ // {{{ _dirCheck()
1567
+
1568
+ /**
1569
+ * Check if a directory exists and create it (including parent
1570
+ * dirs) if not.
1571
+ *
1572
+ * @param string $p_dir directory to check
1573
+ *
1574
+ * @return bool TRUE if the directory exists or was created
1575
+ */
1576
+ function _dirCheck($p_dir)
1577
+ {
1578
+ if ((@is_dir($p_dir)) || ($p_dir == ''))
1579
+ return true;
1580
+
1581
+ $p_parent_dir = dirname($p_dir);
1582
+
1583
+ if (($p_parent_dir != $p_dir) &&
1584
+ ($p_parent_dir != '') &&
1585
+ (!$this->_dirCheck($p_parent_dir)))
1586
+ return false;
1587
+
1588
+ if (!@mkdir($p_dir, 0777)) {
1589
+ $this->_error("Unable to create directory '$p_dir'");
1590
+ return false;
1591
+ }
1592
+
1593
+ return true;
1594
+ }
1595
+
1596
+ // }}}
1597
+
1598
+ // {{{ _pathReduction()
1599
+
1600
+ /**
1601
+ * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", and
1602
+ * remove double slashes.
1603
+ *
1604
+ * @param string $p_dir path to reduce
1605
+ *
1606
+ * @return string reduced path
1607
+ *
1608
+ * @access private
1609
+ *
1610
+ */
1611
+ function _pathReduction($p_dir)
1612
+ {
1613
+ $v_result = '';
1614
+
1615
+ // ----- Look for not empty path
1616
+ if ($p_dir != '') {
1617
+ // ----- Explode path by directory names
1618
+ $v_list = explode('/', $p_dir);
1619
+
1620
+ // ----- Study directories from last to first
1621
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
1622
+ // ----- Look for current path
1623
+ if ($v_list[$i] == ".") {
1624
+ // ----- Ignore this directory
1625
+ // Should be the first $i=0, but no check is done
1626
+ }
1627
+ else if ($v_list[$i] == "..") {
1628
+ // ----- Ignore it and ignore the $i-1
1629
+ $i--;
1630
+ }
1631
+ else if (($v_list[$i] == '') && ($i!=(sizeof($v_list)-1)) && ($i!=0)) {
1632
+ // ----- Ignore only the double '//' in path,
1633
+ // but not the first and last /
1634
+ } else {
1635
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?'/'.$v_result:'');
1636
+ }
1637
+ }
1638
+ }
1639
+ $v_result = strtr($v_result, '\\', '/');
1640
+ return $v_result;
1641
+ }
1642
+
1643
+ // }}}
1644
+
1645
+ // {{{ _translateWinPath()
1646
+ function _translateWinPath($p_path, $p_remove_disk_letter=true)
1647
+ {
1648
+ if (OS_WINDOWS) {
1649
+ // ----- Look for potential disk letter
1650
+ if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
1651
+ $p_path = substr($p_path, $v_position+1);
1652
+ }
1653
+ // ----- Change potential windows directory separator
1654
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
1655
+ $p_path = strtr($p_path, '\\', '/');
1656
+ }
1657
+ }
1658
+ return $p_path;
1659
+ }
1660
+ // }}}
1661
+
1662
+ }
1663
+ ?>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>MagentoInstaller</name>
4
+ <version>0.1.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>A tool to install magento extension from the admin section.</summary>
10
+ <description>A tool to install magento extension from the admin section.</description>
11
+ <notes>0.1.0</notes>
12
+ <authors><author><name>Magestore</name><user>auto-converted</user><email>magestore@gmail.com</email></author></authors>
13
+ <date>2010-02-04</date>
14
+ <time>09:25:34</time>
15
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mageinstaller.xml" hash="30e3f824d2ef01fc626cb15460a2c718"/></dir></dir></dir></dir></target><target name="mage"><dir name="lib"><dir name="PEAR"><file name="Archive_Tar.php" hash="b064779adbef1c0189bd78acce2b300e"/></dir></dir></target><target name="magecommunity"><dir name="Magestore"><dir name="Mageinstaller"><dir name="Block"><dir name="Adminhtml"><file name="Files.php" hash="228919607ad4b9481ed724b3cebae6c9"/><file name="Mageinstaller.php" hash="8fa8391489998aea47ddb41d34b44c83"/><dir name="Files"><file name="Grid.php" hash="312e1bd9f6e7265d17ea78f5ccfb599c"/></dir><dir name="Mageinstaller"><file name="Edit.php" hash="8058552f60305db6d39dff15de05d6a4"/><file name="Grid.php" hash="d7db6c5d60cbc1a37d24a7a06c308357"/><dir name="Edit"><file name="Form.php" hash="ba42dd756c5c3e70ea766df57b049121"/><file name="Tabs.php" hash="99f890589de33579591f43fd09f4d726"/><dir name="Tab"><file name="Form.php" hash="253f7cadc38da7a7b0dfc6087f38b7b8"/></dir></dir></dir></dir></dir><dir name="controllers"><file name="IndexController.php" hash="0376ad787f7730891d10d6750ab17da2"/><dir name="Adminhtml"><file name="FilesController.php" hash="a03eb991237e29c8f4fbd7d7ef13bb95"/><file name="MageinstallerController.php" hash="82e4b317c527ff283f420c0eb5cd638c"/></dir></dir><dir name="etc"><file name="config.xml" hash="1a5c4c7424be51068c04a7d37cecc715"/></dir><dir name="Helper"><file name="Data.php" hash="54a9bf5135c6dc4196d6c5e5b4809e6c"/></dir><dir name="Model"><file name="Extension.php" hash="f9aca70b260b130eccd26a1761df62b5"/><file name="File.php" hash="2c1046e6d4a7bebbfc0aac5697c75145"/><file name="Gzipper.php" hash="e0405d263b5b7aab3ec3a6badf17f5d8"/><file name="Installer.php" hash="22677f634bc182080714aa5cf1f8d078"/><file name="Status.php" hash="9707c26163e27d94af70c91e8713e82b"/><file name="Zipper.php" hash="6cbd27b155b5bf7f2037e235c99f1a19"/><dir name="Mysql4"><file name="Extension.php" hash="d5546bb27e232d42542b1742fffdd528"/><file name="File.php" hash="5c237ce87118e85f14b75a34bcc9f24f"/><dir name="Extension"><file name="Collection.php" hash="ec89152fbcf73733c6cefa865930baab"/></dir><dir name="File"><file name="Collection.php" hash="4e147df750662e5bdf6858c3940ad9b1"/></dir></dir></dir><dir name="sql"><dir name="mageinstaller_setup"><file name="mysql4-install-0.1.0.php" hash="6370405dd3443bef5e48217c62e9c8b7"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Magestore_Mageinstaller.xml" hash="ba5d8422790e977b906efc2b28bb6edd"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies/>
18
+ </package>