/** * Clean attachment package. * * @return array Returns array containing any errors encountered. */ protected function clean_package() { $error = array(); if (!$this->contrib->type->restore_root && !$this->contrib->type->clean_package) { return $error; } $root_directory = null; if ($this->contrib->type->restore_root && is_array($this->contrib->type->root_search)) { $search = $this->contrib->type->root_search; $exclude = !empty($search['exclude']) ? $search['exclude'] : null; unset($search['exclude']); $root_directory = $this->package->find_directory($search, $exclude); if ($root_directory === null) { $error[] = $this->user->lang($this->contrib->type->root_not_found_key); } } if (empty($error)) { if ($root_directory !== null) { // Adjust package name to follow naming conventions $new_root_name = $this->contrib->type->fix_package_name($this->contrib, $this->revision, $this->attachment, $root_directory); $this->package->restore_root($root_directory, $new_root_name); } // Replace the uploaded zip package with the new one $this->package->repack($this->contrib->type->clean_package); $this->update_package_stats(); } // Remove our temp files $this->package->cleanup(); return $error; }
/** * Repack extension to add version check info and match * correct directory structure to given ext name. * * @param package $package * @param \titania_contribution $contrib * @pram \titania_revision $revision * @throws \Exception if an error occurred */ protected function repack(package $package, \titania_contribution $contrib, \titania_revision $revision) { $package->ensure_extracted(); $ext_base_path = $package->find_directory(array('files' => array('required' => 'composer.json', 'optional' => 'ext.php')), 'vendor'); if ($ext_base_path === null) { throw new \Exception($this->root_not_found_key); } $composer_file = $package->get_temp_path() . '/' . $ext_base_path . '/composer.json'; $data = $this->get_composer_data($composer_file); if (!is_array($data) || empty($data['name']) || !$this->validate_ext_name($data['name'])) { throw new \Exception('INVALID_EXT_NAME'); } $ext_name = $data['name']; $data = $this->update_phpbb_requirement($data); $data = $this->set_version_check($data, $contrib); $data = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); file_put_contents($composer_file, $data); $package->restore_root($ext_base_path, $ext_name); $package->repack($this->clean_package); $revision->revision_composer_json = $data; $contrib->contrib_package_name = $ext_name; $contrib->submit(); }
/** * Generate Composer package. * * @param string $composer_package Path to package destination */ protected function generate_composer_package($composer_package) { $package = new package(); $package->set_source($this->ext_config->upload_path . $this->file['physical_filename']); $package->set_temp_path($this->ext_config->contrib_temp_path, true); $ext_base_path = $package->find_directory(array('files' => array('required' => 'composer.json', 'optional' => 'ext.php')), 'vendor'); $package->restore_root($ext_base_path, $this->id); $filesystem = new Filesystem(); $filesystem->copy($package->get_source(), $this->ext_config->upload_path . $composer_package); $package->set_source($package->get_source() . '.composer'); $package->repack(true); $package->cleanup(); }
/** * Checks the file for the array contents * Make sure it has all the keys present in the newest version * * @param \phpbb\titania\entity\package $package * @param string $reference_filepath The path to the files against I want to validate the uploaded package * @return array Returns an array of error messages encountered */ public function check_package($package, $reference_filepath) { $package->ensure_extracted(); $error = $missing_keys = array(); // Basically the individual parts of the translation, we check them separately, because they have colliding filenames $types = array('language' => 'language/', 'prosilver' => 'styles/prosilver/imageset/en', 'subsilver2' => 'styles/subsilver2/imageset/en'); // Do the check for all types foreach ($types as $type => $path) { // Get all the files present in the uploaded package for the currently iterated type $uploaded_files = $this->lang_filelist($package->get_temp_path()); $reference_files = $this->lang_filelist($reference_filepath); ksort($uploaded_files); ksort($reference_files); switch ($type) { case 'language': // The uploaded files array has keys prefixed with the upload path of the contribution // Have it stored in the variable so we can work with it $uploaded_files_prefix = explode('/', key($uploaded_files)); $iso_code = $uploaded_files_prefix[2]; $uploaded_files_prefix = $package->get_temp_path() . '/' . $uploaded_files_prefix[0]; // This goes directly to the root of the uploaded language pack, like /upload_path/language/cs/ $uploaded_lang_root = $uploaded_files_prefix . '/language/' . $iso_code . '/'; // Just perform a basic check if the common file is there if (!is_file($uploaded_lang_root . 'common.php')) { return array($this->user->lang('NO_TRANSLATION')); } // Loop through the reference files foreach ($reference_files as $dir => $files) { // Do not loop through files which are in non-language directories if (strpos($dir, $path) === 0) { // Loop through the files in the language/, language/adm etc. directories foreach ($files as $file) { $exists = true; $uploaded_file_path = str_replace('/en/', '/' . $iso_code . '/', $uploaded_files_prefix . '/' . $dir . $file); $ext = strtolower(substr($file, -3)); // Require php and txt files if ($ext == 'php' || $ext == 'txt') { if (!is_file($uploaded_file_path)) { $error[] = $this->user->lang('MISSING_FILE', str_replace('/en/', '/' . $iso_code . '/', $dir . $file)); // report a missing file $exists = false; } } // If the file is a php file and actually exists, no point in checking keys in a nonexistent one if ($ext == 'php' && $exists) { $missing_keys[$dir . $file] = $this->check_missing_keys($reference_filepath . '' . $dir . $file, $uploaded_file_path); } // In the last step we have removed the license and index files if there were any. We'll just put a new one instead $this->add_license_files($uploaded_lang_root . '/LICENSE', $reference_filepath); $this->add_htm_files($uploaded_lang_root, $reference_filepath); } } } if (sizeof($missing_keys)) { foreach ($missing_keys as $file => $keys) { if (sizeof($keys)) { $error[] = $this->user->lang('MISSING_KEYS', $file, implode('<br />', $keys)); } } } break; case 'prosilver': case 'subsilver2': // just let them go through atm... break; } } // We are going to check if all files included in the language pack are allowed // Before we need some stuff // We construct a list of all reference files with complete structure foreach ($reference_files as $dir => $files) { if (strpos($dir, $types['language']) === 0 || strpos($dir, $types['prosilver']) === 0 || strpos($dir, $types['subsilver2']) === 0) { foreach ($files as $file) { $list_reference_files[] = $dir . $file; } } } // We construct a list of all uploaded file with complete structure foreach ($uploaded_files as $dir => $files) { // We need to clean our directory path according the type and replace iso_code package by en if (strpos($dir, $types['language']) != 0) { $dir_prefix = explode($types['language'], $dir); } else { if (strpos($dir, $types['prosilver']) != 0) { $dir_prefix = explode($types['prosilver'], $dir); } else { if (strpos($dir, $types['subsilver2']) != 0) { $dir_prefix = explode($types['subsilver2'], $dir); } } } $dir_clean = str_replace('/' . $iso_code . '/', '/en/', str_replace($dir_prefix[0], '', $dir)); foreach ($files as $file) { $list_uploaded_files[] = $dir_clean . $file; } } // It's time to check if each file uploaded in the package is allowed foreach ($list_uploaded_files as $file) { if (!in_array($file, $list_reference_files) && !in_array($file, $this->ignore_files)) { $error[] = $this->user->lang('WRONG_FILE', str_replace('/en/', '/' . $iso_code . '/', $file)); // report a wrong file } } if (!sizeof($error)) { $package->repack(); // we have made changes to the package, so replace the original zip file } return $error; }