Languages > * * It also contains the hooks for altering the output of the InputfieldFile to hold language info and links. * This is the process assigned to processwire/setup/languages/. * * ProcessWire 2.x * Copyright (C) 2012 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://www.processwire.com * http://www.ryancramer.com * */ class ProcessLanguage extends ProcessPageType { static public function getModuleInfo() { return array( 'title' => __('Languages', __FILE__), 'version' => 102, 'summary' => __('Manage system languages', __FILE__), 'author' => 'Ryan Cramer', 'requires' => 'LanguageSupport', 'icon' => 'language', 'useNavJSON' => true, ); } /** * The URL to the language-translator page (typically admin/setup/language-translator/) * */ protected $translationUrl = ''; /** * Array of messages for language_files, indexed by file basename * */ protected $fileMessages = array(); /** * Populate the fields shown in the default language list output * */ public function __construct() { parent::__construct(); $showFields = array('name', 'title', 'language_files', 'language_files_site'); $this->set('showFields', $showFields); $this->set('jsonListLabel', 'title|name'); require_once(dirname(__FILE__) . '/LanguageParser.php'); } /** * Add InputfieldFile hooks * */ public function init() { $this->addHookBefore('InputfieldFile::render', $this, 'renderInputfieldFile'); $this->addHookAfter('InputfieldFile::renderItem', $this, 'renderInputfieldFileItem'); $this->addHookAfter('InputfieldFile::renderUpload', $this, 'renderInputfieldFileUpload'); $this->addHookBefore('InputfieldFile::processInput', $this, 'processInputfieldFileInput'); parent::init(); } protected function translationUrl() { if(!$this->translationUrl) { $support = wire('modules')->get('LanguageSupport'); $this->translationUrl = wire('pages')->get($support->languageTranslatorPageID)->url; } return $this->translationUrl; } public function processInputfieldFileInput(HookEvent $event) { $event->object->overwrite = true; } /** * Hook for InputfieldFile::renderItem * * In this case we add an 'edit' link to the translator and some info about the translation file. * */ public function renderInputfieldFile(HookEvent $event) { $event->object->descriptionRows = 0; $event->object->overwrite = true; } /** * Hook for InputfieldFile::renderItem * * In this case we add an 'edit' link to the translator and some info about the translation file. * */ public function renderInputfieldFileItem(HookEvent $event) { $translationUrl = $this->translationUrl(); $pagefile = $event->arguments[0]; $page = $pagefile->get('page'); $textdomain = basename($pagefile->basename, '.json'); $data = $page->translator->getTextdomain($textdomain); $file = $data['file']; $pathname = wire('config')->paths->root . $file; $translations =& $data['translations']; $total = count($translations); $parser = new LanguageParser($page->translator, $pathname); $untranslated = $parser->getUntranslated(); $numPending = 0; $numAbandoned = 0; foreach($untranslated as $hash => $text) { if(!isset($translations[$hash]) || !strlen($translations[$hash]['text'])) $numPending++; } foreach($translations as $hash => $translation) { if(!isset($untranslated[$hash])) $numAbandoned++; } $total += $numAbandoned; $message = sprintf($this->_n("%d phrase", "%d phrases", $total), $total); if($numAbandoned || $numPending) { $message .= " ("; if($numAbandoned) $message .= sprintf($this->_('%d abandoned'), $numAbandoned); if($numPending) $message .= ($numAbandoned ? ', ' : '') . sprintf($this->_('%d blank'), $numPending); $message .= ")"; } $lastMod = date($this->config->dateFormat, filemtime($pagefile->filename)); $editLabel = $this->_x('Edit', 'edit-language-file'); $out = "
" . "/$file — $message " . "  " . " $editLabel " . "
"; $page->translator->unloadTextdomain($textdomain); $event->return .= $out; } /** * Hook for InputfieldFile::renderUpload * * This just adds a 'new' link to add a new translation file. * */ public function renderInputfieldFileUpload(HookEvent $event) { $translationUrl = $this->translationUrl(); $page = $event->arguments[0]->get('page'); $inputfield = $event->object; $out = ''; $btn1 = $this->wire('modules')->get('InputfieldButton'); $btn1->href = "{$translationUrl}add/?language_id={$page->id}"; $btn1->value = $this->_('Translate File'); $btn1->icon = 'plane'; if($inputfield->name == 'language_files') $btn1->addClass('head_button_clone'); $out .= $btn1->render(); if(count($inputfield->attr('value'))) { $btn2 = $this->wire('modules')->get('InputfieldButton'); $btn2->href = "../download/?language_id={$page->id}&field=" . $inputfield->attr('name'); $btn2->value = $this->_('Download ZIP'); $btn2->icon = 'cloud-download'; $btn2->addClass('ui-priority-secondary'); $out .= $btn2->render(); } $event->return .= "

$out

"; } /** * Modify the output per-field in the PageType list (template-method) * * In this case we make it return a count for the language_files * */ protected function renderListFieldValue($name, $value) { if($name == 'language_files' || $name == 'language_files_site') { return count($value); } else if($name == 'title') { if(!$value) return '(blank)'; return (string) $value; } else { return parent::renderListFieldValue($name, $value); } } public function ___execute() { // check if 2.5 update needed to add new language_files_site field if(!$this->wire('fields')->get('language_files_site')) { require_once(dirname(__FILE__) . '/LanguageSupportInstall.php'); $installer = new LanguageSupportInstall(); $installer->addFilesFields($this->wire('fieldgroups')->get(LanguageSupport::languageTemplateName)); } return parent::___execute(); } /** * Create and send a ZIP of translation files * */ public function ___executeDownload() { $id = (int) $this->input->get('language_id'); if(!$id) throw new WireException("No language specified"); $language = $this->wire('languages')->get($id); $fieldName = $this->input->get('field') == 'language_files_site' ? 'language_files_site' : 'language_files'; if(!$language->id) throw new WireException("Unknown language"); $path = $language->$fieldName->path(); $files = array(); foreach($language->$fieldName as $file) { $files[] = $file->filename; } $zipname = $language->name . "-"; $zipname .= $fieldName == 'language_files' ? 'wire' : 'site'; $zipfile = "$path$zipname.zip"; $info = wireZipFile($zipfile, $files, array("overwrite" => true)); if(!count($info['files'])) { $this->error("Error adding files to ZIP"); $this->session->redirect('../'); } else { wireSendFile($zipfile); exit(0); } } }