/** * @param local_amos_filter $filter * @param stdclass $user working with the translator */ public function __construct(local_amos_filter $filter, stdclass $user) { global $DB; // get the list of strings to display according the current filter values $branches = $filter->get_data()->version; $languages = array_merge(array('en'), $filter->get_data()->language); $components = $filter->get_data()->component; if (empty($branches) or empty($components) or empty($languages)) { return; } $missing = $filter->get_data()->missing; $helps = $filter->get_data()->helps; $substring = $filter->get_data()->substring; $substringregex = $filter->get_data()->substringregex; $substringcs = $filter->get_data()->substringcs; $stringid = $filter->get_data()->stringid; $stringidpartial = $filter->get_data()->stringidpartial; $stagedonly = $filter->get_data()->stagedonly; $greylistedonly = $filter->get_data()->greylistedonly; $withoutgreylisted = $filter->get_data()->withoutgreylisted; list($inner_sqlbranches, $inner_paramsbranches) = $DB->get_in_or_equal($branches, SQL_PARAMS_NAMED, 'innerbranch00000'); list($inner_sqllanguages, $inner_paramslanguages) = $DB->get_in_or_equal($languages, SQL_PARAMS_NAMED, 'innerlang00000'); list($inner_sqlcomponents, $inner_paramcomponents) = $DB->get_in_or_equal($components, SQL_PARAMS_NAMED, 'innercomp00000'); list($outer_sqlbranches, $outer_paramsbranches) = $DB->get_in_or_equal($branches, SQL_PARAMS_NAMED, 'outerbranch00000'); list($outer_sqllanguages, $outer_paramslanguages) = $DB->get_in_or_equal($languages, SQL_PARAMS_NAMED, 'outerlang00000'); list($outer_sqlcomponents, $outer_paramcomponents) = $DB->get_in_or_equal($components, SQL_PARAMS_NAMED, 'outercomp00000'); // get the greylisted strings first $sql = "SELECT branch, component, stringid\n FROM {amos_greylist}\n WHERE branch {$inner_sqlbranches}\n AND component {$inner_sqlcomponents}"; if ($stringid) { if ($stringidpartial) { $sql .= " AND " . $DB->sql_like('stringid', ':stringid', false); $params = array('stringid' => '%' . $DB->sql_like_escape($stringid) . '%'); } else { $sql .= " AND stringid = :stringid"; $params = array('stringid' => $stringid); } } else { $params = array(); } $sql .= " ORDER BY branch, component, stringid"; $params = array_merge($params, $inner_paramsbranches, $inner_paramcomponents); $greylist = array(); $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $s) { $greylist[$s->branch][$s->component][$s->stringid] = true; } $rs->close(); // get all the strings for the translator $sql = "SELECT r.id, r.branch, r.lang, r.component, r.stringid, r.text, r.timemodified, r.timeupdated, r.deleted\n FROM {amos_repository} r\n JOIN (SELECT branch, lang, component, stringid, MAX(timemodified) AS timemodified\n FROM {amos_repository}\n WHERE branch {$inner_sqlbranches}\n AND lang {$inner_sqllanguages}\n AND component {$inner_sqlcomponents}"; $sql .= " GROUP BY branch,lang,component,stringid) j\n ON (r.branch = j.branch\n AND r.lang = j.lang\n AND r.component = j.component\n AND r.stringid = j.stringid\n AND r.timemodified = j.timemodified)\n WHERE r.branch {$outer_sqlbranches}\n AND r.lang {$outer_sqllanguages}\n AND r.component {$outer_sqlcomponents}"; if ($stringid) { if ($stringidpartial) { $sql .= " AND " . $DB->sql_like('r.stringid', ':stringid', false); $params = array('stringid' => '%' . $DB->sql_like_escape($stringid) . '%'); } else { $sql .= " AND r.stringid = :stringid"; $params = array('stringid' => $stringid); } } else { $params = array(); } if ($helps) { $sql .= " AND " . $DB->sql_like('r.stringid', ':helpstringid', false); $params['helpstringid'] = '%' . $DB->sql_like_escape('_help'); } else { $sql .= " AND " . $DB->sql_like('r.stringid', ':linkstringid', false, true, true); $params['linkstringid'] = '%' . $DB->sql_like_escape('_link'); } $sql .= " ORDER BY r.component, r.stringid, r.lang, r.branch, r.id DESC"; $params = array_merge($params, $inner_paramsbranches, $inner_paramslanguages, $inner_paramcomponents, $outer_paramsbranches, $outer_paramslanguages, $outer_paramcomponents); $rs = $DB->get_recordset_sql($sql, $params); $s = array(); // tree of strings grouped by lang, component, stringid and branch $d = array(); // same tree - but containing deleted strings only foreach ($rs as $r) { // if the most recent record is a deletion record, do not add the string to $s tree // this filtering can not be done in SQL because there can be two records with // the same timemodified, one changing the string and one removing it if ($r->deleted) { $d[$r->lang][$r->component][$r->stringid][$r->branch] = true; } if (isset($d[$r->lang][$r->component][$r->stringid][$r->branch])) { // the more recent record of this string removes it continue; } if (!isset($s[$r->lang][$r->component][$r->stringid][$r->branch])) { // store the most recent record in the $s tree $string = new stdclass(); $string->amosid = $r->id; $string->text = $r->text; $string->timemodified = $r->timemodified; $string->timeupdated = $r->timeupdated; $s[$r->lang][$r->component][$r->stringid][$r->branch] = $string; } } unset($d); $rs->close(); // replace the loaded values with those already staged $stage = mlang_persistent_stage::instance_for_user($user->id, $user->sesskey); foreach ($stage->get_iterator() as $component) { foreach ($component->get_iterator() as $staged) { $string = new stdclass(); $string->amosid = null; $string->text = $staged->text; $string->timemodified = $staged->timemodified; $string->timeupdated = $staged->timemodified; $string->class = 'staged'; $s[$component->lang][$component->name][$staged->id][$component->version->code] = $string; } } $this->currentpage = $filter->get_data()->page; $from = ($this->currentpage - 1) * self::PERPAGE + 1; $to = $this->currentpage * self::PERPAGE; if (isset($s['en'])) { foreach ($s['en'] as $component => $t) { foreach ($t as $stringid => $u) { foreach ($u as $branchcode => $english) { reset($languages); foreach ($languages as $lang) { if ($lang == 'en') { continue; } $string = new stdclass(); $string->branch = mlang_version::by_code($branchcode)->label; $string->branchcode = mlang_version::by_code($branchcode)->code; $string->language = $lang; $string->component = $component; $string->stringid = $stringid; $string->metainfo = ''; // todo read metainfo from database $string->original = $english->text; $string->originalid = $english->amosid; $string->originalmodified = $english->timemodified; $string->committable = false; if (isset($s[$lang][$component][$stringid][$branchcode])) { $string->translation = $s[$lang][$component][$stringid][$branchcode]->text; $string->translationid = $s[$lang][$component][$stringid][$branchcode]->amosid; $string->timemodified = $s[$lang][$component][$stringid][$branchcode]->timemodified; $string->timeupdated = $s[$lang][$component][$stringid][$branchcode]->timeupdated; if (isset($s[$lang][$component][$stringid][$branchcode]->class)) { $string->class = $s[$lang][$component][$stringid][$branchcode]->class; } else { $string->class = 'translated'; } if ($string->originalmodified > max($string->timemodified, $string->timeupdated)) { $string->outdated = true; } else { $string->outdated = false; } } else { $string->translation = null; $string->translationid = null; $string->timemodified = null; $string->timeupdated = null; $string->class = 'missing'; $string->outdated = false; } if (isset($greylist[$branchcode][$component][$stringid])) { $string->greylisted = true; } else { $string->greylisted = false; } unset($s[$lang][$component][$stringid][$branchcode]); if ($stagedonly and $string->class != 'staged') { continue; // do not display this string } if ($greylistedonly and !$string->greylisted) { continue; // do not display this string } if ($withoutgreylisted and $string->greylisted) { continue; // do not display this string } if (!empty($substring)) { // if defined, then either English or the translation must contain the substring if (empty($substringregex)) { if (empty($substringcs)) { if (!stristr($string->original, trim($substring)) and !stristr($string->translation, trim($substring))) { continue; // do not display this strings } } else { if (!strstr($string->original, trim($substring)) and !strstr($string->translation, trim($substring))) { continue; // do not display this strings } } } else { // considered substring a regular expression if (empty($substringcs)) { if (!preg_match("/{$substring}/i", $string->original) and !preg_match("/{$substring}/i", $string->translation)) { continue; } } else { if (!preg_match("/{$substring}/", $string->original) and !preg_match("/{$substring}/", $string->translation)) { continue; } } } } if ($missing) { // missing or outdated string only if (($string->translation or $string->translation === '0' or $string->original === '') and !$string->outdated) { continue; // it is considered up-top-date - do not display it } } $this->numofrows++; if (is_null($string->translation)) { $this->numofmissing++; } // keep just strings from the current page if ($this->numofrows < $from or $this->numofrows > $to) { unset($string); continue; } $this->strings[] = $string; } } } } } $allowedlangs = mlang_tools::list_allowed_languages($user->id); foreach ($this->strings as $string) { if (!empty($allowedlangs['X']) or !empty($allowedlangs[$string->language])) { $string->committable = true; } if (empty(mlang_version::by_code($string->branchcode)->translatable)) { $string->translatable = false; } else { $string->translatable = true; } } }
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once dirname(dirname(dirname(__FILE__))) . '/config.php'; require_once dirname(__FILE__) . '/locallib.php'; require_login(SITEID, false); require_capability('local/amos:stage', get_system_context()); $PAGE->set_pagelayout('standard'); $PAGE->set_url('/local/amos/view.php'); $PAGE->set_title('AMOS ' . get_string('translatortool', 'local_amos')); $PAGE->set_heading('AMOS ' . get_string('translatortool', 'local_amos')); $PAGE->requires->strings_for_js(array('languagesall', 'languagesnone', 'componentsall', 'componentsnone', 'componentsstandard'), 'local_amos'); $PAGE->requires->js_init_call('M.local_amos.init_translator', array(), true); $PAGE->requires->yui_module('moodle-local_amos-timeline', 'M.local_amos.init_timeline'); $output = $PAGE->get_renderer('local_amos'); // create a renderable object that represents the filter form $filter = new local_amos_filter($PAGE->url); // save the filter settings into the sesssion $fdata = $filter->get_data(); foreach ($fdata as $setting => $value) { $USER->{'local_amos_' . $setting} = serialize($value); } $filter->set_permalink($PAGE->url, $fdata); // just make sure that USER contains sesskey $sesskey = sesskey(); // create a renderable object that represent the translation table $translator = new local_amos_translator($filter, $USER); /// Output starts here echo $output->header(); echo $output->render($filter); echo $output->render($translator); echo $output->box('', 'googlebranding', 'googlebranding');
/** * Renders the filter form * * @todo this code was used as sort of prototype of the HTML produced by the future forms framework, to be replaced by proper forms library * @param local_amos_filter $filter * @return string */ protected function render_local_amos_filter(local_amos_filter $filter) { $output = ''; // version checkboxes $output .= html_writer::start_tag('div', array('class' => 'item elementsgroup')); $output .= html_writer::start_tag('div', array('class' => 'label first')); $output .= html_writer::tag('label', get_string('filterver', 'local_amos'), array('for' => 'amosfilter_fver')); $output .= html_writer::tag('div', get_string('filterver_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $fver = ''; foreach (mlang_version::list_all() as $version) { if ($version->code < 1900) { continue; } $checkbox = html_writer::checkbox('fver[]', $version->code, in_array($version->code, $filter->get_data()->version), $version->label); $fver .= html_writer::tag('div', $checkbox, array('class' => 'labelled_checkbox')); } $output .= html_writer::tag('div', $fver, array('id' => 'amosfilter_fver', 'class' => 'checkboxgroup')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // language selector $output .= html_writer::start_tag('div', array('class' => 'item select')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', get_string('filterlng', 'local_amos'), array('for' => 'amosfilter_flng')); $output .= html_writer::tag('div', get_string('filterlng_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $options = mlang_tools::list_languages(); foreach ($options as $langcode => $langname) { $options[$langcode] = $langname; } unset($options['en']); // English is not translatable via AMOS $output .= html_writer::select($options, 'flng[]', $filter->get_data()->language, '', array('id' => 'amosfilter_flng', 'multiple' => 'multiple', 'size' => 3)); $output .= html_writer::tag('span', '', array('id' => 'amosfilter_flng_actions', 'class' => 'actions')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // component selector $output .= html_writer::start_tag('div', array('class' => 'item select')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', get_string('filtercmp', 'local_amos'), array('for' => 'amosfilter_fcmp')); $output .= html_writer::tag('div', get_string('filtercmp_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $optionscore = array(); $optionsstandard = array(); $optionscontrib = array(); $standard = array(); foreach (local_amos_standard_plugins() as $plugins) { $standard = array_merge($standard, $plugins); } foreach (mlang_tools::list_components() as $componentname => $undefined) { if (isset($standard[$componentname])) { if ($standard[$componentname] === 'core' or substr($standard[$componentname], 0, 5) === 'core_') { $optionscore[$componentname] = $standard[$componentname]; } else { $optionsstandard[$componentname] = $standard[$componentname]; } } else { $optionscontrib[$componentname] = $componentname; } } asort($optionscore); asort($optionsstandard); asort($optionscontrib); $options = array(array(get_string('typecore', 'local_amos') => $optionscore), array(get_string('typestandard', 'local_amos') => $optionsstandard), array(get_string('typecontrib', 'local_amos') => $optionscontrib)); $output .= html_writer::select($options, 'fcmp[]', $filter->get_data()->component, '', array('id' => 'amosfilter_fcmp', 'multiple' => 'multiple', 'size' => 5)); $output .= html_writer::tag('span', '', array('id' => 'amosfilter_fcmp_actions', 'class' => 'actions')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // other filter settings $output .= html_writer::start_tag('div', array('class' => 'item elementsgroup')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', get_string('filtermis', 'local_amos'), array('for' => 'amosfilter_fmis')); $output .= html_writer::tag('div', get_string('filtermis_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $fmis = html_writer::checkbox('fmis', 1, $filter->get_data()->missing, get_string('filtermisfmis', 'local_amos')); $fmis = html_writer::tag('div', $fmis, array('class' => 'labelled_checkbox')); $fhlp = html_writer::checkbox('fhlp', 1, $filter->get_data()->helps, get_string('filtermisfhlp', 'local_amos')); $fhlp = html_writer::tag('div', $fhlp, array('class' => 'labelled_checkbox')); $fstg = html_writer::checkbox('fstg', 1, $filter->get_data()->stagedonly, get_string('filtermisfstg', 'local_amos')); $fstg = html_writer::tag('div', $fstg, array('class' => 'labelled_checkbox')); $fgrey = html_writer::start_tag('div', array('id' => 'amosfilter_fgrey', 'class' => 'checkboxgroup')); $fgrey .= html_writer::tag('div', html_writer::checkbox('fglo', 1, $filter->get_data()->greylistedonly, get_string('filtermisfglo', 'local_amos'), array('id' => 'amosfilter_fglo')), array('class' => 'labelled_checkbox')); $fgrey .= html_writer::tag('div', html_writer::checkbox('fwog', 1, $filter->get_data()->withoutgreylisted, get_string('filtermisfwog', 'local_amos'), array('id' => 'amosfilter_fwog')), array('class' => 'labelled_checkbox')); $fgrey .= html_writer::end_tag('div'); $output .= html_writer::tag('div', $fmis . $fhlp . $fstg . $fgrey, array('id' => 'amosfilter_fmis', 'class' => 'checkboxgroup')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // must contain string $output .= html_writer::start_tag('div', array('class' => 'item text')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', get_string('filtertxt', 'local_amos'), array('for' => 'amosfilter_ftxt')); $output .= html_writer::tag('div', get_string('filtertxt_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $output .= html_writer::empty_tag('input', array('name' => 'ftxt', 'type' => 'text', 'value' => $filter->get_data()->substring)); $output .= html_writer::checkbox('ftxr', 1, $filter->get_data()->substringregex, get_string('filtertxtregex', 'local_amos'), array('class' => 'inputmodifier')); $output .= html_writer::checkbox('ftxs', 1, $filter->get_data()->substringcs, get_string('filtertxtcasesensitive', 'local_amos'), array('class' => 'inputmodifier')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // string identifier $output .= html_writer::start_tag('div', array('class' => 'item text')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', get_string('filtersid', 'local_amos'), array('for' => 'amosfilter_fsid')); $output .= html_writer::tag('div', get_string('filtersid_desc', 'local_amos'), array('class' => 'description')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $output .= html_writer::empty_tag('input', array('name' => 'fsid', 'type' => 'text', 'value' => $filter->get_data()->stringid)); $output .= html_writer::checkbox('fsix', 1, $filter->get_data()->stringidpartial, get_string('filtersidpartial', 'local_amos'), array('class' => 'inputmodifier')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // hidden fields $output .= html_writer::start_tag('div'); $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '__lazyform_' . $filter->lazyformname, 'value' => 1)); $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); $output .= html_writer::end_tag('div'); // submit $output .= html_writer::start_tag('div', array('class' => 'item submit')); $output .= html_writer::start_tag('div', array('class' => 'label')); $output .= html_writer::tag('label', ' ', array('for' => 'amosfilter_fsbm')); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'element')); $output .= html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('savefilter', 'local_amos'), 'class' => 'submit')); $output .= html_writer::tag('span', '', array('id' => 'amosfilter_submitted_icon')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // permalink $permalink = $filter->get_permalink(); if (!is_null($permalink)) { $output .= html_writer::start_tag('div', array('class' => 'item static')); $output .= html_writer::tag('div', '', array('class' => 'label')); $output .= html_writer::start_tag('div', array('class' => 'element')); $output .= html_writer::link($permalink, get_string('permalink', 'local_amos')); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); } // block wrapper for xhtml strictness $output = html_writer::tag('div', $output, array('id' => 'amosfilter')); // form $attributes = array('method' => 'post', 'action' => $filter->handler->out(), 'id' => 'amosfilter_form', 'class' => 'lazyform ' . $filter->lazyformname); $output = html_writer::tag('form', $output, $attributes); $output = html_writer::tag('div', $output, array('class' => 'filterwrapper')); return $output; }