/** * returns complex array containing all mod actions */ function get_actions() { global $db, $user; $actions = array(); $xml_actions = $this->data[0]['children']['ACTION-GROUP'][0]['children']; // sql $actions['SQL'] = array(); $sql_info = !empty($xml_actions['SQL']) ? $xml_actions['SQL'] : array(); $match_dbms = array(); switch ($db->sql_layer) { case 'firebird': case 'oracle': case 'postgres': case 'sqlite': case 'mssql': case 'db2': $match_dbms = array($db->sql_layer); break; case 'mssql_odbc': $match_dbms = array('mssql'); break; // and now for the MySQL fun // This will generate an array of things we can probably use, but // will not have any priority // and now for the MySQL fun // This will generate an array of things we can probably use, but // will not have any priority case 'mysqli': $match_dbms = array('mysql_41', 'mysqli', 'mysql'); break; case 'mysql4': case 'mysql': if (version_compare($db->sql_server_info(true), '4.1.3', '>=')) { $match_dbms = array('mysql_41', 'mysql4', 'mysql', 'mysqli'); } else { if (version_compare($db->sql_server_info(true), '4.0.0', '>=')) { $match_dbms = array('mysql_40', 'mysql4', 'mysql', 'mysqli'); } else { $match_dbms = array('mysql'); } } break; // Should never happen // Should never happen default: break; } for ($i = 0; $i < sizeof($sql_info); $i++) { if ($this->modx_version == 1.0) { $actions['SQL'][] = !empty($sql_info[$i]['data']) ? trim($sql_info[$i]['data']) : ''; } else { if ($this->modx_version == 1.2) { // Make a slightly shorter name. $xml_dbms =& $sql_info[$i]['attrs']['DBMS']; if (!isset($sql_info[$i]['attrs']['DBMS']) || in_array($xml_dbms, $match_dbms)) { $actions['SQL'][] = !empty($sql_info[$i]['data']) ? trim($sql_info[$i]['data']) : ''; } else { // NOTE: skipped SQL is not currently useful $sql_skipped = true; } } } } // new files $new_files_info = !empty($xml_actions['COPY']) ? $xml_actions['COPY'] : array(); for ($i = 0; $i < sizeof($new_files_info); $i++) { $new_files = $new_files_info[$i]['children']['FILE']; for ($j = 0; $j < sizeof($new_files); $j++) { $from = str_replace('\\', '/', $new_files[$j]['attrs']['FROM']); $to = str_replace('\\', '/', $new_files[$j]['attrs']['TO']); $actions['NEW_FILES'][$from] = $to; } } $delete_files_info = !empty($xml_actions['DELETE']) ? $xml_actions['DELETE'] : array(); for ($i = 0; $i < sizeof($delete_files_info); $i++) { $delete_files = $delete_files_info[$i]['children']['FILE']; for ($j = 0; $j < sizeof($delete_files); $j++) { $name = str_replace('\\', '/', $delete_files[$j]['attrs']['NAME']); $actions['DELETE_FILES'][] = $name; } } // open $open_info = !empty($xml_actions['OPEN']) ? $xml_actions['OPEN'] : array(); for ($i = 0; $i < sizeof($open_info); $i++) { $current_file = str_replace('\\', '/', trim($open_info[$i]['attrs']['SRC'])); $actions['EDITS'][$current_file] = array(); $edit_info = !empty($open_info[$i]['children']['EDIT']) ? $open_info[$i]['children']['EDIT'] : array(); // find, after add, before add, replace with for ($j = 0; $j < sizeof($edit_info); $j++) { $action_info = !empty($edit_info[$j]['children']) ? $edit_info[$j]['children'] : array(); // store some array information to help decide what kind of operation we're doing $action_count = $total_action_count = $remove_count = $find_count = 0; if (isset($action_info['ACTION'])) { $action_count += sizeof($action_info['ACTION']); } if (isset($action_info['INLINE-EDIT'])) { $total_action_count += sizeof($action_info['INLINE-EDIT']); } if (isset($action_info['REMOVE'])) { $remove_count = sizeof($action_info['REMOVE']); // should be an integer bounded between zero and one } if (isset($action_info['FIND'])) { $find_count = sizeof($action_info['FIND']); } // the basic idea is to transform a "remove" tag into a replace-with action if ($remove_count && !$find_count) { // but we still support it if $remove_count is > 1 for ($k = 0; $k < $remove_count; $k++) { // if there is no find tag associated, handle it directly $actions['EDITS'][$current_file][$j][trim($action_info['REMOVE'][$k]['data'], "\n\r")]['replace with'] = ''; } } else { if ($remove_count && $find_count) { // if there is a find and a remove, transform into a replace-with // action, and let the logic below sort out the relationships. for ($k = 0; $k < $remove_count; $k++) { $insert_index = isset($action_info['ACTION']) ? sizeof($action_info['ACTION']) : 0; $action_info['ACTION'][$insert_index] = array('data' => '', 'attrs' => array('TYPE' => 'replace with')); } } else { if (!$find_count) { trigger_error(sprintf($user->lang['INVALID_MOD_NO_FIND'], htmlspecialchars($action_info['ACTION'][0]['data'])), E_USER_WARNING); } } } // first we try all the possibilities for a FIND/ACTION combo, then look at inline possibilities. if (isset($action_info['ACTION'])) { for ($k = 0; $k < $find_count; $k++) { // is this anything but the last iteration of the loop? if ($k < $find_count - 1) { // NULL has special meaning for an action ... no action to be taken; advance pointer $actions['EDITS'][$current_file][$j][$action_info['FIND'][$k]['data']] = NULL; } else { // this is the last iteration, assign the action tags for ($l = 0; $l < $action_count; $l++) { $type = str_replace('-', ' ', $action_info['ACTION'][$l]['attrs']['TYPE']); $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'], "\n\r")][$type] = isset($action_info['ACTION'][$l]['data']) ? preg_replace("#^(\\s)+\n#", '', rtrim(trim($action_info['ACTION'][$l]['data'], "\n"))) : ''; } } } } else { if (!$remove_count && !$total_action_count) { trigger_error(sprintf($user->lang['INVALID_MOD_NO_ACTION'], htmlspecialchars($action_info['FIND'][0]['data'])), E_USER_WARNING); } } // add comment to the actions array $actions['EDITS'][$current_file][$j]['comment'] = localise_tags($action_info, 'COMMENT'); // inline if (isset($action_info['INLINE-EDIT'])) { $inline_info = !empty($action_info['INLINE-EDIT']) ? $action_info['INLINE-EDIT'] : array(); if (isset($inline_info[0]['children']['INLINE-REMOVE']) && sizeof($inline_info[0]['children']['INLINE-REMOVE'])) { // overwrite the existing array with the new one $inline_info[0]['children'] = array('INLINE-FIND' => $inline_info[0]['children']['INLINE-REMOVE'], 'INLINE-ACTION' => array(0 => array('attrs' => array('TYPE' => 'replace-with'), 'data' => ''))); } if ($find_count > $total_action_count) { // Yeah, $k is used more than once for different information for ($k = 0; $k < $find_count; $k++) { // is this anything but the last iteration of the loop? if ($k < $find_count - 1) { // NULL has special meaning for an action ... no action to be taken; advance pointer $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'], "\r\n")] = NULL; } } } /* * This loop attaches the in-line information to the _last * find_ in the <edit> tag. This is the intended behavior * Any additional finds ought to be in a different edit tag */ for ($k = 0; $k < sizeof($inline_info); $k++) { $inline_data = !empty($inline_info[$k]['children']) ? $inline_info[$k]['children'] : array(); $inline_find_count = isset($inline_data['INLINE-FIND']) ? sizeof($inline_data['INLINE-FIND']) : 0; $inline_comment = localise_tags($inline_data, 'INLINE-COMMENT'); $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit']['inline-comment'] = $inline_comment; $inline_actions = !empty($inline_data['INLINE-ACTION']) ? $inline_data['INLINE-ACTION'] : array(); if (empty($inline_actions)) { trigger_error(sprintf($user->lang['INVALID_MOD_NO_ACTION'], htmlspecialchars($inline_data['INLINE-FIND'][0]['data'])), E_USER_WARNING); } if (empty($inline_find_count)) { trigger_error(sprintf($user->lang['INVALID_MOD_NO_FIND'], htmlspecialchars($inline_actions[0]['data'])), E_USER_WARNING); } for ($l = 0; $l < $inline_find_count; $l++) { $inline_find = $inline_data['INLINE-FIND'][$l]['data']; // trying to reduce the levels of arrays without impairing features. // need to keep the "full" edit intact. // // inline actions must be trimmed in case the MOD author // inserts a new line by mistake if ($l < $inline_find_count - 1) { $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-'][] = null; } else { for ($m = 0; $m < sizeof($inline_actions); $m++) { $type = str_replace(',', '-', str_replace(' ', '', $inline_actions[$m]['attrs']['TYPE'])); if (!empty($inline_actions[$m]['data'])) { $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-' . $type][] = trim($inline_actions[$m]['data'], "\n"); } else { $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-' . $type][] = ''; } } } } } } } } if (!empty($xml_actions['PHP-INSTALLER'])) { $actions['PHP_INSTALLER'] = $xml_actions['PHP-INSTALLER'][0]['data']; } if (!empty($xml_actions['DIY-INSTRUCTIONS'])) { $actions['DIY_INSTRUCTIONS'] = localise_tags($xml_actions, 'DIY-INSTRUCTIONS'); } return $actions; }
/** * returns complex array containing all mod actions */ function get_actions() { global $db, $user; $actions = array(); $xml_actions = $this->data[0]['children']['ACTION-GROUP'][0]['children']; // sql $actions['SQL'] = array(); $sql_info = !empty($xml_actions['SQL']) ? $xml_actions['SQL'] : array(); $match_dbms = array(); switch ($db->sql_layer) { case 'firebird': case 'oracle': case 'postgres': case 'sqlite': case 'mssql': case 'db2': $match_dbms = array($db->sql_layer); break; case 'mssql_odbc': $match_dbms = array('mssql'); break; // and now for the MySQL fun // This will generate an array of things we can probably use, but // will not have any priority // and now for the MySQL fun // This will generate an array of things we can probably use, but // will not have any priority case 'mysqli': $match_dbms = array('mysql_41', 'mysqli', 'mysql'); break; case 'mysql4': case 'mysql': if (version_compare($db->sql_server_info(true), '4.1.3', '>=')) { $match_dbms = array('mysql_41', 'mysql4', 'mysql', 'mysqli'); } else { if (version_compare($db->sql_server_info(true), '4.0.0', '>=')) { $match_dbms = array('mysql_40', 'mysql4', 'mysql', 'mysqli'); } else { $match_dbms = array('mysql'); } } break; // Should never happen // Should never happen default: break; } for ($i = 0; $i < sizeof($sql_info); $i++) { if ($this->modx_version == 1.0) { $actions['SQL'][] = !empty($sql_info[$i]['data']) ? trim($sql_info[$i]['data']) : ''; } else { if ($this->modx_version == 1.2) { // Make a slightly shorter name. $xml_dbms =& $sql_info[$i]['attrs']['DBMS']; if (!isset($sql_info[$i]['attrs']['DBMS']) || in_array($xml_dbms, $match_dbms)) { $actions['SQL'][] = !empty($sql_info[$i]['data']) ? trim($sql_info[$i]['data']) : ''; } else { // NOTE: skipped SQL is not currently useful $sql_skipped = true; } } } } // new files $new_files_info = !empty($xml_actions['COPY']) ? $xml_actions['COPY'] : array(); for ($i = 0; $i < sizeof($new_files_info); $i++) { $new_files = $new_files_info[$i]['children']['FILE']; for ($j = 0; $j < sizeof($new_files); $j++) { $from = str_replace('\\', '/', $new_files[$j]['attrs']['FROM']); $to = str_replace('\\', '/', $new_files[$j]['attrs']['TO']); $actions['NEW_FILES'][$from] = $to; } } // open $open_info = !empty($xml_actions['OPEN']) ? $xml_actions['OPEN'] : array(); for ($i = 0; $i < sizeof($open_info); $i++) { $current_file = str_replace('\\', '/', trim($open_info[$i]['attrs']['SRC'])); $actions['EDITS'][$current_file] = array(); $edit_info = !empty($open_info[$i]['children']['EDIT']) ? $open_info[$i]['children']['EDIT'] : array(); // find, after add, before add, replace with for ($j = 0; $j < sizeof($edit_info); $j++) { $action_info = !empty($edit_info[$j]['children']) ? $edit_info[$j]['children'] : array(); // store some array information to help decide what kind of operation we're doing $action_count = $total_action_count = 0; if (isset($action_info['ACTION'])) { $action_count += sizeof($action_info['ACTION']); } if (isset($action_info['INLINE-EDIT'])) { $total_action_count += sizeof($action_info['INLINE-EDIT']); } $find_count = sizeof($action_info['FIND']); // first we try all the possibilities for a FIND/ACTION combo, then look at inline possibilities. if (isset($action_info['ACTION'])) { for ($k = 0; $k < $find_count; $k++) { // is this anything but the last iteration of the loop? if ($k < $find_count - 1) { // NULL has special meaning for an action ... no action to be taken; advance pointer $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'])] = NULL; } else { // this is the last iteration, assign the action tags for ($l = 0; $l < $action_count; $l++) { $type = str_replace('-', ' ', $action_info['ACTION'][$l]['attrs']['TYPE']); $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'])][$type] = isset($action_info['ACTION'][$l]['data']) ? preg_replace("#^(\\s)+\n#", '', rtrim(trim($action_info['ACTION'][$l]['data'], "\n"))) : ''; } } } } // add comment to the actions array $actions['EDITS'][$current_file][$j]['comment'] = localise_tags($action_info, 'COMMENT'); // inline if (isset($action_info['INLINE-EDIT'])) { $inline_info = !empty($action_info['INLINE-EDIT']) ? $action_info['INLINE-EDIT'] : array(); if ($find_count > $total_action_count) { // Yeah, $k is used more than once for different information for ($k = 0; $k < $find_count; $k++) { // is this anything but the last iteration of the loop? if ($k < $find_count - 1) { // NULL has special meaning for an action ... no action to be taken; advance pointer $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'])] = NULL; } } } /* * This loop attaches the in-line information to the _last * find_ in the <edit> tag. This is the intended behavior * Any additional finds ought to be in a different edit tag */ for ($k = 0; $k < sizeof($inline_info); $k++) { $inline_actions = !empty($inline_info[$k]['children']) ? $inline_info[$k]['children'] : array(); $inline_find = $inline_actions['INLINE-FIND'][0]['data']; $inline_comment = localise_tags($inline_actions, 'INLINE-COMMENT'); $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'])]['in-line-edit']['inline-comment'] = $inline_comment; $inline_actions = !empty($inline_actions['INLINE-ACTION']) ? $inline_actions['INLINE-ACTION'] : array(); for ($l = 0; $l < sizeof($inline_actions); $l++) { $type = str_replace(',', '-', str_replace(' ', '', $inline_actions[$l]['attrs']['TYPE'])); // trying to reduce the levels of arrays without impairing features. // need to keep the "full" edit intact. // // inline actions must be trimmed in case the MOD author // inserts a new line by mistake $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'])]['in-line-edit'][trim($inline_find)]['in-line-' . $type][] = trim($inline_actions[$l]['data'], "\n"); } } } } } if (!empty($xml_actions['DIY-INSTRUCTIONS'])) { $actions['DIY_INSTRUCTIONS'] = localise_tags($xml_actions, 'DIY-INSTRUCTIONS'); } return $actions; }