1 <?php
  2   3   4   5   6   7   8 
  9 
 10 defined('JPATH_PLATFORM') or die;
 11 
 12 jimport('joomla.filesystem.folder');
 13 
 14  15  16  17  18 
 19 class JInstallerAdapterFile extends JInstallerAdapter
 20 {
 21      22  23  24  25  26 
 27     protected $scriptElement = null;
 28 
 29      30  31  32  33  34  35  36 
 37     protected $supportsDiscoverInstall = false;
 38 
 39      40  41  42  43  44  45  46 
 47     protected function copyBaseFiles()
 48     {
 49         
 50         $this->populateFilesAndFolderList();
 51 
 52         
 53         foreach ($this->folderList as $folder)
 54         {
 55             if (!JFolder::exists($folder))
 56             {
 57                 if (!$created = JFolder::create($folder))
 58                 {
 59                     throw new RuntimeException(
 60                         JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $folder)
 61                     );
 62                 }
 63 
 64                 
 65                 
 66                 if ($created)
 67                 {
 68                     $this->parent->pushStep(array('type' => 'folder', 'path' => $folder));
 69                 }
 70             }
 71         }
 72 
 73         
 74         $this->parent->copyFiles($this->fileList);
 75     }
 76 
 77      78  79  80  81  82  83  84 
 85     protected function finaliseInstall()
 86     {
 87         
 88         $update = JTable::getInstance('update');
 89 
 90         $uid = $update->find(
 91             array(
 92                 'element' => $this->element,
 93                 'type' => $this->type,
 94             )
 95         );
 96 
 97         if ($uid)
 98         {
 99             $update->delete($uid);
100         }
101 
102         
103         $manifest = array();
104         $manifest['src'] = $this->parent->getPath('manifest');
105         $manifest['dest'] = JPATH_MANIFESTS . '/files/' . basename($this->parent->getPath('manifest'));
106 
107         if (!$this->parent->copyFiles(array($manifest), true))
108         {
109             
110             throw new RuntimeException(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP'));
111         }
112 
113         
114         if ($this->manifest_script)
115         {
116             
117             if (!file_exists($this->parent->getPath('extension_root')))
118             {
119                 JFolder::create($this->parent->getPath('extension_root'));
120             }
121 
122             $path['src'] = $this->parent->getPath('source') . '/' . $this->manifest_script;
123             $path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->manifest_script;
124 
125             if ($this->parent->isOverwrite() || !file_exists($path['dest']))
126             {
127                 if (!$this->parent->copyFiles(array($path)))
128                 {
129                     
130                     throw new RuntimeException(
131                         JText::sprintf(
132                             'JLIB_INSTALLER_ABORT_MANIFEST',
133                             JText::_('JLIB_INSTALLER_' . strtoupper($this->route))
134                         )
135                     );
136                 }
137             }
138         }
139     }
140 
141     142 143 144 145 146 147 148 149 
150     public function getElement($element = null)
151     {
152         if (!$element)
153         {
154             $manifestPath = JPath::clean($this->parent->getPath('manifest'));
155             $element = preg_replace('/\.xml/', '', basename($manifestPath));
156         }
157 
158         return $element;
159     }
160 
161     162 163 164 165 166 167 168 169 
170     public function loadLanguage($path)
171     {
172         $extension = 'files_' . strtolower(str_replace('files_', '', $this->getElement()));
173 
174         $this->doLoadLanguage($extension, $path, JPATH_SITE);
175     }
176 
177     178 179 180 181 182 183 
184     protected function parseOptionalTags()
185     {
186         
187         $this->parent->parseLanguages($this->getManifest()->languages);
188     }
189 
190     191 192 193 194 195 196 
197     protected function setupInstallPaths()
198     {
199         
200         if ($this->name === 'files_joomla')
201         {
202             
203             $this->parent->setPath('extension_root', JPATH_ROOT);
204         }
205         else
206         {
207             $this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $this->element);
208         }
209     }
210 
211     212 213 214 215 216 217 218 
219     protected function storeExtension()
220     {
221         if ($this->currentExtensionId)
222         {
223             
224             $this->extension->load($this->currentExtensionId);
225 
226             
227             $this->extension->name = $this->name;
228 
229             
230             $this->extension->manifest_cache = $this->parent->generateManifestCache();
231 
232             if (!$this->extension->store())
233             {
234                 
235                 throw new RuntimeException(
236                     JText::sprintf(
237                         'JLIB_INSTALLER_ABORT_ROLLBACK',
238                         JText::_('JLIB_INSTALLER_' . strtoupper($this->route)),
239                         $this->extension->getError()
240                     )
241                 );
242             }
243         }
244         else
245         {
246             
247             $this->extension->name = $this->name;
248             $this->extension->type = 'file';
249             $this->extension->element = $this->element;
250 
251             
252             $this->extension->folder = '';
253             $this->extension->enabled = 1;
254             $this->extension->protected = 0;
255             $this->extension->access = 0;
256             $this->extension->client_id = 0;
257             $this->extension->params = '';
258             $this->extension->system_data = '';
259             $this->extension->manifest_cache = $this->parent->generateManifestCache();
260             $this->extension->custom_data = '';
261 
262             if (!$this->extension->store())
263             {
264                 
265                 throw new RuntimeException(
266                     JText::sprintf(
267                         'JLIB_INSTALLER_ABORT_ROLLBACK',
268                         JText::_('JLIB_INSTALLER_' . strtoupper($this->route)),
269                         $this->extension->getError()
270                     )
271                 );
272             }
273 
274             
275             
276             $this->parent->pushStep(array('type' => 'extension', 'extension_id' => $this->extension->extension_id));
277         }
278     }
279 
280     281 282 283 284 285 286 287 288 
289     public function uninstall($id)
290     {
291         $row = JTable::getInstance('extension');
292 
293         if (!$row->load($id))
294         {
295             JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY'), JLog::WARNING, 'jerror');
296 
297             return false;
298         }
299 
300         if ($row->protected)
301         {
302             JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_WARNCOREFILE'), JLog::WARNING, 'jerror');
303 
304             return false;
305         }
306 
307         308 309 310 
311         if ($row->package_id && !$this->parent->isPackageUninstall() && !$this->canUninstallPackageChild($row->package_id))
312         {
313             JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_CANNOT_UNINSTALL_CHILD_OF_PACKAGE', $row->name), JLog::WARNING, 'jerror');
314 
315             return false;
316         }
317 
318         $retval = true;
319         $manifestFile = JPATH_MANIFESTS . '/files/' . $row->element . '.xml';
320 
321         
322         if (file_exists($manifestFile))
323         {
324             
325             $this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $row->element);
326 
327             $xml = simplexml_load_file($manifestFile);
328 
329             
330             if (!$xml)
331             {
332                 JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_MANIFEST'), JLog::WARNING, 'jerror');
333 
334                 return false;
335             }
336 
337             
338             if ($xml->getName() !== 'extension')
339             {
340                 JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST'), JLog::WARNING, 'jerror');
341 
342                 return false;
343             }
344 
345             $this->setManifest($xml);
346 
347             
348             $this->scriptElement = $this->getManifest()->scriptfile;
349             $manifestScript = (string) $this->getManifest()->scriptfile;
350 
351             if ($manifestScript)
352             {
353                 $manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
354 
355                 
356                 $classname = $row->element . 'InstallerScript';
357 
358                 JLoader::register($classname, $manifestScriptFile);
359 
360                 if (class_exists($classname))
361                 {
362                     
363                     $this->parent->manifestClass = new $classname($this);
364 
365                     
366                     $this->set('manifest_script', $manifestScript);
367                 }
368             }
369 
370             ob_start();
371             ob_implicit_flush(false);
372 
373             
374             if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
375             {
376                 $this->parent->manifestClass->uninstall($this);
377             }
378 
379             $msg = ob_get_contents();
380             ob_end_clean();
381 
382             if ($msg != '')
383             {
384                 $this->parent->set('extension_message', $msg);
385             }
386 
387             $db = JFactory::getDbo();
388 
389             
390             $result = $this->parent->parseSQLFiles($this->getManifest()->uninstall->sql);
391 
392             if ($result === false)
393             {
394                 
395                 JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_SQL_ERROR', $db->stderr(true)), JLog::WARNING, 'jerror');
396                 $retval = false;
397             }
398 
399             
400             $query = $db->getQuery(true)
401                 ->delete('#__schemas')
402                 ->where('extension_id = ' . $row->extension_id);
403             $db->setQuery($query);
404             $db->execute();
405 
406             
407             foreach ($xml->fileset->files as $eFiles)
408             {
409                 $target = (string) $eFiles->attributes()->target;
410 
411                 
412                 if (empty($target))
413                 {
414                     $targetFolder = JPATH_ROOT;
415                 }
416                 else
417                 {
418                     $targetFolder = JPATH_ROOT . '/' . $target;
419                 }
420 
421                 $folderList = array();
422 
423                 
424                 if (count($eFiles->children()) > 0)
425                 {
426                     
427                     foreach ($eFiles->children() as $eFileName)
428                     {
429                         if ($eFileName->getName() === 'folder')
430                         {
431                             $folderList[] = $targetFolder . '/' . $eFileName;
432                         }
433                         else
434                         {
435                             $fileName = $targetFolder . '/' . $eFileName;
436                             JFile::delete($fileName);
437                         }
438                     }
439                 }
440 
441                 
442                 foreach ($folderList as $folder)
443                 {
444                     $files = JFolder::files($folder);
445 
446                     if (!count($files))
447                     {
448                         JFolder::delete($folder);
449                     }
450                 }
451             }
452 
453             JFile::delete($manifestFile);
454 
455             
456             $folder = $this->parent->getPath('extension_root');
457 
458             if (JFolder::exists($folder))
459             {
460                 JFolder::delete($folder);
461             }
462         }
463         else
464         {
465             JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST'), JLog::WARNING, 'jerror');
466 
467             
468             $row->delete();
469 
470             return false;
471         }
472 
473         $this->parent->removeFiles($xml->languages);
474 
475         $row->delete();
476 
477         return $retval;
478     }
479 
480     481 482 483 484 485 486 487 488 
489     protected function extensionExistsInSystem($extension = null)
490     {
491         
492         $db = $this->parent->getDbo();
493 
494         $query = $db->getQuery(true)
495             ->select($db->quoteName('extension_id'))
496             ->from($db->quoteName('#__extensions'))
497             ->where($db->quoteName('type') . ' = ' . $db->quote('file'))
498             ->where($db->quoteName('element') . ' = ' . $db->quote($extension));
499         $db->setQuery($query);
500 
501         try
502         {
503             $db->execute();
504         }
505         catch (RuntimeException $e)
506         {
507             
508             $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', $db->stderr(true)));
509 
510             return false;
511         }
512         $id = $db->loadResult();
513 
514         if (empty($id))
515         {
516             return false;
517         }
518 
519         return true;
520     }
521 
522     523 524 525 526 527 528 
529     protected function populateFilesAndFolderList()
530     {
531         
532         $this->folderList = array();
533         $this->fileList = array();
534 
535         
536         $packagePath = $this->parent->getPath('source');
537         $jRootPath = JPath::clean(JPATH_ROOT);
538 
539         
540         foreach ($this->getManifest()->fileset->files as $eFiles)
541         {
542             
543             $folder = (string) $eFiles->attributes()->folder;
544             $target = (string) $eFiles->attributes()->target;
545 
546             
547             $arrList = preg_split("#/|\\/#", $target);
548 
549             $folderName = $jRootPath;
550 
551             foreach ($arrList as $dir)
552             {
553                 if (empty($dir))
554                 {
555                     continue;
556                 }
557 
558                 $folderName .= '/' . $dir;
559 
560                 
561                 if (!JFolder::exists($folderName))
562                 {
563                     $this->folderList[] = $folderName;
564                 }
565             }
566 
567             
568             $sourceFolder = empty($folder) ? $packagePath : $packagePath . '/' . $folder;
569             $targetFolder = empty($target) ? $jRootPath : $jRootPath . '/' . $target;
570 
571             
572             if (!JFolder::exists($sourceFolder))
573             {
574                 JLog::add(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $sourceFolder), JLog::WARNING, 'jerror');
575 
576                 
577                 $this->parent->abort();
578 
579                 return false;
580             }
581 
582             
583             if (count($eFiles->children()))
584             {
585                 
586                 foreach ($eFiles->children() as $eFileName)
587                 {
588                     $path['src'] = $sourceFolder . '/' . $eFileName;
589                     $path['dest'] = $targetFolder . '/' . $eFileName;
590                     $path['type'] = 'file';
591 
592                     if ($eFileName->getName() === 'folder')
593                     {
594                         $folderName         = $targetFolder . '/' . $eFileName;
595                         $this->folderList[] = $folderName;
596                         $path['type']       = 'folder';
597                     }
598 
599                     $this->fileList[] = $path;
600                 }
601             }
602             else
603             {
604                 $files = JFolder::files($sourceFolder);
605 
606                 foreach ($files as $file)
607                 {
608                     $path['src'] = $sourceFolder . '/' . $file;
609                     $path['dest'] = $targetFolder . '/' . $file;
610 
611                     $this->fileList[] = $path;
612                 }
613             }
614         }
615     }
616 
617     618 619 620 621 622 623 
624     public function refreshManifestCache()
625     {
626         
627         $manifestPath = JPATH_MANIFESTS . '/files/' . $this->parent->extension->element . '.xml';
628         $this->parent->manifest = $this->parent->isManifest($manifestPath);
629         $this->parent->setPath('manifest', $manifestPath);
630 
631         $manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
632         $this->parent->extension->manifest_cache = json_encode($manifest_details);
633         $this->parent->extension->name = $manifest_details['name'];
634 
635         try
636         {
637             return $this->parent->extension->store();
638         }
639         catch (RuntimeException $e)
640         {
641             JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
642 
643             return false;
644         }
645     }
646 }
647 
648 649 650 651 652 653 654 
655 class JInstallerFile extends JInstallerAdapterFile
656 {
657 }
658