Skip to content

Commit

Permalink
Merge pull request #4 from ewhanson/master
Browse files Browse the repository at this point in the history
  • Loading branch information
asmecher authored May 12, 2020
2 parents d450baa + 3fb1e4d commit f826c9d
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 150 deletions.
7 changes: 7 additions & 0 deletions CustomLocalePlugin.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ function register($category, $path, $mainContextId = null) {
HookRegistry::register('LoadComponentHandler', array($this, 'setupGridHandler'));
HookRegistry::register('Template::Settings::website', array($this, 'callbackShowWebsiteSettingsTabs'));
HookRegistry::register('LoadHandler', array($this, 'handleLoadRequest'));

$templateMgr = TemplateManager::getManager($request);
$templateMgr->addJavaScript(
'customLocale',
$request->getBaseUrl() . '/' . $this->getPluginPath() . '/js/customLocale.js',
['contexts' => 'backend']
);
}

return true;
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
- Custom Locale Plugin
- Version: 1.0.1
- Author: Carola Fanselow (updates by Alec Smecher)
- Version: 1.1.0
- Author: Carola Fanselow (updates by Alec Smecher, Erik Hanson)

About
-----
Expand Down
27 changes: 13 additions & 14 deletions controllers/grid/CustomLocaleGridHandler.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,31 +61,23 @@ function updateLocale($args, $request) {
$contextId = $context->getId();
$locale = $args['locale'];
$filename = $args['key'];
$currentPage = $args['currentPage'];
$searchKey = ''; if (isset($args['searchKey'])) {$searchKey=$args['searchKey'];};
$searchString = $args['searchString'];

// don't save changes if the locale is searched
if (!$searchKey) {
// save changes
$changes = $args['changes'];

// save changes
$changes = (array) $args['changes'];
if (!empty($changes)) {
import('lib.pkp.classes.file.ContextFileManager');
$contextFileManager = new ContextFileManager($context->getId());
$customFilesDir = $contextFileManager->getBasePath() . "customLocale/$locale/";
$customFilePath = "$customFilesDir/$filename";

if ($args['nextPage']) $currentPage = $args['nextPage'];

if ($contextFileManager->fileExists($customFilePath)) {
$translations = Gettext\Translations::fromPoFile($customFilePath);
} else {
$translations = new \Gettext\Translations();
}

while (!empty($changes)) {
$key = array_shift($changes);
$value = str_replace("\r\n", "\n", array_shift($changes));
foreach ($changes as $key => $value) {
$value = str_replace("\r\n", "\n", $value);
if (!empty($value)) {
$translation = $translations->find('', $key);
if ($translation) {
Expand All @@ -101,10 +93,17 @@ function updateLocale($args, $request) {
}
}
}

$contextFileManager->mkdirtree(dirname($customFilePath));
$translations->toPoFile($customFilePath);

// Create success notification and close modal on save
$notificationMgr = new NotificationManager();
$notificationMgr->createTrivialNotification($request->getUser()->getId());
return new JSONMessage(false);
}


$context = $request->getContext();
$this->setupTemplate($request);

Expand All @@ -114,7 +113,7 @@ function updateLocale($args, $request) {
$localeFileForm = new LocaleFileForm(self::$plugin, $filename, $locale);

$localeFileForm->initData();
return new JSONMessage(true, $localeFileForm->fetch($request, $currentPage, $searchKey, $searchString));
return new JSONMessage(true, $localeFileForm->fetch($request));
}

//
Expand Down
47 changes: 8 additions & 39 deletions controllers/grid/form/LocaleFileForm.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ function __construct($customLocalePlugin, $filePath, $locale) {

/**
* @copydoc Form::fetch
* @param $currentPage int
* @param $searchKey string
* @param $searchString string
*/
function fetch($request, $currentPage=0, $searchKey='', $searchString='') {
function fetch($request) {
$file = $this->filePath;
$locale = $this->locale;
if (!CustomLocaleAction::isLocaleFile($locale, $file)) throw new Exception("$file is not a locale file!");
Expand All @@ -52,37 +49,12 @@ function fetch($request, $currentPage=0, $searchKey='', $searchString='') {
if ($contextFileManager->fileExists($customLocalePath)) $localeContents = LocaleFile::load($customLocalePath);
else $localeContents = null;
$referenceLocaleContents = LocaleFile::load($file);

$numberOfItemsPerPage = 30;
$numberOfPages = ceil(sizeof($referenceLocaleContents) / $numberOfItemsPerPage);

if ($searchKey) {

$keysReferenceLocaleContents = array_keys($referenceLocaleContents);
$keyPosition = array_search($searchString, $keysReferenceLocaleContents);

if ($keyPosition==0) {
$currentPage = 1;
}

if ($keyPosition>0) {
$currentPage = floor($keyPosition/$numberOfItemsPerPage)+1;
}

}

// set page number, default: go to first page
if (!$currentPage){
$currentPage=1;
}

$dropdownEntries = array();
for ($i=1; $i<=$numberOfPages; $i++) {
if ($i==$currentPage) {
$dropdownEntries[$i] = "stay on page " . $i;
} else {
$dropdownEntries[$i] = "go to page " . $i;
}
$referenceLocaleContentsArray = [];
foreach ($referenceLocaleContents as $key => $value) {
$referenceLocaleContentsArray[] = [
'localeKey' => $key,
'value' => $value,
];
}

import('lib.pkp.classes.core.ArrayItemIterator');
Expand All @@ -91,10 +63,7 @@ function fetch($request, $currentPage=0, $searchKey='', $searchString='') {
'filePath' => $this->filePath,
'localeContents' => $localeContents,
'locale' => $locale,
'currentPage' => $currentPage,
'dropdownEntries' => $dropdownEntries,
'searchString' => $searchString,
'referenceLocaleContents' => new ArrayItemIterator(LocaleFile::load($file), $currentPage, $numberOfItemsPerPage),
'referenceLocaleContentsArray' => $referenceLocaleContentsArray,
));

return parent::fetch($request);
Expand Down
34 changes: 18 additions & 16 deletions css/customLocale.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,33 @@
*
*/

.highlight {
background-color: #A9E2F3;
input.valueChanged, textArea.valueChanged {
background-color:#FFFF93 !important;
}

td.input {
border-top: 1px solid #999;
padding: 15px 10px 5px 10px;
.customLocale__headerDescription {
padding-top: 0.5rem;
font-size: 14px;
line-height: 1.6em;
}

input.valueChanged, textArea.valueChanged {
background-color:#FFFF93 !important;
.pkpTable td.customLocale__itemCount {
font-size: 12px;
padding: 0.5rem 1rem;
}

input, textArea {
background-color:#eee !important;
.customLocale__cellTable {
border: inherit;
}
.customLocale__cellTable tr {
border-bottom: inherit;
}

#nextPage {
width:150px;
.customLocale__cellHeader td {
font-weight: bold;
}

#searchString {
float:left;
width: 520px;
margin: 3px 10px 0px 0px;
padding: 0;
textarea.customLocale__fixedSize {
resize: none;
}

12 changes: 6 additions & 6 deletions cypress/tests/functional/CustomLocale.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ describe('Custom Locale plugin tests', function() {
cy.get('button#customLocale-button').click();
cy.get('span.label:contains("lib/pkp/locale/en_US/user.po")').parent().parent().parent().contains('Edit').click();
cy.wait(1000); // Form init
cy.get('input#searchString').type('user.affiliation');
cy.get('button:contains("Search for key")').click();
cy.get('tr.highlight').should('have.length', 1)
cy.get('tr.highlight input[id="user.affiliation"]').type('Floog Bleem', {delay: 0});
cy.get('input.pkpSearch__input').type('user.affiliation');
cy.get('button.pkpButton:contains("Search")').click();
cy.get('table.customLocale__cellTable').should('have.length', 3)
cy.get('td input[name="changes[user.affiliation]"]').type('Floog Bleem', {delay: 0});
cy.get('button:contains("Save and continue")').click();
cy.waitJQuery();
cy.get('a:contains("Cancel")').click();

// Check that the overridden locale key works.
cy.get('a:contains("admin")').click();
cy.get('a:contains("View Profile")').click();
cy.get('ul[id="navigationUser"] a:contains("admin")').click();
cy.get('ul[id="navigationUser"] a:contains("View Profile")').click({ force: true }); // Force workaround for lack of .hover() in Cypress
cy.wait(5000); // Delay to ensure cache refresh
cy.get('a:contains("Contact")').click();
cy.get('label[for^="affiliation-en_US"]:contains("Floog Bleem")');
Expand Down
87 changes: 87 additions & 0 deletions js/customLocale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
var customLocalesApp = {};
$(function() {
customLocalesApp = {
el: '#customLocales',
data: {
edited: {},
filePath: '',
localEdited: {}, // temporarily holds edited values, both saved and new
localeKeysMaster: [], // master list of all keys in locale file
filteredKeysList: [], // filtered keys allows for paginating search results
currentLocaleKeys: [], // keys available on a given page
searchPhrase: '',
phraseSearched: '',
currentPage: 0,
itemsPerPage: 50,
displaySearchResults: false,
},
methods: {
search: function() {
if (!this.searchPhrase) {
this.initializeView();
return;
}
this.phraseSearched = this.searchPhrase;
this.displaySearchResults = true;
this.currentPage = -1;
var filteredKeysList = [];
for (var i in this.localeKeysMaster) {
if (
new RegExp(this.searchPhrase, 'i' ).test(this.localeKeysMaster[i].localeKey)
|| new RegExp(this.searchPhrase, 'i' ).test(this.localeKeysMaster[i].value)
) {
filteredKeysList.push({
localeKey: this.localeKeysMaster[i].localeKey,
value: this.localeKeysMaster[i].value,
});
}
}

// Similar to initializeView, but uses search results rather than master list
this.currentPage = 1;
var end = this.currentPage * this.itemsPerPage;
var start = end - this.itemsPerPage;
this.filteredKeysList = filteredKeysList;
this.currentLocaleKeys = this.filteredKeysList.slice(start,end);
},
initializeView: function() {
this.searchPhrase = '';
this.phraseSearched = '';
this.currentPage = 1;
this.displaySearchResults = false;

this.filteredKeysList = this.localeKeysMaster; // Filtering changes
var end = this.currentPage * this.itemsPerPage;
var start = end - this.itemsPerPage;
this.currentLocaleKeys = this.filteredKeysList.slice(start,end);
}
},
computed: {
maxPages: function() {
if (!this.filteredKeysList.length) {
return 0;
}
return Math.ceil(this.filteredKeysList.length / this.itemsPerPage);
}
},
watch: {
currentPage: function(newVal, oldVal) {
if (newVal === oldVal) {
return;
}
var end = newVal * this.itemsPerPage;
var start = end - this.itemsPerPage;
this.currentLocaleKeys = this.filteredKeysList.slice(start, end); // Filtering changes

}
},
mounted: function() {
this.initializeView();
// merges edited into localEdited
this.localEdited = {}
for (var attrName in this.edited) {
this.localEdited[attrName] = this.edited[attrName];
}
},
};
});
6 changes: 6 additions & 0 deletions locale/de_DE/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ msgstr "Anpassen"
msgid "grid.action.printChanges"
msgstr "Hier können Sie eine Datei downloaden, die alle Anpassungen auflistet."

msgid "plugins.generic.customLocale.file.editHeader"
msgstr "Regionaleinstellung anpassen"

msgid "plugins.generic.customLocale.file.edit"
msgstr "{$filename} bearbeiten"

Expand All @@ -70,3 +73,6 @@ msgstr "Regionaleinstellungsdateien"

msgid "plugins.generic.customLocale.fileDescription"
msgstr "Geben Sie den angepassten Text in das jeweilige Feld ein. Lassen Sie das Feld leer, wenn der OMP-Standardtext genutzt werden soll."

msgid "plugins.generic.customLocale.searchResultsCount"
msgstr "{{ currentLocaleKeys.length }} von {{ filteredKeysList.length }} Ergebnissen für \"{{ phraseSearched }}\" ausgegeben."
6 changes: 6 additions & 0 deletions locale/en_US/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ msgstr "Customize"
msgid "grid.action.printChanges"
msgstr "Download a file that lists all the customizations you made."

msgid "plugins.generic.customLocale.file.editHeader"
msgstr "Customize locale keys"

msgid "plugins.generic.customLocale.file.edit"
msgstr "Editing {$filename}"

Expand All @@ -73,3 +76,6 @@ msgstr "Enter a complete locale key here. Keys found are highlighted."

msgid "plugins.generic.customLocale.fileDescription"
msgstr "Enter text into corresponding custom text field. Leave custom text field blank if the default OMP text should be used."

msgid "plugins.generic.customLocale.searchResultsCount"
msgstr "Displaying {{ currentLocaleKeys.length }} of {{ filteredKeysList.length }} results for \"{{ phraseSearched }}.\""
9 changes: 5 additions & 4 deletions pluginDocumentation_customLocale.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ Key data
============

- name of the plugin: Custom Locale Plugin
- author: Carola Fanselow (updates by Alec Smecher)
- current version: 1.0.1.0
- author: Carola Fanselow (updates by Alec Smecher, Erik Hanson)
- current version: 1.1.0.0
- see .travis.yml for compatibility information
- github link: https://github.com/asmecher/customLocale.git
- community plugin: yes
- date: 2020/01/24
- date: 2020/05/05

Description
============
Expand Down Expand Up @@ -75,6 +75,7 @@ Classes, plugins, external software
RedirectAction
Form
TemplateManager
NotificationManager

- OMP classes used (js, jqeury, ajax): 0

Expand All @@ -88,7 +89,7 @@ Classes, plugins, external software

Metrics
--------
- number of files: 19
- number of files: 21
- lines of code: 1k LOC

Settings
Expand Down
Loading

0 comments on commit f826c9d

Please sign in to comment.