コード例 #1
0
/**
* Return the number of files (optionally including sub-directories) in a directory, optionally recursively.
*
* @param	$dir		string (required)	- The directory you want to count files in
* @param	$subdirs	boolean (optional)	- Count subdirectories instead of files
* @param	$recurse	boolean (optional)	- Recursive count into sub-directories
* @param	$count		int (optional)		- Initial value of file (or subdirs) count
* @return				int					- Count of files (or count of subdirectories)
* @author	jasmineaura
*/
function directory_num_files($dir, $subdirs = false, $recurse = false, $count = 0)
{
    if (is_dir($dir)) {
        if ($handle = opendir($dir)) {
            while (($file = readdir($handle)) !== false) {
                if ($file == '.' || $file == '..') {
                    continue;
                } else {
                    if (is_dir($dir . "/" . $file)) {
                        if ($subdirs) {
                            $count++;
                        } else {
                            if ($recurse) {
                                $count = directory_num_files($dir . "/" . $file, $subdirs, $recurse, $count);
                            }
                        }
                    } else {
                        if (!$subdirs) {
                            $count++;
                        }
                    }
                }
            }
            closedir($handle);
        }
    }
    return $count;
}
コード例 #2
0
 function process_edits($editor, $actions, $details, $change = false, $display = true, $reverse = false)
 {
     global $template, $user, $db, $phpbb_root_path, $force_install, $mod_installed;
     global $dest_inherits, $dest_template, $children, $config;
     $mod_installed = true;
     if ($reverse) {
         global $rev_actions;
         if (empty($rev_actions)) {
             // maybe should allow for potential extensions here
             $actions = parser::reverse_edits($actions);
         } else {
             $actions = $rev_actions;
             unset($rev_actions);
         }
     }
     $template->assign_vars(array('S_DISPLAY_DETAILS' => (bool) $display, 'S_CHANGE_FILES' => (bool) $change));
     if (!empty($details['PHPBB_VERSION']) && $details['PHPBB_VERSION'] != $config['version']) {
         $version_warnig = sprintf($user->lang['VERSION_WARNING'], $details['PHPBB_VERSION'], $config['version']);
         $template->assign_vars(array('VERSION_WARNING' => $version_warnig, 'S_PHPBB_VESION' => true));
     }
     if (!empty($details['AUTHOR_NOTES']) && $details['AUTHOR_NOTES'] != $user->lang['UNKNOWN_MOD_AUTHOR-NOTES']) {
         $template->assign_vars(array('S_AUTHOR_NOTES' => true, 'AUTHOR_NOTES' => nl2br($details['AUTHOR_NOTES'])));
     }
     // not all MODs will have edits (!)
     if (isset($actions['EDITS'])) {
         $template->assign_var('S_EDITS', true);
         foreach ($actions['EDITS'] as $filename => $edits) {
             // see if the file to be opened actually exists
             if (!file_exists("{$phpbb_root_path}{$filename}")) {
                 $is_inherit = strpos($filename, 'styles/') !== false && !empty($dest_inherits) ? true : false;
                 $template->assign_block_vars('edit_files', array('S_MISSING_FILE' => $is_inherit ? false : true, 'INHERIT_MSG' => $is_inherit ? sprintf($user->lang['INHERIT_NO_CHANGE'], $dest_template, $dest_inherits) : '', 'FILENAME' => $filename));
                 $mod_installed = $is_inherit ? $mod_installed : false;
                 continue;
             } else {
                 $template->assign_block_vars('edit_files', array('S_SUCCESS' => false, 'FILENAME' => $filename));
                 // If installing - not pre_install nor (pre_)uninstall, backup the file
                 // This is to make sure it works with editor_ftp because write_method is
                 // forced to direct when in preview modes, and ignored in editor_manual!
                 if ($change && !$reverse) {
                     $status = $editor->open_file($filename, $this->backup_root);
                 } else {
                     $status = $editor->open_file($filename);
                 }
                 if (is_string($status)) {
                     $template->assign_block_vars('error', array('ERROR' => $status));
                     $mod_installed = false;
                     continue;
                 }
                 $edit_success = true;
                 foreach ($edits as $finds) {
                     $comment = '';
                     foreach ($finds as $find => $commands) {
                         if (isset($finds['comment']) && !$comment && $finds['comment'] != $user->lang['UNKNOWN_MOD_COMMENT']) {
                             $comment = $finds['comment'];
                             unset($finds['comment']);
                         }
                         if ($find == 'comment') {
                             continue;
                         }
                         $find_tpl = array('FIND_STRING' => htmlspecialchars($find), 'COMMENT' => htmlspecialchars($comment));
                         $offset_ary = $editor->find($find);
                         // special case for FINDs with no action associated
                         if (is_null($commands)) {
                             continue;
                         }
                         foreach ($commands as $type => $contents) {
                             if (!$offset_ary) {
                                 $offset_ary['start'] = $offset_ary['end'] = false;
                             }
                             $status = false;
                             $inline_template_ary = array();
                             $contents_orig = $contents;
                             switch (strtoupper($type)) {
                                 case 'AFTER ADD':
                                     $status = $editor->add_string($find, $contents, 'AFTER', $offset_ary['start'], $offset_ary['end']);
                                     break;
                                 case 'BEFORE ADD':
                                     $status = $editor->add_string($find, $contents, 'BEFORE', $offset_ary['start'], $offset_ary['end']);
                                     break;
                                 case 'INCREMENT':
                                 case 'OPERATION':
                                     //$contents = "";
                                     $status = $editor->inc_string($find, '', $contents);
                                     break;
                                 case 'REPLACE WITH':
                                     $status = $editor->replace_string($find, $contents, $offset_ary['start'], $offset_ary['end']);
                                     break;
                                 case 'IN-LINE-EDIT':
                                     // these aren't quite as straight forward.  Still have multi-level arrays to sort through
                                     $inline_comment = '';
                                     foreach ($contents as $inline_edit_id => $inline_edit) {
                                         if ($inline_edit_id === 'inline-comment') {
                                             // This is a special case for tucking comments in the array
                                             if ($inline_edit != $user->lang['UNKNOWN_MOD_INLINE-COMMENT']) {
                                                 $inline_comment = $inline_edit;
                                             }
                                             continue;
                                         }
                                         foreach ($inline_edit as $inline_find => $inline_commands) {
                                             foreach ($inline_commands as $inline_action => $inline_contents) {
                                                 // inline finds are pretty cantankerous, so do them in the loop
                                                 $line = $editor->inline_find($find, $inline_find, $offset_ary['start'], $offset_ary['end']);
                                                 if (!$line) {
                                                     // find failed
                                                     $status = $mod_installed = false;
                                                     $inline_template_ary[] = array('FIND' => array('S_SUCCESS' => $status, 'NAME' => $user->lang[$type], 'COMMAND' => htmlspecialchars($inline_find)), 'ACTION' => array());
                                                     continue 2;
                                                 }
                                                 $inline_contents = $inline_contents[0];
                                                 $contents_orig = $inline_find;
                                                 switch (strtoupper($inline_action)) {
                                                     case 'IN-LINE-':
                                                         $editor->last_string_offset = $line['string_offset'] + $line['find_length'] - 1;
                                                         $status = true;
                                                         continue 2;
                                                         break;
                                                     case 'IN-LINE-BEFORE-ADD':
                                                         $status = $editor->inline_add($find, $inline_find, $inline_contents, 'BEFORE', $line['array_offset'], $line['string_offset'], $line['find_length']);
                                                         break;
                                                     case 'IN-LINE-AFTER-ADD':
                                                         $status = $editor->inline_add($find, $inline_find, $inline_contents, 'AFTER', $line['array_offset'], $line['string_offset'], $line['find_length']);
                                                         break;
                                                     case 'IN-LINE-REPLACE':
                                                     case 'IN-LINE-REPLACE-WITH':
                                                         $status = $editor->inline_replace($find, $inline_find, $inline_contents, $line['array_offset'], $line['string_offset'], $line['find_length']);
                                                         break;
                                                     case 'IN-LINE-OPERATION':
                                                         $status = $editor->inc_string($find, $inline_find, $inline_contents);
                                                         break;
                                                     default:
                                                         $message = sprintf($user->lang['UNRECOGNISED_COMMAND'], $inline_action);
                                                         trigger_error($message, E_USER_WARNING);
                                                         // ERROR!
                                                         break;
                                                 }
                                                 $inline_template_ary[] = array('FIND' => array('S_SUCCESS' => $status, 'NAME' => $user->lang[$type], 'COMMAND' => is_array($contents_orig) ? $user->lang['INVALID_MOD_INSTRUCTION'] : htmlspecialchars($contents_orig)), 'ACTION' => array('S_SUCCESS' => $status, 'NAME' => $user->lang[$inline_action], 'COMMAND' => is_array($inline_contents) ? $user->lang['INVALID_MOD_INSTRUCTION'] : htmlspecialchars($inline_contents)));
                                             }
                                             if (!$status) {
                                                 $mod_installed = false;
                                             }
                                             $editor->close_inline_edit();
                                         }
                                     }
                                     break;
                                 default:
                                     $message = sprintf($user->lang['UNRECOGNISED_COMMAND'], $type);
                                     trigger_error($message, E_USER_WARNING);
                                     // ERROR!
                                     break;
                             }
                             $template->assign_block_vars('edit_files.finds', array_merge($find_tpl, array('S_SUCCESS' => $status)));
                             if (!$status) {
                                 $edit_success = false;
                                 $mod_installed = false;
                             }
                             if (sizeof($inline_template_ary)) {
                                 foreach ($inline_template_ary as $inline_template) {
                                     // We must assign the vars for the FIND first
                                     $template->assign_block_vars('edit_files.finds.actions', $inline_template['FIND']);
                                     // And now the vars for the ACTION
                                     $template->assign_block_vars('edit_files.finds.actions.inline', $inline_template['ACTION']);
                                 }
                                 $inline_template_ary = array();
                             } else {
                                 if (!is_array($contents_orig)) {
                                     $template->assign_block_vars('edit_files.finds.actions', array('S_SUCCESS' => $status, 'NAME' => $user->lang[$type], 'COMMAND' => htmlspecialchars($contents_orig)));
                                 }
                             }
                         }
                     }
                     $editor->close_edit();
                 }
                 $template->alter_block_array('edit_files', array('S_SUCCESS' => $edit_success), true, 'change');
             }
             if ($change) {
                 $status = $editor->close_file("{$this->edited_root}{$filename}");
                 if (is_string($status)) {
                     $template->assign_block_vars('error', array('ERROR' => $status));
                     $mod_installed = false;
                 }
             }
         }
     }
     // end foreach
     // Move included files
     if (isset($actions['NEW_FILES']) && !empty($actions['NEW_FILES'])) {
         $template->assign_var('S_NEW_FILES', true);
         // Because foreach operates on a copy of the specified array and not the array itself,
         // we cannot rely on the array pointer while using it, so we use a while loop w/ each()
         // We need array pointer to rewind the loop when is_array($target) (See Ticket #62341)
         while (list($source, $target) = each($actions['NEW_FILES'])) {
             if (is_array($target)) {
                 // If we've shifted off all targets, we're done w/ that element
                 if (empty($target)) {
                     continue;
                 }
                 // Shift off first target, then rewind array pointer to get next target
                 $target = array_shift($actions['NEW_FILES'][$source]);
                 prev($actions['NEW_FILES']);
             }
             if ($change && ($mod_installed || $force_install)) {
                 $status = $editor->copy_content($this->mod_root . str_replace('*.*', '', $source), str_replace('*.*', '', $target));
                 if ($status !== true && !is_null($status)) {
                     $mod_installed = false;
                 }
                 $template->assign_block_vars('new_files', array('S_SUCCESS' => $status === true ? true : false, 'S_NO_COPY_ATTEMPT' => is_null($status) ? true : false, 'SOURCE' => $source, 'TARGET' => $target));
             } else {
                 if ($display && !$change) {
                     $template->assign_block_vars('new_files', array('SOURCE' => $source, 'TARGET' => $target));
                 } else {
                     if ($change && $display && !$mod_installed && !$force_install) {
                         $template->assign_block_vars('new_files', array('S_NO_COPY_ATTEMPT' => true, 'FILENAME' => $target));
                     }
                 }
             }
         }
     }
     // Delete (or reverse-delete) installed files
     if (!empty($actions['DELETE_FILES'])) {
         $template->assign_var('S_REMOVING_FILES', true);
         // Dealing with a reverse-delete, must heed to the dangers ahead!
         if ($reverse) {
             $directories = array();
             $directories['src'] = array();
             $directories['dst'] = array();
             $directories['del'] = array();
             // Because foreach operates on a copy of the specified array and not the array itself,
             // we cannot rely on the array pointer while using it, so we use a while loop w/ each()
             // We need array pointer to rewind the loop when is_array($target) (See Ticket #62341)
             while (list($source, $target) = each($actions['DELETE_FILES'])) {
                 if (is_array($target)) {
                     // If we've shifted off all targets, we're done w/ that element
                     if (empty($target)) {
                         continue;
                     }
                     // Shift off first target, then rewind array pointer to get next target
                     $target = array_shift($actions['DELETE_FILES'][$source]);
                     prev($actions['DELETE_FILES']);
                 }
                 // Some MODs include 'umil/', avoid deleting!
                 if (strpos($target, 'umil/') === 0) {
                     unset($actions['DELETE_FILES'][$source]);
                     continue;
                 } else {
                     if (strpos($source, '*.*') !== false) {
                         // This could be phpbb_root_path, if "Copy: root/*.* to: *.*" syntax was used
                         // or root/custom_dir if "Copy: root/custom/*.* to: custom/*.*", etc.
                         $source = $this->mod_root . str_replace('*.*', '', $source);
                         $target = str_replace('*.*', '', $target);
                         // Get all of the files in the source directory
                         $files = find_files($source, '.*');
                         // And translate into destination files
                         $files = str_replace($source, $target, $files);
                         // Get all of the sub-directories in the source directory
                         $directories['src'] = find_files($source, '.*', 20, true);
                         // And translate it into destination sub-directories
                         $directories['dst'] = str_replace($source, $target, $directories['src']);
                         // Compare source and destination subdirs, if any, in _reverse_ order! (array_pop)
                         for ($i = 0, $cnt = count($directories['dst']); $i < $cnt; $i++) {
                             $dir_source = array_pop($directories['src']);
                             $dir_target = array_pop($directories['dst']);
                             // Some MODs include 'umil/', avoid deleting!
                             if (strpos($dir_target, 'umil/') === 0) {
                                 continue;
                             }
                             $src_file_cnt = directory_num_files($dir_source, false, true);
                             $dst_file_cnt = directory_num_files($phpbb_root_path . $dir_target, false, true);
                             $src_dir_cnt = directory_num_files($dir_source, true, true);
                             $dst_dir_cnt = directory_num_files($phpbb_root_path . $dir_target, true, true);
                             // Do we have a match in recursive file count and match in recursive subdir count?
                             // This could be vastly improved..
                             if ($src_file_cnt == $dst_file_cnt && $src_dir_cnt == $dst_dir_cnt) {
                                 $directories['del'][] = $dir_target;
                             }
                             unset($dir_source, $dir_target, $src_file_cnt, $dst_file_cnt, $src_dir_cnt, $dst_dir_cnt);
                             //cleanup
                         }
                         foreach ($files as $file) {
                             // Some MODs include 'umil/', avoid deleting!
                             if (strpos($file, 'umil/') === 0) {
                                 continue;
                             } else {
                                 if (!file_exists($phpbb_root_path . $file) && ($change || $display)) {
                                     $template->assign_block_vars('removing_files', array('S_MISSING_FILE' => true, 'S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $file));
                                 } else {
                                     if ($change && ($mod_installed || $force_install)) {
                                         $status = $editor->remove($file);
                                         $template->assign_block_vars('removing_files', array('S_SUCCESS' => $status === true ? true : false, 'S_NO_DELETE_ATTEMPT' => is_null($status) ? true : false, 'FILENAME' => $file));
                                     } else {
                                         if ($display && !$change) {
                                             $template->assign_block_vars('removing_files', array('FILENAME' => $file));
                                         } else {
                                             if ($change && $display && !$mod_installed && !$force_install) {
                                                 $template->assign_block_vars('removing_files', array('S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $file));
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                         unset($files);
                         //cleanup
                     } else {
                         if (!file_exists($phpbb_root_path . $target) && ($change || $display)) {
                             $template->assign_block_vars('removing_files', array('S_MISSING_FILE' => true, 'S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $target));
                         } else {
                             if ($change && ($mod_installed || $force_install)) {
                                 $status = $editor->remove($target);
                                 $template->assign_block_vars('removing_files', array('S_SUCCESS' => $status === true ? true : false, 'S_NO_DELETE_ATTEMPT' => is_null($status) ? true : false, 'FILENAME' => $target));
                             } else {
                                 if ($display && !$change) {
                                     $template->assign_block_vars('removing_files', array('FILENAME' => $target));
                                 } else {
                                     if ($change && $display && !$mod_installed && !$force_install) {
                                         $template->assign_block_vars('removing_files', array('S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $target));
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             // Delete wildcard directories, if any, which should now be empty anyway (no recursive delete needed)
             if ($cnt = count($directories['del'])) {
                 for ($i = 0; $i < $cnt; $i++) {
                     if ($change && ($mod_installed || $force_install)) {
                         $status = $editor->remove($directories['del'][$i]);
                         $template->assign_block_vars('removing_files', array('S_SUCCESS' => $status === true ? true : false, 'S_NO_DELETE_ATTEMPT' => is_null($status) ? true : false, 'FILENAME' => $directories['del'][$i]));
                     } else {
                         if ($display && !$change) {
                             $template->assign_block_vars('removing_files', array('FILENAME' => $directories['del'][$i]));
                         } else {
                             if ($change && $display && !$mod_installed && !$force_install) {
                                 $template->assign_block_vars('removing_files', array('S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $directories['del'][$i]));
                             }
                         }
                     }
                 }
                 unset($directories['del']);
                 //cleanup
             }
         } else {
             if ($mod_installed || $force_install) {
                 foreach ($actions['DELETE_FILES'] as $file) {
                     $wildcards = strpos($file, '*.*');
                     $file = str_replace('*.*', '', $file);
                     if (!file_exists($phpbb_root_path . $file) && ($change || $display)) {
                         $template->assign_block_vars('removing_files', array('S_MISSING_FILE' => true, 'S_NO_DELETE_ATTEMPT' => true, 'FILENAME' => $file));
                     } else {
                         if ($wildcards || is_file($phpbb_root_path . $file)) {
                             if ($change) {
                                 // Delete, recursively if needed
                                 $status = $editor->remove($file, true);
                                 $template->assign_block_vars('removing_files', array('S_SUCCESS' => $status === true ? true : false, 'S_NO_DELETE_ATTEMPT' => is_null($status) ? true : false, 'FILENAME' => $file));
                             } else {
                                 if ($display) {
                                     $template->assign_block_vars('removing_files', array('FILENAME' => $file));
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Perform SQL queries last -- Queries usually cannot be done a second
     // time, so do them only if the edits were successful.  Still complies
     // with the MODX spec in this location
     if (!empty($actions['SQL']) && ($mod_installed || $force_install || $display && !$change)) {
         $template->assign_var('S_SQL', true);
         parser::parse_sql($actions['SQL']);
         $db->sql_return_on_error(true);
         foreach ($actions['SQL'] as $query) {
             if ($change) {
                 $query_success = $db->sql_query($query);
                 if ($query_success) {
                     $template->assign_block_vars('sql_queries', array('S_SUCCESS' => true, 'QUERY' => $query));
                 } else {
                     $error = $db->sql_error();
                     $template->assign_block_vars('sql_queries', array('S_SUCCESS' => false, 'QUERY' => $query, 'ERROR_MSG' => $error['message'], 'ERROR_CODE' => $error['code']));
                     $mod_installed = false;
                 }
             } else {
                 if ($display) {
                     $template->assign_block_vars('sql_queries', array('QUERY' => $query));
                 }
             }
         }
         $db->sql_return_on_error(false);
     } else {
         $template->assign_var('S_SQL', false);
     }
     return $mod_installed;
 }