updated webform, webform_localization, profile2, term_merge, search_api_saved_pages, rules, redirect, overide_node_options

This commit is contained in:
2019-05-13 18:47:27 +02:00
parent 58cd990c8c
commit 9adc940a67
281 changed files with 28658 additions and 7138 deletions

View File

@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\Component\Gettext\PoHeader
* Definition of Drupal\Component\Gettext\PoHeader.
*/
/**
@@ -88,7 +88,7 @@ class PoHeader {
* Plural form component from the header, for example:
* 'nplurals=2; plural=(n > 1);'.
*/
function getPluralForms() {
public function getPluralForms() {
return $this->_pluralForms;
}
@@ -98,7 +98,7 @@ class PoHeader {
* @param string $languageName
* Human readable language name.
*/
function setLanguageName($languageName) {
public function setLanguageName($languageName) {
$this->_languageName = $languageName;
}
@@ -108,7 +108,7 @@ class PoHeader {
* @return string
* The human readable language name.
*/
function getLanguageName() {
public function getLanguageName() {
return $this->_languageName;
}
@@ -118,7 +118,7 @@ class PoHeader {
* @param string $projectName
* Human readable project name.
*/
function setProjectName($projectName) {
public function setProjectName($projectName) {
$this->_projectName = $projectName;
}
@@ -128,7 +128,7 @@ class PoHeader {
* @return string
* The human readable project name.
*/
function getProjectName() {
public function getProjectName() {
return $this->_projectName;
}
@@ -186,11 +186,14 @@ class PoHeader {
* @param string $pluralforms
* The Plural-Forms entry value.
*
* @return
* @return array|boolean
* An array containing the number of plural forms and the converted version
* of the formula that can be evaluated with PHP later.
*
* @throws \Exception
* Throws exception in case plural formula could not be parsed.
*/
function parsePluralForms($pluralforms) {
public function parsePluralForms($pluralforms) {
// First, delete all whitespace.
$pluralforms = strtr($pluralforms, array(" " => "", "\t" => ""));
@@ -253,7 +256,7 @@ class PoHeader {
* @param string $string
* A string containing the arithmetic formula.
*
* @return
* @return string|FALSE
* A version of the formula to evaluate with PHP later.
*/
private function parseArithmetic($string) {
@@ -388,6 +391,7 @@ class PoHeader {
$tokens[] = $formula[$i];
}
break;
case 5:
if ($next == '&') {
$tokens[] = '&&';
@@ -397,6 +401,7 @@ class PoHeader {
$tokens[] = $formula[$i];
}
break;
case 6:
if ($next == '|') {
$tokens[] = '||';

View File

@@ -13,7 +13,7 @@ class PoItem {
/**
* The language code this translation is in.
*
* @car string
* @var string
*/
private $_langcode;
@@ -27,7 +27,8 @@ class PoItem {
/**
* The source string or array of strings if it has plurals.
*
* @var string or array
* @var string|array
*
* @see $_plural
*/
private $_source;
@@ -46,10 +47,18 @@ class PoItem {
*/
private $_comment;
/**
* The text group of this translation.
*
* @var string
*/
private $_textgroup;
/**
* The translation string or array of strings if it has plurals.
*
* @var string or array
* @var string|array
*
* @see $_plural
*/
private $_translation;
@@ -57,9 +66,10 @@ class PoItem {
/**
* Get the language code of the currently used language.
*
* @return string with langcode
* @return string
* The translation language code.
*/
function getLangcode() {
public function getLangcode() {
return $this->_langcode;
}
@@ -67,109 +77,131 @@ class PoItem {
* Set the language code of the current language.
*
* @param string $langcode
* The translation language code.
*/
function setLangcode($langcode) {
public function setLangcode($langcode) {
$this->_langcode = $langcode;
}
/**
* Get the translation group of this translation.
*
* @return string
* The translation text group.
*/
public function getTextgroup() {
return empty($this->_textgroup) ? 'default' : $this->_textgroup;
}
/**
* Set the translation group of this translation.
*
* @param string $textgroup
* The translation text group.
*/
public function setTextgroup($textgroup) {
$this->_textgroup = $textgroup;
}
/**
* Get the context this translation belongs to.
*
* @return string $context
* @return string
* The translation context.
*/
function getContext() {
public function getContext() {
return $this->_context;
}
/**
* Set the context this translation belongs to.
*
* @param string $context
*/
function setContext($context) {
public function setContext($context) {
$this->_context = $context;
}
/**
* Get the source string or the array of strings if the translation has
* plurals.
* Get the source string(s) if the translation has plurals.
*
* @return string or array $translation
* @return string|array
* Translation source string(s).
*/
function getSource() {
public function getSource() {
return $this->_source;
}
/**
* Set the source string or the array of strings if the translation has
* plurals.
* Set the source string(s) if the translation has plurals.
*
* @param string or array $source
* @param string|array
* Translation source string(s).
*/
function setSource($source) {
public function setSource($source) {
$this->_source = $source;
}
/**
* Get the translation string or the array of strings if the translation has
* plurals.
* Get the translation string(s) if the translation has plurals.
*
* @return string or array $translation
* @return string|array
* Translation string(s).
*/
function getTranslation() {
public function getTranslation() {
return $this->_translation;
}
/**
* Set the translation string or the array of strings if the translation has
* plurals.
*
* @param string or array $translation
* Set the translation string(s) if the translation has plurals.
*/
function setTranslation($translation) {
public function setTranslation($translation) {
$this->_translation = $translation;
}
/**
* Set if the translation has plural values.
*
* @param boolean $plural
* @param bool $plural
* The translation plural flag.
*/
function setPlural($plural) {
public function setPlural($plural) {
$this->_plural = $plural;
}
/**
* Get if the translation has plural values.
*
* @return boolean $plural
* @return integer $plural
* The translation plural flag.
*/
function isPlural() {
public function isPlural() {
return $this->_plural;
}
/**
* Get the comment of this translation.
*
* @return String $comment
* @return string
* The translation comment.
*/
function getComment() {
public function getComment() {
return $this->_comment;
}
/**
* Set the comment of this translation.
*
* @param String $comment
* @param string $comment
* The translation comment.
*/
function setComment($comment) {
public function setComment($comment) {
$this->_comment = $comment;
}
/**
* Create the PoItem from a structured array.
*
* @param array values
* @param array $values
* Keyed array with translation data.
*/
public function setFromArray(array $values = array()) {
if (isset($values['context'])) {
@@ -181,19 +213,19 @@ class PoItem {
if (isset($values['translation'])) {
$this->setTranslation($values['translation']);
}
if (isset($values['comment'])){
if (isset($values['comment'])) {
$this->setComment($values['comment']);
}
if (isset($this->_source) &&
strpos($this->_source, L10N_UPDATE_PLURAL_DELIMITER) !== FALSE) {
$this->setSource(explode(L10N_UPDATE_PLURAL_DELIMITER, $this->_source));
$this->setTranslation(explode(L10N_UPDATE_PLURAL_DELIMITER, $this->_translation));
if (isset($this->_source) && count($this->_source) > 1) {
$this->setPlural(count($this->_translation) > 1);
}
}
/**
* Output the PoItem as a string.
*
* @return string
* PO item string value.
*/
public function __toString() {
return $this->formatItem();
@@ -201,6 +233,9 @@ class PoItem {
/**
* Format the POItem as a string.
*
* @return string
* Formatted PO item.
*/
private function formatItem() {
$output = '';
@@ -226,6 +261,9 @@ class PoItem {
/**
* Formats a plural translation.
*
* @return string
* Gettext formatted plural translation.
*/
private function formatPlural() {
$output = '';
@@ -248,6 +286,9 @@ class PoItem {
/**
* Formats a singular translation.
*
* @return string
* Gettext formatted singular translation.
*/
private function formatSingular() {
$output = '';
@@ -258,6 +299,12 @@ class PoItem {
/**
* Formats a string for output on multiple lines.
*
* @param string $string
* A string.
*
* @return string
* Gettext formatted multi-line string.
*/
private function formatString($string) {
// Escape characters for processing.

View File

@@ -20,7 +20,7 @@ class PoMemoryWriter implements PoWriterInterface {
/**
* Constructor, initialize empty items.
*/
function __construct() {
public function __construct() {
$this->_items = array();
}
@@ -28,12 +28,28 @@ class PoMemoryWriter implements PoWriterInterface {
* Implements PoWriterInterface::writeItem().
*/
public function writeItem(PoItem $item) {
if (is_array($item->getSource())) {
$item->setSource(implode(L10N_UPDATE_PLURAL_DELIMITER, $item->getSource()));
$item->setTranslation(implode(L10N_UPDATE_PLURAL_DELIMITER, $item->getTranslation()));
}
$context = $item->getContext();
$this->_items[$context != NULL ? $context : ''][$item->getSource()] = $item->getTranslation();
$context = $context != NULL ? $context : '';
if ($item->isPlural()) {
$sources = $item->getSource();
$translations = $item->getTranslation();
// Build additional source strings for plurals.
$entries = array_keys($translations);
for ($i = 3; $i <= count($entries); $i++) {
$sources[] = $sources[1];
}
$translations = array_map('_locale_import_append_plural', $translations, $entries);
$sources = array_map('_locale_import_append_plural', $sources, $entries);
foreach ($entries as $index) {
$this->_items[][$sources[$index]] = $translations[$index];
}
}
else {
$this->_items[$context][$item->getSource()] = $item->getTranslation();
}
}
/**
@@ -49,7 +65,8 @@ class PoMemoryWriter implements PoWriterInterface {
/**
* Get all stored PoItem's.
*
* @return array PoItem
* @return array
* Array of PO item's.
*/
public function getData() {
return $this->_items;
@@ -60,7 +77,7 @@ class PoMemoryWriter implements PoWriterInterface {
*
* Not implemented. Not relevant for the MemoryWriter.
*/
function setLangcode($langcode) {
public function setLangcode($langcode) {
}
/**
@@ -68,7 +85,7 @@ class PoMemoryWriter implements PoWriterInterface {
*
* Not implemented. Not relevant for the MemoryWriter.
*/
function getLangcode() {
public function getLangcode() {
}
/**
@@ -76,7 +93,7 @@ class PoMemoryWriter implements PoWriterInterface {
*
* Not implemented. Not relevant for the MemoryWriter.
*/
function getHeader() {
public function getHeader() {
}
/**
@@ -84,7 +101,7 @@ class PoMemoryWriter implements PoWriterInterface {
*
* Not implemented. Not relevant for the MemoryWriter.
*/
function setHeader(PoHeader $header) {
public function setHeader(PoHeader $header) {
}
}

View File

@@ -26,7 +26,7 @@ interface PoStreamInterface {
/**
* Get the URI of the PO stream that is being read or written.
*
* @return
* @return string
* URI string for this stream.
*/
public function getURI();
@@ -34,7 +34,7 @@ interface PoStreamInterface {
/**
* Set the URI of the PO stream that is going to be read or written.
*
* @param $uri
* @param string $uri
* URI string to set for this stream.
*/
public function setURI($uri);

View File

@@ -9,7 +9,7 @@
* Implements Gettext PO stream reader.
*
* The PO file format parsing is implemented according to the documentation at
* http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
* http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files.
*/
class PoStreamReader implements PoStreamInterface, PoReaderInterface {
@@ -228,7 +228,7 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
if (!$item) {
return;
}
$header = new PoHeader;
$header = new PoHeader();
$header->setFromString(trim($item->getTranslation()));
$this->_header = $header;
}
@@ -240,13 +240,13 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
* this line ends the current item, it is saved with setItemFromArray() with
* data from $this->_current_item.
*
* An internal state machine is maintained in this reader using $this->_context
* as the reading state. PO items are inbetween COMMENT states (when items have
* at least one line or comment inbetween them or indicated by MSGSTR or
* MSGSTR_ARR followed immediately by an MSGID or MSGCTXT (when items closely
* follow each other).
* An internal state machine is maintained in this reader using
* $this->_context as the reading state. PO items are in between COMMENT
* states (when items have at least one line or comment in between them or
* indicated by MSGSTR or MSGSTR_ARR followed immediately by an MSGID or
* MSGCTXT (when items closely follow each other).
*
* @return
* @return FALSE|NULL
* FALSE if an error was logged, NULL otherwise. The errors are considered
* non-blocking, so reading can continue, while the errors are collected
* for later presentation.
@@ -281,7 +281,6 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
if (!strncmp('#', $line, 1)) {
// Lines starting with '#' are comments.
if ($this->_context == 'COMMENT') {
// Already in comment context, add to current comment.
$this->_current_item['#'][] = substr($line, 1);
@@ -295,18 +294,17 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item['#'][] = substr($line, 1);
$this->_context = 'COMMENT';
return;
return NULL;
}
else {
// A comment following any other context is a syntax error.
$this->_errors[] = format_string('The translation stream %uri contains an error: "msgstr" was expected but not found on line %line.', $log_vars);
return FALSE;
}
return;
return NULL;
}
elseif (!strncmp('msgid_plural', $line, 12)) {
// A plural form for the current source string.
if ($this->_context != 'MSGID') {
// A plural form can only be added to an msgid directly.
$this->_errors[] = format_string('The translation stream %uri contains an error: "msgid_plural" was expected but not found on line %line.', $log_vars);
@@ -333,11 +331,10 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item['msgid'][] = $quoted;
$this->_context = 'MSGID_PLURAL';
return;
return NULL;
}
elseif (!strncmp('msgid', $line, 5)) {
// Starting a new message.
if (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
// We are currently in string context, save current item.
$this->setItemFromArray($this->_current_item);
@@ -346,7 +343,8 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item = array();
}
elseif ($this->_context == 'MSGID') {
// We are currently already in the context, meaning we passed an id with no data.
// We are currently already in the context, meaning we passed an id
// with no data.
$this->_errors[] = format_string('The translation stream %uri contains an error: "msgid" is unexpected on line %line.', $log_vars);
return FALSE;
}
@@ -358,17 +356,16 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$quoted = $this->parseQuoted($line);
if ($quoted === FALSE) {
// The message id must be wrapped in quotes.
$this->_errors[] = format_string('The translation stream %uri contains an error: invalid format for "msgid" on line %line.', $log_vars, $log_vars);
$this->_errors[] = format_string('The translation stream %uri contains an error: invalid format for "msgid" on line %line.', $log_vars);
return FALSE;
}
$this->_current_item['msgid'] = $quoted;
$this->_context = 'MSGID';
return;
return NULL;
}
elseif (!strncmp('msgctxt', $line, 7)) {
// Starting a new context.
if (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
// We are currently in string context, save current item.
$this->setItemFromArray($this->_current_item);
@@ -394,11 +391,10 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item['msgctxt'] = $quoted;
$this->_context = 'MSGCTXT';
return;
return NULL;
}
elseif (!strncmp('msgstr[', $line, 7)) {
// A message string for a specific plurality.
if (($this->_context != 'MSGID') &&
($this->_context != 'MSGCTXT') &&
($this->_context != 'MSGID_PLURAL') &&
@@ -436,11 +432,10 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item['msgstr'][$this->_current_plural_index] = $quoted;
$this->_context = 'MSGSTR_ARR';
return;
return NULL;
}
elseif (!strncmp("msgstr", $line, 6)) {
// A string pair for an msgidid (with optional context).
if (($this->_context != 'MSGID') && ($this->_context != 'MSGCTXT')) {
// Strings are only valid within an id or context scope.
$this->_errors[] = format_string('The translation stream %uri contains an error: "msgstr" is unexpected on line %line.', $log_vars);
@@ -461,11 +456,11 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_current_item['msgstr'] = $quoted;
$this->_context = 'MSGSTR';
return;
return NULL;
}
elseif ($line != '') {
// Anything that is not a token may be a continuation of a previous token.
// Anything that is not a token may be a continuation of a previous
// token.
$quoted = $this->parseQuoted($line);
if ($quoted === FALSE) {
// This string must be quoted.
@@ -502,7 +497,7 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_errors[] = format_string('The translation stream %uri contains an error: unexpected string on line %line.', $log_vars);
return FALSE;
}
return;
return NULL;
}
}
@@ -515,6 +510,8 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$this->_errors[] = format_string('The translation stream %uri ended unexpectedly at line %line.', $log_vars);
return FALSE;
}
return NULL;
}
/**
@@ -524,8 +521,10 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$plural = FALSE;
$comments = '';
$textgroup = 'default';
if (isset($value['#'])) {
$comments = $this->shortenComments($value['#']);
$textgroup = $this->fetchGroupFromComment($comments);
}
if (is_array($value['msgstr'])) {
@@ -541,6 +540,7 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
$item->setPlural($plural);
$item->setComment($comments);
$item->setLangcode($this->_langcode);
$item->setTextgroup($textgroup);
$this->_last_item = $item;
@@ -550,13 +550,13 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
/**
* Parses a string in quotes.
*
* @param $string
* @param string $string
* A string specified with enclosing quotes.
*
* @return
* @return string|FALSE
* The string parsed from inside the quotes.
*/
function parseQuoted($string) {
public function parseQuoted($string) {
if (substr($string, 0, 1) != substr($string, -1, 1)) {
// Start and end quotes must be the same.
return FALSE;
@@ -580,10 +580,10 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
/**
* Generates a short, one-string version of the passed comment array.
*
* @param $comment
* @param string|array $comment
* An array of strings containing a comment.
*
* @return
* @return string
* Short one-string version of the comment.
*/
private function shortenComments($comment) {
@@ -600,4 +600,27 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
return trim(substr($comm, 0, -2));
}
/**
* Determine a translation text group using a source's comment-string.
*
* @param string $comment
* Comment string.
*
* @return string
* The comment's text group.
*/
private function fetchGroupFromComment($comment) {
// Only if i18n_string is installed, check for and set textgroups.
if (module_exists('i18n_string') && strpos($comment, ':') !== FALSE) {
// Fetch available textgroups.
$groups = array_keys(i18n_string_group_info());
// Parse textgroup from comment (assume default drupal exports).
$comment_array = explode(':', $comment);
if (!empty($comment_array) && in_array($comment_array[0], $groups)) {
return $comment_array[0];
}
}
return 'default';
}
}

View File

@@ -23,7 +23,7 @@ interface PoWriterInterface extends PoMetadataInterface {
*
* @param PoReaderInterface $reader
* Reader to read PoItems from.
* @param $count
* @param int $count
* Amount of items to read from $reader to write. If -1, all items are
* read from $reader.
*/

View File

@@ -11,14 +11,14 @@
* The operations are related to pumping data from a source to a destination,
* for example:
* - Remote files http://*.po to memory
* - File public://*.po to database
* - File public://*.po to database.
*/
class Gettext {
/**
* Reads the given PO files into the database.
*
* @param stdClass $file
* @param object $file
* File object with an URI property pointing at the file's path.
* - "langcode": The language the strings will be added to.
* - "uri": File URI.
@@ -28,8 +28,8 @@ class Gettext {
* PoDatabaseWriter. Optional, defaults to an empty array.
* - 'customized': Flag indicating whether the strings imported from $file
* are customized translations or come from a community source. Use
* L10N_UPDATE_CUSTOMIZED or L10N_UPDATE_NOT_CUSTOMIZED. Optional, defaults to
* L10N_UPDATE_NOT_CUSTOMIZED.
* L10N_UPDATE_CUSTOMIZED or L10N_UPDATE_NOT_CUSTOMIZED. Optional,
* defaults to L10N_UPDATE_NOT_CUSTOMIZED.
* - 'seek': Specifies from which position in the file should the reader
* start reading the next items. Optional, defaults to 0.
* - 'items': Specifies the number of items to read. Optional, defaults to
@@ -38,9 +38,12 @@ class Gettext {
* @return array
* Report array as defined in PoDatabaseWriter.
*
* @throws \Exception
* Throws exception in case of missing header.
*
* @see PoDatabaseWriter
*/
static function fileToDatabase($file, $options) {
public static function fileToDatabase($file, array $options) {
// Add the default values to the options array.
$options += array(
'overwrite_options' => array(),
@@ -94,4 +97,5 @@ class Gettext {
$report['seek'] = $reader->getSeek();
return $report;
}
}

View File

@@ -40,6 +40,13 @@ class PoDatabaseReader implements PoReaderInterface {
*/
private $_result;
/**
* D7: Text group.
*
* @var string
*/
protected $_textgroup;
/**
* Database storage to retrieve the strings from.
*
@@ -50,7 +57,7 @@ class PoDatabaseReader implements PoReaderInterface {
/**
* Constructor, initializes with default options.
*/
function __construct() {
public function __construct() {
$this->setOptions(array());
$this->storage = new StringDatabaseStorage();
}
@@ -72,14 +79,14 @@ class PoDatabaseReader implements PoReaderInterface {
/**
* Get the options used by the reader.
*/
function getOptions() {
public function getOptions() {
return $this->_options;
}
/**
* Set the options for the current reader.
*/
function setOptions(array $options) {
public function setOptions(array $options) {
$options += array(
'customized' => FALSE,
'not_customized' => FALSE,
@@ -88,10 +95,17 @@ class PoDatabaseReader implements PoReaderInterface {
$this->_options = $options;
}
/**
* @param \string $textgroup
*/
public function setTextgroup($textgroup) {
$this->_textgroup = $textgroup;
}
/**
* Implements PoMetadataInterface::getHeader().
*/
function getHeader() {
public function getHeader() {
return new PoHeader($this->getLangcode());
}
@@ -101,7 +115,7 @@ class PoDatabaseReader implements PoReaderInterface {
* @throws Exception
* Always, because you cannot set the PO header of a reader.
*/
function setHeader(PoHeader $header) {
public function setHeader(PoHeader $header) {
throw new \Exception('You cannot set the PO header in a reader.');
}
@@ -111,7 +125,11 @@ class PoDatabaseReader implements PoReaderInterface {
private function loadStrings() {
$langcode = $this->_langcode;
$options = $this->_options;
$textgroup = $this->_textgroup;
$conditions = array();
if ($textgroup) {
$conditions['textgroup'] = $textgroup;
}
if (array_sum($options) == 0) {
// If user asked to not include anything in the translation files,
@@ -166,9 +184,9 @@ class PoDatabaseReader implements PoReaderInterface {
/**
* Implements PoReaderInterface::readItem().
*/
function readItem() {
public function readItem() {
if ($string = $this->readString()) {
$values = (array)$string;
$values = (array) $string;
$poItem = new PoItem();
$poItem->setFromArray($values);
return $poItem;

View File

@@ -47,7 +47,7 @@ class PoDatabaseWriter implements PoWriterInterface {
* - additions: number of source strings newly added
* - updates: number of translations updated
* - deletes: number of translations deleted
* - skips: number of strings skipped due to disallowed HTML
* - skips: number of strings skipped due to disallowed HTML.
*
* @var array
*/
@@ -63,7 +63,7 @@ class PoDatabaseWriter implements PoWriterInterface {
/**
* Constructor, initialize reporting array.
*/
function __construct() {
public function __construct() {
$this->setReport();
$this->storage = new StringDatabaseStorage();
}
@@ -95,7 +95,7 @@ class PoDatabaseWriter implements PoWriterInterface {
* @param array $report
* Associative array with result information.
*/
function setReport($report = array()) {
public function setReport($report = array()) {
$report += array(
'additions' => 0,
'updates' => 0,
@@ -109,14 +109,14 @@ class PoDatabaseWriter implements PoWriterInterface {
/**
* Get the options used by the writer.
*/
function getOptions() {
public function getOptions() {
return $this->_options;
}
/**
* Set the options for the current writer.
*/
function setOptions(array $options) {
public function setOptions(array $options) {
if (!isset($options['overwrite_options'])) {
$options['overwrite_options'] = array();
}
@@ -133,7 +133,7 @@ class PoDatabaseWriter implements PoWriterInterface {
/**
* Implements PoMetadataInterface::getHeader().
*/
function getHeader() {
public function getHeader() {
return $this->_header;
}
@@ -151,8 +151,9 @@ class PoDatabaseWriter implements PoWriterInterface {
* Header metadata.
*
* @throws Exception
* Exception is thrown when required properties are not set.
*/
function setHeader(PoHeader $header) {
public function setHeader(PoHeader $header) {
$this->_header = $header;
$languages = language_list();
@@ -193,12 +194,29 @@ class PoDatabaseWriter implements PoWriterInterface {
/**
* Implements PoWriterInterface::writeItem().
*/
function writeItem(PoItem $item) {
public function writeItem(PoItem $item) {
if ($item->isPlural()) {
$item->setSource(join(L10N_UPDATE_PLURAL_DELIMITER, $item->getSource()));
$item->setTranslation(join(L10N_UPDATE_PLURAL_DELIMITER, $item->getTranslation()));
$sources = $item->getSource();
$translations = $item->getTranslation();
// Build additional source strings for plurals.
$entries = array_keys($translations);
for ($i = 3; $i <= count($entries); $i++) {
$sources[] = $sources[1];
}
$translations = array_map('_locale_import_append_plural', $translations, $entries);
$sources = array_map('_locale_import_append_plural', $sources, $entries);
$plid = 0;
foreach ($entries as $index) {
$item->setSource($sources[$index]);
$item->setTranslation($translations[$index]);
$plid = $this->importString($item, $plid, $index);
}
}
else {
$this->importString($item);
}
$this->importString($item);
}
/**
@@ -216,11 +234,15 @@ class PoDatabaseWriter implements PoWriterInterface {
*
* @param PoItem $item
* The item being imported.
* @param integer $plid
* The parent string identifier for plural strings.
* @param integer $plural
* The plural index number.
*
* @return int
* The string ID of the existing string modified or the new string added.
*/
private function importString(PoItem $item) {
private function importString(PoItem $item, $plid = 0, $plural = 0) {
// Initialize overwrite options if not set.
$this->_options['overwrite_options'] += array(
'not_customized' => FALSE,
@@ -232,12 +254,14 @@ class PoDatabaseWriter implements PoWriterInterface {
$context = $item->getContext();
$source = $item->getSource();
$translation = $item->getTranslation();
$textgroup = $item->getTextgroup();
// Look up the source string and any existing translation.
$strings = $this->storage->getTranslations(array(
'language' => $this->_langcode,
'source' => $source,
'context' => $context
'context' => $context,
'textgroup' => $textgroup,
));
$string = reset($strings);
@@ -253,8 +277,10 @@ class PoDatabaseWriter implements PoWriterInterface {
if ($string->isNew()) {
// No translation in this language.
$string->setValues(array(
'plid' => $plid,
'plural' => $plural,
'language' => $this->_langcode,
'customized' => $customized
'customized' => $customized,
));
$string->save();
$this->_report['additions']++;
@@ -270,10 +296,12 @@ class PoDatabaseWriter implements PoWriterInterface {
}
else {
// No such source string in the database yet.
$string = $this->storage->createString(array('source' => $source, 'context' => $context))
$string = $this->storage->createString(array('source' => $source, 'context' => $context, 'textgroup' => $textgroup))
->save();
$target = $this->storage->createTranslation(array(
$this->storage->createTranslation(array(
'lid' => $string->getId(),
'plid' => $plid,
'plural' => $plural,
'language' => $this->_langcode,
'translation' => $translation,
'customized' => $customized,
@@ -292,5 +320,4 @@ class PoDatabaseWriter implements PoWriterInterface {
return $string->lid;
}
}
}

View File

@@ -13,6 +13,15 @@
* value, and is assumed to be in English language.
*/
class SourceString extends StringBase {
/**
* Implements StringInterface::getParentId().
*/
public function getParentId() {
// Source strings don't have a parent; Translations do.
return 0;
}
/**
* Implements StringInterface::isSource().
*/

View File

@@ -12,6 +12,7 @@
* the common properties and methods for source and translation strings.
*/
abstract class StringBase implements StringInterface {
/**
* The string identifier.
*
@@ -19,6 +20,20 @@ abstract class StringBase implements StringInterface {
*/
public $lid;
/**
* The parent string identifier for plural translations.
*
* @var integer
*/
public $plid;
/**
* Plural index in case of plural string.
*
* @var integer
*/
public $plural;
/**
* The string locations indexed by type.
*
@@ -40,6 +55,13 @@ abstract class StringBase implements StringInterface {
*/
public $context;
/**
* The string group.
*
* @var string
*/
public $textgroup;
/**
* The string version.
*
@@ -61,7 +83,7 @@ abstract class StringBase implements StringInterface {
* Object or array with initial values.
*/
public function __construct($values = array()) {
$this->setValues((array)$values);
$this->setValues((array) $values);
}
/**
@@ -79,6 +101,21 @@ abstract class StringBase implements StringInterface {
return $this;
}
/**
* Implements StringInterface::getParentId().
*/
public function getParentId() {
return isset($this->plid) ? $this->plid : 0;
}
/**
* Implements StringInterface::setParentId().
*/
public function setParentId($plid) {
$this->plid = $plid;
return $this;
}
/**
* Implements StringInterface::getVersion().
*/
@@ -94,21 +131,6 @@ abstract class StringBase implements StringInterface {
return $this;
}
/**
* Implements StringInterface::getPlurals().
*/
public function getPlurals() {
return explode(L10N_UPDATE_PLURAL_DELIMITER, $this->getString());
}
/**
* Implements StringInterface::setPlurals().
*/
public function setPlurals($plurals) {
$this->setString(implode(L10N_UPDATE_PLURAL_DELIMITER, $plurals));
return $this;
}
/**
* Implements StringInterface::getStorage().
*/
@@ -119,7 +141,7 @@ abstract class StringBase implements StringInterface {
/**
* Implements StringInterface::setStorage().
*/
public function setStorage($storage) {
public function setStorage(StringStorageInterface $storage) {
$this->storage = $storage;
return $this;
}
@@ -149,6 +171,20 @@ abstract class StringBase implements StringInterface {
return $values;
}
/**
* Implements StringInterface::getTextgroup().
*/
public function getTextgroup() {
return empty($this->textgroup) ? 'default' : $this->textgroup;
}
/**
* Implements StringInterface::setTextgroup().
*/
public function setTextgroup($textgroup) {
$this->textgroup = $textgroup;
}
/**
* Implements LocaleString::save().
*/
@@ -158,7 +194,7 @@ abstract class StringBase implements StringInterface {
}
else {
throw new StringStorageException(format_string('The string cannot be saved because its not bound to a storage: @string', array(
'@string' => $this->getString()
'@string' => $this->getString(),
)));
}
return $this;
@@ -174,7 +210,7 @@ abstract class StringBase implements StringInterface {
}
else {
throw new StringStorageException(format_string('The string cannot be deleted because its not bound to a storage: @string', array(
'@string' => $this->getString()
'@string' => $this->getString(),
)));
}
}

View File

@@ -91,7 +91,7 @@ class StringDatabaseStorage implements StringStorageInterface {
/**
* Implements StringStorageInterface::save().
*/
public function save($string) {
public function save(\StringInterface $string) {
if ($string->isNew()) {
$result = $this->dbStringInsert($string);
if ($string->isSource() && $result) {
@@ -114,20 +114,20 @@ class StringDatabaseStorage implements StringStorageInterface {
* @param string $version
* Drupal version to check against.
*/
protected function checkVersion($string, $version) {
protected function checkVersion(StringInterface $string, $version) {
if ($string->getId() && $string->getVersion() != $version) {
$string->setVersion($version);
db_update('locales_source', $this->options)
->condition('lid', $string->getId())
->fields(array('version' => $version))
->execute();
->condition('lid', $string->getId())
->fields(array('version' => $version))
->execute();
}
}
/**
* Implements StringStorageInterface::delete().
*/
public function delete($string) {
public function delete(\StringInterface $string) {
if ($keys = $this->dbStringKeys($string)) {
$this->dbDelete('locales_target', $keys)->execute();
if ($string->isSource()) {
@@ -138,7 +138,7 @@ class StringDatabaseStorage implements StringStorageInterface {
}
else {
throw new StringStorageException(format_string('The string cannot be deleted because it lacks some key fields: @string', array(
'@string' => $string->getString()
'@string' => $string->getString(),
)));
}
return $this;
@@ -147,19 +147,19 @@ class StringDatabaseStorage implements StringStorageInterface {
/**
* Implements StringStorageInterface::deleteLanguage().
*/
public function deleteStrings($conditions) {
public function deleteStrings(array $conditions) {
$lids = $this->dbStringSelect($conditions, array('fields' => array('lid')))->execute()->fetchCol();
if ($lids) {
$this->dbDelete('locales_target', array('lid' => $lids))->execute();
$this->dbDelete('locales_source', array('lid' => $lids))->execute();
$this->dbDelete('locales_location', array('sid' => $lids))->execute();
$this->dbDelete('locales_source', array('lid' => $lids))->execute();
$this->dbDelete('locales_location', array('sid' => $lids))->execute();
}
}
/**
* Implements StringStorageInterface::deleteLanguage().
*/
public function deleteTranslations($conditions) {
public function deleteTranslations(array $conditions) {
$this->dbDelete('locales_target', $conditions)->execute();
}
@@ -176,7 +176,7 @@ class StringDatabaseStorage implements StringStorageInterface {
public function createTranslation($values = array()) {
return new TranslationString($values + array(
'storage' => $this,
'is_new' => TRUE
'is_new' => TRUE,
));
}
@@ -191,7 +191,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* target or location table table.
*/
protected function dbFieldTable($field) {
if (in_array($field, array('language', 'translation', 'customized'))) {
if (in_array($field, array('language', 'translation', 'l10n_status'))) {
return 't';
}
elseif (in_array($field, array('type', 'name'))) {
@@ -211,7 +211,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* @return string
* The table name.
*/
protected function dbStringTable($string) {
protected function dbStringTable(StringInterface $string) {
if ($string->isSource()) {
return 'locales_source';
}
@@ -229,7 +229,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* @return array
* Array with key fields if the string has all keys, or empty array if not.
*/
protected function dbStringKeys($string) {
protected function dbStringKeys(StringInterface $string) {
if ($string->isSource()) {
$keys = array('lid');
}
@@ -285,6 +285,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* ones:
* - 'translation', Whether to include translation fields too. Defaults to
* FALSE.
*
* @return SelectQuery
* Query object with all the tables, fields and conditions.
*/
@@ -295,10 +296,6 @@ class StringDatabaseStorage implements StringStorageInterface {
$conditions['l10n_status'] = $conditions['customized'];
unset($conditions['customized']);
}
if (isset($options['customized'])) {
$options['l10n_status'] = $options['customized'];
unset($options['customized']);
}
// Start building the query with source table and check whether we need to
// join the target table too.
$query = db_select('locales_source', 's', $this->options)
@@ -326,7 +323,7 @@ class StringDatabaseStorage implements StringStorageInterface {
if (isset($conditions['language'])) {
// If we've got a language condition, we use it for the join.
$query->$join('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", array(
':langcode' => $conditions['language']
':langcode' => $conditions['language'],
));
unset($conditions['language']);
}
@@ -336,6 +333,8 @@ class StringDatabaseStorage implements StringStorageInterface {
}
if (!empty($options['translation'])) {
// We cannot just add all fields because 'lid' may get null values.
$query->addField('t', 'plid');
$query->addField('t', 'plural');
$query->addField('t', 'language');
$query->addField('t', 'translation');
$query->addField('t', 'l10n_status', 'customized');
@@ -399,7 +398,7 @@ class StringDatabaseStorage implements StringStorageInterface {
}
/**
* Createds a database record for a string object.
* Creates a database record for a string object.
*
* @param StringInterface $string
* The string object.
@@ -411,14 +410,15 @@ class StringDatabaseStorage implements StringStorageInterface {
* @throws StringStorageException
* If the string is not suitable for this storage, an exception ithrown.
*/
protected function dbStringInsert($string) {
protected function dbStringInsert(StringInterface $string) {
if ($string->isSource()) {
$string->setValues(array('context' => '', 'version' => 'none'), FALSE);
$fields = $string->getValues(array('source', 'context', 'version'));
$fields = $string->getValues(array('source', 'context', 'version', 'textgroup'));
// @todo Add support for D7 fields 'location' and 'textgroup'.
}
elseif ($string->isTranslation()) {
$string->setValues(array('customized' => 0), FALSE);
$fields = $string->getValues(array('lid', 'language', 'translation', 'customized'));
$fields = $string->getValues(array('lid', 'language', 'translation', 'plid', 'plural', 'customized'));
}
if (!empty($fields)) {
// Change field 'customized' into 'l10n_status'. This enables the Drupal 8
@@ -434,7 +434,7 @@ class StringDatabaseStorage implements StringStorageInterface {
}
else {
throw new StringStorageException(format_string('The string cannot be saved: @string', array(
'@string' => $string->getString()
'@string' => $string->getString(),
)));
}
}
@@ -452,7 +452,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* @throws StringStorageException
* If the string is not suitable for this storage, an exception is thrown.
*/
protected function dbStringUpdate($string) {
protected function dbStringUpdate(StringInterface $string) {
if ($string->isSource()) {
$values = $string->getValues(array('source', 'context', 'version'));
}
@@ -478,7 +478,7 @@ class StringDatabaseStorage implements StringStorageInterface {
}
else {
throw new StringStorageException(format_string('The string cannot be updated: @string', array(
'@string' => $string->getString()
'@string' => $string->getString(),
)));
}
}
@@ -494,7 +494,7 @@ class StringDatabaseStorage implements StringStorageInterface {
* @return DeleteQuery
* Returns a new DeleteQuery object for the active database.
*/
protected function dbDelete($table, $keys) {
protected function dbDelete($table, array $keys) {
$query = db_delete($table, $this->options);
// Change field 'customized' into 'l10n_status'. This enables the Drupal 8
// backported code to work with the Drupal 7 style database tables.
@@ -515,4 +515,5 @@ class StringDatabaseStorage implements StringStorageInterface {
protected function dbExecute($query, array $args = array()) {
return db_query($query, $args, $this->options);
}
}

View File

@@ -24,11 +24,30 @@ interface StringInterface {
* @param int $id
* The string identifier.
*
* @return LocaleString
* @return StringInterface
* The called object.
*/
public function setId($id);
/**
* Gets the parent string identifier.
*
* @return int
* The string identifier.
*/
public function getParentId();
/**
* Sets the parent string identifier.
*
* @param int $id
* The string identifier.
*
* @return StringInterface
* The called object.
*/
public function setParentId($id);
/**
* Gets the string version.
*
@@ -43,7 +62,7 @@ interface StringInterface {
* @param string $version
* Version identifier.
*
* @return LocaleString
* @return StringInterface
* The called object.
*/
public function setVersion($version);
@@ -62,31 +81,10 @@ interface StringInterface {
* @param string $string
* String to set as value.
*
* @return LocaleString
* @return StringInterface
* The called object.
*/
public function setString($string);
/**
* Splits string to work with plural values.
*
* @return array
* Array of strings that are plural variants.
*/
public function getPlurals();
/**
* Sets this string using array of plural values.
*
* Serializes plural variants in one string glued by L10N_UPDATE_PLURAL_DELIMITER.
*
* @param array $plurals
* Array of strings with plural variants.
*
* @return LocaleString
* The called object.
*/
public function setPlurals($plurals);
public function setString($string);
/**
* Gets the string storage.
@@ -102,10 +100,10 @@ interface StringInterface {
* @param StringStorageInterface $storage
* The storage to use for this string.
*
* @return LocaleString
* @return StringInterface
* The called object.
*/
public function setStorage($storage);
*/
public function setStorage(StringStorageInterface $storage);
/**
* Checks whether the object is not saved to storage yet.
@@ -135,11 +133,11 @@ interface StringInterface {
* Sets an array of values as object properties.
*
* @param array $values
* Array with values indexed by property name,
* Array with values indexed by property name.
* @param bool $override
* (optional) Whether to override already set fields, defaults to TRUE.
*
* @return LocaleString
* @return StringInterface
* The called object.
*/
public function setValues(array $values, $override = TRUE);
@@ -158,7 +156,7 @@ interface StringInterface {
/**
* Saves string object to storage.
*
* @return LocaleString
* @return StringInterface
* The called object.
*
* @throws StringStorageException
@@ -169,7 +167,7 @@ interface StringInterface {
/**
* Deletes string object from storage.
*
* @return LocaleString
* @return StringInterface
* The called object.
*
* @throws StringStorageException
@@ -177,4 +175,20 @@ interface StringInterface {
*/
public function delete();
/**
* Get the translation group of this translation.
*
* @return string
* The textgroup set for the current string
*/
public function getTextgroup();
/**
* Set the translation group of this translation.
*
* @param string $textgroup
* The text group to set for the given string.
*/
public function setTextgroup($textgroup);
}

View File

@@ -8,4 +8,4 @@
/**
* Defines an exception thrown when storage operations fail.
*/
class StringStorageException extends \Exception { }
class StringStorageException extends \Exception {}

View File

@@ -93,7 +93,7 @@ interface StringStorageInterface {
* @throws \StringStorageException
* In case of failures, an exception is thrown.
*/
public function save($string);
public function save(\StringInterface $string);
/**
* Delete string from storage.
@@ -107,7 +107,7 @@ interface StringStorageInterface {
* @throws \StringStorageException
* In case of failures, an exception is thrown.
*/
public function delete($string);
public function delete(\StringInterface $string);
/**
* Deletes source strings and translations using conditions.
@@ -115,7 +115,7 @@ interface StringStorageInterface {
* @param array $conditions
* Array with simple field conditions for source strings.
*/
public function deleteStrings($conditions);
public function deleteStrings(array $conditions);
/**
* Deletes translations using conditions.
@@ -123,7 +123,7 @@ interface StringStorageInterface {
* @param array $conditions
* Array with simple field conditions for string translations.
*/
public function deleteTranslations($conditions);
public function deleteTranslations(array $conditions);
/**
* Counts source strings.
@@ -162,4 +162,5 @@ interface StringStorageInterface {
* New string translation object.
*/
public function createTranslation($values = array());
}

View File

@@ -14,6 +14,7 @@
* in the specified language.
*/
class TranslationString extends StringBase {
/**
* The language code.
*
@@ -31,7 +32,7 @@ class TranslationString extends StringBase {
/**
* Integer indicating whether this string is customized.
*
* @var int
* @var integer
*/
public $customized;
@@ -78,7 +79,7 @@ class TranslationString extends StringBase {
/**
* Implements StringInterface::isTranslation().
*/
*/
public function isTranslation() {
return !empty($this->lid) && !empty($this->language) && isset($this->translation);
}

View File

@@ -12,7 +12,7 @@
*/
class TranslationsStreamWrapper extends DrupalLocalStreamWrapper {
/**
* Implements abstract public function getDirectoryPath()
* Implements abstract public function getDirectoryPath().
*/
public function getDirectoryPath() {
return variable_get('l10n_update_download_store', L10N_UPDATE_DEFAULT_TRANSLATION_PATH);
@@ -21,7 +21,8 @@ class TranslationsStreamWrapper extends DrupalLocalStreamWrapper {
/**
* Overrides getExternalUrl().
*/
function getExternalUrl() {
public function getExternalUrl() {
throw new Exception('PO files URL should not be public.');
}
}