Problem/Motivation
- Code is baked in to locale module. Drupal core has some support for parsing and generating Gettext Portable Object (.po) files. This functionality was improved with Drupal 7 to support text context, that was part of the spec but not implemented in Drupal before. However, the actual code that is used to process and generate Gettext files is so baked in, there is no practical way to reuse at all. You can only import all strings from a filename (tied together all through from opening the file to parsing and writing to the database); you can only export direct from the database for a HTTP header equipped download. Everything is vey tightly coupled.
- Duplicate code done with other modules As a consequence, contrib modules such as l10n_client, l10n_server, l10n_update and gettextapi need to duplicate this code.
- Parser is bound to fixed sources (memory, db) The current .po file parser for example takes modes like memory or database level storage and it has fixed callbacks invoked to store the data. It also takes a filename which it opens and reads itself. This makes it impossible to reuse, read in chunks, read from other sources, store at other places, etc. The above mentioned modules have examples of reworked versions of this API.
- It should be independent code Ultimately the gettext .po file parsing and generation code should be entirely independent of the locale module UI and/or database.
- Memory and runtime limits due to all in imports of possibly big files see #1637348: Import Gettext .po files in progressive batches to avoid time limits
Proposed resolution
Create a new Component Drupal/Component/Gettext
By introducing a generic Gettext component we get independent code. This will move gettext.inc functions into their new classes. The component must be capable of reading from/writing to *.po files, reading/writing to database, 'writing' to memory. Code involving reading and writing to the database is locale module specific, so those implementations should live with the locale module. More generic implementations for file parsing and generation and memory based loading (for the installer) should reside with the component.
Proposal is to have separate components for each direction (read, write) and each source type. This leads to:
- PoStreamReader
- PoStreamWriter
- PoDatabaseReader (implemented inside Drupal\locale\GetText, because it is locale database specific)
- PoDatabaseWriter (implemented inside Drupal\locale\GetText, because it is locale database specific)
- PoMemoryWriter
We can then chain a Reader to a Writer (core common implementations in Drupal\locale\GetText) to get a job done:
- PoStreamReader -> PoDatabaseWriter (importing a translation)
- PoStreamReader -> PoMemoryWriter (installing Drupal in ones own language)
- PoDatabaseReader -> PoStreamWriter (exporting a translation, creating a *.POT file)
The architectural overview of the interfaces and classes is proposed is the following:
This solves all the problems explained above except the memory/runtime limit issue. We have been working hard to solve that as part of this patch, but after 200+ comments and lots of existing work, we decided to move that to a followup at #1637348: Import Gettext .po files in progressive batches to avoid time limits.
Related issues
- #147915: Refactor locale import/export API to support non-local files and non-gettext formats (we make this possible in contrib)
- #361597: CRUD API for locale source and locale target strings (we are getting closer to this but not yet there, its a related problem)
Original report by Gábor Hojtsy
I've proposed this as a GSoC project at http://groups.drupal.org/node/138369 but nobody was interested. It is probably not interesting enough, but still needs to be done. Here is my existing writeup.
Drupal core has some support for parsing and generating Gettext Portable Object (.po) files. This functionality was improved with Drupal 7 to support text context, that was part of the spec but not implemented in Drupal before. However, the actual code that is used to process and generate Gettext files is so baked in, there is no practical way to reuse at all.
As a result, for example Translation template extractor and Localization server duplicate code for generating .po files themselves while Localization update and Localization server duplicate code to process .po files. While these implementations are more pluggable, there are already too many copies and the bigger problems are not solved. A major problem with .po file parsing is our one-pass approach, which bumps into memory and runtime limits on basic hosting. (That issue is being discussed at #569004: Add support for seek based batch import of .po files).
The current .po file parser for example takes modes like memory or database level storage and it has fixed callbacks invoked to store the data. It also takes a filename which it opens and reads itself. This makes it impossible to reuse, read in chunks, read from other sources, store at other places, etc. The above mentioned modules have examples of reworked versions of this API.
Ultimately the gettext .po file parsing and generation code should be entirely independent of the locale module UI and/or database.
Comment | File | Size | Author |
---|---|---|---|
#268 | 1189184-locale-oop-268.patch | 610 bytes | andypost |
#265 | locale-catch-265.patch | 1.29 KB | Kristen Pol |
#264 | locale-catch-264.patch | 1.3 KB | Kristen Pol |
#259 | locale-catch-259.patch | 1.28 KB | penyaskito |
#257 | locale-catch.patch | 1.18 KB | Gábor Hojtsy |
Comments
Comment #1
Gábor HojtsyRelated #147915: Refactor locale import/export API to support non-local files and non-gettext formats.
Comment #2
Gábor Hojtsy#361597: CRUD API for locale source and locale target strings is a requirement to make this work well.
Comment #3
Gábor Hojtsy#420510: Possibly misleading documentation/func naming for developers on locale.inc functions is not a duplicate clearly but makes a great point that the function naming and responsibility separation is broken. It is going to be resolved here and in #361597: CRUD API for locale source and locale target strings, so marked it duplicate.
Comment #4
Gábor HojtsyI'm hard at work on this as well as #361597: CRUD API for locale source and locale target strings at http://drupal.org/project/gettextapi for Drupal 7 so we can work out our solution in the wild, get a lot of real life use and then integrate into Drupal 8. The import refactoring is already very well ahead there.
Comment #5
Gábor HojtsyI've documented how this fits to overall Druapl 8 plans at http://groups.drupal.org/node/161589.
Comment #6
Gábor HojtsyPostponed on #1219236: Locale module includes 1350+ lines of unneeded code on all page loads.
Comment #7
Gábor HojtsyComment #8
Gábor Hojtsy#1219236: Locale module includes 1350+ lines of unneeded code on all page loads was committed to Drupal 8, so here is a quick stab at just taking the D7 gettextapi approach and applying it to current D8 core. You'll see that there are many callbacks and states passed around, so these are clear signs of possibilities to improve this much better with an OOP approach. Anyway, here is a direct port of the module to core for now to start this off. Lots to do here.
Comment #9
Gábor Hojtsy#8: incorporate-gettextapi.patch queued for re-testing.
Comment #10
Gábor Hojtsy#1260586: Consolidate .po file import to one directory touches the very same code and I consider that more important at the moment (also useful for installer usability improvements) and generally a gateway for starting integration work for l10n_update, so putting this one a bit on hold for now.
Comment #11
Gábor HojtsyAdding UI language translation tag.
Also marking postponed for now on ongoing tasks like #532512: Plural string storage is broken, editing UI is missing
Comment #12
Gábor HojtsyAdd interface language tag.
Comment #13
Gábor HojtsyRetitling, since gettextapi in contrib is all procedural but we'll obviously want to rework this to be all around buzzword compliant like PSR-0 named/placed, etc. We want to likely attack the export functionality first once #532512: Plural string storage is broken, editing UI is missing lands, since export is much easier to do. I've in fact started out working on this and have a rough version here... It will not work, but I started to minimize/modernize the code proper. The idea is that an instance of this would get a string iterator that would feed the export with strings and it would format the individual strings with its formatString(). This is just a start. Not even setting for review, since we need #532512: Plural string storage is broken, editing UI is missing to land first.
Comment #14
Sutharsan CreditAttribution: Sutharsan commentedFile format:
http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Fi...
http://docs.webtranslateit.com/file_formats/gettext_po/
A few gettext related classes to get inspiration from:
http://svn.automattic.com/wordpress-i18n/tools/trunk
http://pypi.python.org/pypi/Translate%20Toolkit (python)
Comment #15
Sutharsan CreditAttribution: Sutharsan commentedOne more gettext class:
http://codeigniter.com/wiki/Category:Internationalization::Gettext
Comment #16
Gábor HojtsyThe CodeIgniter code uses PHP's built-in gettext extension that is a no-go for Drupal (eg. it needs to kill the PHP processes to refresh the gettext info from the files last time I tried). Also I could not find actual .po parsing or generation code when skimming through the WP code.
Comment #17
Sutharsan CreditAttribution: Sutharsan commentedWordpress does generate po files: http://svn.automattic.com/wordpress-i18n/tools/trunk/makepot.php
Found another, Pear: http://pear.php.net/package/File_Gettext/
Comment #18
Sutharsan CreditAttribution: Sutharsan commentedformatString()
in #13 works fine, except it removes the trailing space from every string part. An additional parameter forwordwrap()
restores the space:Comment #19
Sutharsan CreditAttribution: Sutharsan commentedMy first wobbly steps in Drupal OOP. Be kind on me, but hard on the code ;) Added a translations database iterator to accompany to Gábor's (#13) Writer class.
I sure hope it is worth to use an iterator here because processing db records takes twice as much time as the usual db_query + foreach. Yes I see the benefits of seek based batch imports, but do we need all this flexibility when reading translations from the database?
The patch requires #532512: Plural string storage is broken, editing UI is missing.
Comment #20
Gábor HojtsyIs dbtng not providing us with ways to ask if we can continue to fetch? That is in itself iterator based, so I assume we can just ask, and that might mitigate most of the overhead.
Comment #21
Gábor HojtsyBtw patch looks good. #532512: Plural string storage is broken, editing UI is missing landed, so thtat unblock this issue. Yay!
Comment #22
Gábor HojtsyOn that iterator, in other words, if we define our API to expect objects like the ones we are getting from the query result, we can forego doing are own iterator and just depend on the query result iterator, which is already there. If we are fine with the data directly received from the query.
Comment #23
Gábor HojtsyRetitling for the export we are working on.
Comment #24
Sutharsan CreditAttribution: Sutharsan commentedOne more reference: Gettext and locale API project.
I've started to sketch out the code and expect to have some results in the following days. Just in time for the sprint ;)
Comment #25
Sutharsan CreditAttribution: Sutharsan commentedThe sketch code I'd like to share. It covers the procedural part of the gettext import/export handling, the batch processing and the required methods from a GettextData class. No executable code yet, but big steps. Leaving out all fault handling, exceptions and user experience. Next is to sketch out the Gettext class(es).
Comment #26
Sutharsan CreditAttribution: Sutharsan commentedThe patch contains:
I need review and advise on how to connect a (generic) data source/target to the reader/writer. And whether to use an abstract class, use an traversable or interator, use a steam wrapper.
Comment #27
Gábor HojtsyI started reviewing this as a patch, but it looks like would need more of a review as an "architecture", ie. do you have a drawing of how different components fit here? It looked like pretty well organized on a quick pass, but it would be great if I'd not need to recreate a figure on how it works, if you have one or can produce one quick :) Ie. the different classes introduced, and how they are related. I hope it should be simple to produce :) Thanks.
Comment #28
Sutharsan CreditAttribution: Sutharsan commentedA quick UML of the Writer + GettextInterface classes: https://skitch.com/erikstielstra/8csg9/gettext-uml.graffle
Comment #29
Gábor HojtsyPosting here so it is sure available later.
Comment #30
Gábor HojtsyOk, so the patch has GettextPoFile, GettextDatabase, etc. that are not reflected here. Also it has both import and export which is not reflected on this figure. Can you elaborate a bit on it?
Comment #31
Sutharsan CreditAttribution: Sutharsan commentedFor the architecture, you may ignore the gettext.sketch.inc file in the beginning of the patch. This was written before I started working on the classes. It should read
$file = new GettextFileInterface('public://test-1.po.txt');
Below you find a piece of testing code I used for the PoWrite class:For simplicity I only focused on the Write side. Architecturally the Read side should be similar. Write is an abstract class, PoWrite, DatabaseWrite are derived from that and handle the syntax specific Writing. Translations are transferred between Read and Write as an (translation) object. PoWrite recieves a translations object and passes a set of formatted strings to the data interface. But this is where my problems begin. I thought to use the stream wrapper interface for file handling. But could not make a smooth connection with it. In the patch the GettextFileInterface class uses the PublicStream. This should be replaced by a TranslationStream class which uses the translation directory instead of the files directory.
Comment #32
Sutharsan CreditAttribution: Sutharsan commentedReader and PoReader class added.
high level functions in gettext.sketch.inc modified to match the current architecture.
Comment #33
clemens.tolboomAttached is a tiny update of some classes + inclusion of a test-script + a naive Iterator example of a PoInfiniteProducer which never fails to produce yet another translation structure.
I'm still puzzled by the use-case of Stream versus Iterator. And waiting for fuhby's lexer :)
To test run
Next check the public file system for new files.
Comment #34
Sutharsan CreditAttribution: Sutharsan commentedI'll jump back on it when I can contribute.
Comment #35
clemens.tolboomJust some notes:
As we are now using symfony I checked their code. A simple parser: http://trac.symfony-project.org/ticket/9582 lead to inclusion into https://github.com/symfony/Translation/tree/master/Loader (unfortunately master).
Symfony PoDumper https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Tra... has some nifty escaping
Also the plural processing is nice: https://github.com/symfony/Translation/blob/master/PluralizationRules.php
Should we spent time on these?
Comment #36
Gábor Hojtsy@Clemens: all right, seems like we did not look hard enough in Symfony. Looking at their .po parsed code, it is definitely pretty simplistic, and does not cover many of our needs, such as being able to read a .po file in multiple HTTP requests. That does not mean we should do our stuff all from scratch. Question is if we can merge efforts somehow (and get them put their code on a release branch instead of it sitting on master only :).
Comment #37
clemens.tolboomIt looks like the Symfony implementation is not stream aware thus excluding it's use for us right now.
But the other bits (escaping + plural) could help us I guess.
I'm waiting for fuhby implementation of his stream PO parser to review (or match my thought against :p)
Comment #38
fubhy CreditAttribution: fubhy commentedThe entire symfony translator library looks really interesting and I think we could do many really awesome things with that. It basically covers most of what I talked to you, Gabor, so enthusiastically about during our sprint. Please take a couple of minutes to look at this https://github.com/symfony/Translation in general .... The Parser, Dumper, etc. in this library are indeed very simplistic and we are going to need more (and I already have more) but the other stuff there looks really sweet at a first glance.
I've got a lot of work to catch up with due to DCon and won't be able to finish this before the weekend. I am looking forward to digging even deeper into this... Sorry for the delay.
Comment #39
clemens.tolboomI'm more confused after reading #569004: Add support for seek based batch import of .po files and project http://drupal.org/project/gettextapi referred in that and this issue.
From @Sutharsan diagram and @fubhy intention to write a parser to _read_ .po files the title (and history) of this issue suggest something different: _write_ .po files.
Considering the Symfony way (Having a Dumper, Writer, Parser all in one Class tree) I still expect something similar in this patch.
So am I missing something important here?
(I'm still grasping StreamWrapper which are renamed through #1475020: Convert stream_wrappers.inc to PSR-0)
Comment #40
clemens.tolboomConcerning Symfony translation component:
Translation
- we cannot get access to the read entries so reading and then stuff items into the database is a nogo. The translation is done by
echo $translator->trans('Hello World!') . "\n";
.PoFileLoader is missing features we probably need:
- it cannot parse our files ... ours are missing a white-space before each entry (http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files). I checked ie drupal-7.11.ca.po and commerce_kickstart-7.x-1.3.da.po
- as documented by PoFileLoader::parse()
The following example is translation in action with a whitespace fixed po-file. And a prepared vendor tree with two added components:
My conclusion for now:
Comment #41
Gábor Hojtsy@Cleemns: I'm not aware of a requirement for whitespace between different source/translation pairs in .po files. The best description of .po file format from http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html says Entries begin with some optional white space. Usually, when generated through GNU gettext tools, there is exactly one blank line between entries.. So the GNU gettext tools add a blank line, but this is entirely optional.
Comment #42
clemens.tolboomAfter puzzling a lot how to manage state (and streams work) I want to propose to build the following together with fuhby:
1. BatchStreamManager class
- This manage any Stream for read/write operation.
- Knows how to recover a stream for the next batch op.
2. POStreamHandler class
- Implements get/setHeader to read or write the PO Header
- read/write PO items
- Uses the stream managed by BatchStreamManager
3. POItem class
4. POHeader class
An small code example would look like the following.
next batch iteration
For the DB side of this issue we should have an abstraction for reading/writing POItems to the database as well.
For this to work POStreamProcessor must set the seek position to the end of the last read item and not just read chunks of bytes.
What we gain is:
@fubhy: What do you think of this decoupling? You need to provide for POItem and POHeader (sorry about that :p)
Comment #43
Gábor HojtsyOk, that looks like way over the abstraction level I've ever thought of. Question is if we need/want that level of abstraction or it is going to kill this issue because of no agreement on the various abstractions :) if we can get this defined relatively soon and well, and then get it done, that would be great. I'd hate if we over-plan it and then die in the implementation :)
Comment #44
Sutharsan CreditAttribution: Sutharsan commentedI agree on the separation between stream interface and po lexer/generator. The stream object could be swapped for a database interface when translations come from the database, and the po generator can be swapped for a pot generator when we download a translation template. But I doubt the usefulness of a header and a po object.
The po header is almost empty. The plural formula is the only valuable part. The rest of the po header consist of static data and the header properties are not used in our context.
I have thought about a po object too. It can be usefull as a definition of translation data, but I can't think of any methods in this object. It is just transferred from the reader to the writer. Thats all. Further I have concerns about the performance impact of instantiating this object thousends of times.
Comment #45
andypostDon't forget about number of plurals
Comment #46
clemens.tolboomRereading #42 - #45 and trying to build the BatchStreamManager I think we can do it with just a new Interface and follow the original thoughts of @Sutharsan having a POReader / POWriter as having a POProcessor would require different state management.
Thus a StreamStateInterface allowing for a POReader / POWriter to implement.
Each POReader / POWriter implements StreamStateInterface and are capable to open a Stream by using
fubhy can now build this POReader and the Batch can set the state cleanly.
This seems way cleaner then #42 or #29
What do you think?
Comment #47
Sutharsan CreditAttribution: Sutharsan commented@clemens, your proposal looks good. Indeed more straight forward that our earlier ideas. Remember that besides POReader and POWriter we need and a DBReader and DBWriter. Readers can have the same base class or interface and the Writers likewise.
Comment #48
fubhy CreditAttribution: fubhy commentedSorry for disappearing from this issue for so long... Coming back from Denver I found an overwhelming amount of work on my desk and it took all of my focus to get that stuff over with as soon as possible. Anyways, here are my conclusions and opinions from the last couple of comments on this issue:
Even if this might be obvious: Let's first clarify what "Reading" / "Writing" / "Parsing" means.
Reading: Reading means (in my mind): "Find a msgid in the database / file (in general "source") to identify the respective translated strings". This is more like a "query" behavior (query for a specific condition "msgid" or even something else) to retrieve a subset of the available translated strings from whatever source we are querying. In case of normal t() invocations this would be a query for a "msgid" for example with just one return value.
In a more complex scenario (and if we had that data available in the database) we could also query for the context of a translated string or whatever else might be of interest. Consequently "Reading" is, by default, not a line-by-line reading ("batchable") process. It is really more like a single query (I believe that this is very important).
Hypothetically speaking "reading" from a .po file (querying) could, in a custom environment, replace the currently used db query for t() invocations and instead directly query for specific msgid's from a .po file (really just hypothetically speaking). So in order to make the Interface very solid and clean the "read" operation should just provide a "query for one, return one" functionality.
Parsing: This is basically the same as "reading" but doesn't have a conditional query component. It is a plain iterational procedure where we extract one "Gettext 'node' object" after the other from the data source until it is depleated (EOF is reached or all database record have been returned).
When parsing a .po file (exporting from a .po file) or exporting from the database we could have a special case operation where we don't query / read for a specific msgid but instead repeatedly ask for the next "Gettext 'node' object" in the source (file stream vs. db connection). This operation relies on an internal pointer in the data source (record id in the database vs. current file pointer / position in a file stream). This operation is batchable!
So let's please make a distinction between "reading" and "parsing" :).
Looking at the bigger picture we can probably get to a point where importing / exporting easily works both ways (export from .po file => import into database // export from database => import into .po file).
If you ask me we dont even need two separate classes for reading / writing (the source & destination are the same (db <=> db / .po file <=> .po file) and both operate on that one source (file stream vs. database connection). So why make a disctinction? Just because the "direction" of the operations are different (get vs. set)? So.. Let's get to the "writing"
Writing: This is pretty obvious. Either write a "Gettext 'node' object" to a .po file or create a record for it in the database.
While "exporting" is a repeated "read" operation "importing" basically is a repeated "write" operation.
Practically speaking this is what we could do:
On a side note: I think the title of this issue is indeed slightly outdated if we start to discuss complex proposals like the stuff we have been discussing in the last couple of replies. We should either rename the title of this issue or split this discussion into multiple issues (although the whole architecture [as I would like to see it] is so tightly integrated with each other that we cant really separate it if we really want to build it like this [yes, lets do it!]). :)
Comment #49
Sutharsan CreditAttribution: Sutharsan commentedLooks to me that we all have the same architecture in mind now. A source interface class for database or po file and a reader/parser/writer which works with the source to move data in and out the source interface.
I have no problem with combining the read and the write functionality into one class, theoretically it would be sane. It is that I ran into difficulties when building the class that I decided to split it. Also I saw no use case where we need both reading and writing in the same context. But if you manage to get the two into one without too much hassle, by all means go ahead.
But I have serious concerns of using the gettext classes for t(). t() should be light weight. Using a gettext interface class is theoretically correct and may therefore be preferable. But we risk performance as t() is called very often. If any I would give it the lowest priority in the development.
Time for code.
Comment #50
Gábor HojtsyAny progress on this? It has been a week since the last comment. :/ How can we make this going faster. It was not intended to be such a huge task, so we can scale it back if you are lost in the maze.
Comment #51
clemens.tolboomWell for one this is not trivial :p
To run this from drupal root.
I did some more testing on drupal-7.11.ca.po file which is now partly parse by POReader in a crappy way.
Things to fix are:
- it does not stop reading.
- some plural lines are wrong parsed .. see TODO in POReader (set breakpoint in saveOneString on ksort line)
- the header is now an array ... I really like to have the full header structure
- POReader::readLine() has state related variables lying around. These must be defined in the class header.
- GettextFileInterface is opening a public stream ... this should not be its responsabiliy ... it should only manage a stream. We can test for is_local when assigning it a stream.
This to refactor/implement
- state management
- class structure
Comment #52
clemens.tolboomFailures from the drupal-7.11.ca.po file.
Comment #53
clemens.tolboomI fixed the parser for multi-line plural source lines as that was the problem dumped in #52 and mentioned in #51. I'm puzzled whether the parsing code was that buggy?!? Should we report that elsewhere?
The command now produces a nice dump of public://test.po.txt which was a copy of drupal-7.11.ca.po ... I'd like to test for more complex po files.
seems to work with code like this
so we can use this through a batch as the context+state variabled are now stored outside the PoReader::read() method. This needs some cleanup.
The code must now get converted to something mentioned in #42.
Comment #54
clemens.tolboomFor our db read/writer we need to read an item
(Locale module, line 520):
Or the full monty
Writing a translation to DB (locales.pages.inc):
Write the full monty
Nice
Thanks @Sutharsan
Comment #55
Sutharsan CreditAttribution: Sutharsan commented@clemens,
You worked from my quick and dirty migration of
_locale_import_read_po()
. You should compare your findings with that code.Comment #56
clemens.tolboom@Sutharsan I worked from your version in POReader.
"that buggy" was to hard. Sorry for that. But I had to fix it's ending somehow. I'll check for the mentioned function later on.
Can you add some PO files to the issue summary with known(?) issues or with complex plural forms.
Attached patch is a little improved version. But it still has some issues. It introduces a POItem and POHeader class as I think that's the interface we should deal with. (if garbage collections is an issue we can refactor into a pool of unused objects)
But one benefit is we can now do
I don't like the names POHeader / POItem so better names are welcome.
I hope to get a Writer in place tomorrow and a new UML diagram. Next refactor into that model.
Just run
php core/lib/Drupal/Core/Gettext/testGettext.php
from drupal root.Comment #57
Sutharsan CreditAttribution: Sutharsan commented@clemens, This will keep you busy ;)
Drupal core 7.11, Arabic
Drupal core 7.11, Russian
Drupal core 7.11, Croatian
Comment #58
Sutharsan CreditAttribution: Sutharsan commentedTested with Arabic and Russian, the strings '1 hour' and '1 day'. The plural string are presented in the right order and all translations in l.d.o are present in the parsed po data. For reference: '1 day' in Arabic at l.d.o and '1 day' in Russian at l.d.o
Comment #58.0
clemens.tolboomAdd parent
Comment #59
clemens.tolboomRunning the test script I now manage to import ar, ca, nl from the commandline :)
What it does is Remotely download and write these to public:// next read from public:// and write to Db
I moved around a lot of code snippets from @Sutharsan effort ... not sure whether I missed ... guess I did :(
I created new classes POHeader and POItem and moved code into these clases.
This still needs a lot of work:
Comment #60
clemens.tolboomThis seems not to work.
Calling getState() after some reading shows the lid increasing but it is not set for the next 'batch'
(I cannot find a test in testGettext.php .. darn.
Comment #61
Sutharsan CreditAttribution: Sutharsan commentedDo we need to read the DB in batches? Batch handling was introduced to cope with performance bottlenecks and unusual situations like installing Drupal. Does this apply to DB'es? Also the po export to file is no bottleneck, although I don't know about requirements for export at l.d.o. As far as I can see there is no need for batch handling the db read and file write.
Comment #62
Gábor Hojtsy@Sutharsan: re #61, you are right.
Comment #63
clemens.tolboom@Sutharsan I'm not sure what you mean:
- this issue is about making gettext abstract thus PODbReader should follow an interface. But this does not mean PODbWriter can not finish it's job in one go.
- In #39 I said I was confused about #569004: Add support for seek based batch import of .po files. That why I want you on the phone :)
- Having POFileReader batch aware means PODbWriter must be batch aware too. Ie whether or not writing the header or zapping all db entries. I guess we don't have these features now but shouldn't we?
- The other way around PODbReader + POFileWriter one could argue we don't need this batch but that would make the design asymmetric making PODbReader special which I don't like.
The -1 below is about writing ALL to whichever writer.
and the result from a db_select->execute() below is an Iterator too.
Would it better be adding readItems()?
Regarding Symfony Translation (not for this issue but the near future):
- Do we need it's rich file format support like .mo .csv .xliff to name a few?
- I intend to contribute our POFileParsing POFileLoader
- Should we adhere to their naming: Dumper / Loader
- As Symfony lacks a Batch (afaik) right now I (maybe) want to start a feature request over there.
Get @Sutharsan on the Phone :p
(to be continued)
Comment #64
clemens.tolboomAttached patch fixed the get/setState of PODBReader mentioned in #59 and makes
download from http:// to public:// into database next out into a new public://
I'll try to:
- get rid of gettext.inc
- have tests Unit + Web TestCases
- add UML diagram.
- ?
Comment #65
Gábor HojtsyWoot, woot, this is progressing great.
Comment #65.0
Gábor HojtsyUpdated issue summary.
Comment #66
clemens.tolboomI talked with @Sutharsan about the context of this issue and that helped much :)
Note to self: read #48 and update issue summary.
Attached patch is only for the testbot ... to see what more I missed :p Strategy I choose for now is to rewrite gettext.inc gradually as @Sutharsan sketched in #32.
This patch only has
rewritten. It imported nicely the nl-po file. But the rewrite needs a lot of header related fixes.
It showed me we have also a POMemoryReader|Writer sort of.
Comment #67
clemens.tolboomComment #68
andypostI think we need to leave ability for batch import like #569004: Add support for seek based batch import of .po files
Comment #69
clemens.tolboom@andypost ? ... this issue has (in theory) batch support.
next batch
But I first want to make the testbot happy.
Comment #69.0
clemens.tolboomAdded all functions from gettext.inc
Comment #70
clemens.tolboomNot all import errors are fixed.
- I'm puzzled with why importing a French .po should change the Plural-forms? Plural numbers changed. locale.test 1011
- How should this work : Language file automatically imported. locale.test 1087
- Other 2 errs are prob related to the above?
More gettext.inc functions are moved. See issue summary for details.
Next steps are:
PO Exports : Fix test errors to begin with.
POMemoryWriter (?+ POMemoryReader) : To obsolete
function _locale_import_read_po()
Note: the PoDbWriter relates to #851362: Add hash column to {locales_source} to query faster locale strings
Comment #71
clemens.tolboomStill lots of work.
Comment #72
clemens.tolboomThat's weird. On my laptop I have when testing throught UI I get only failures related to 'Translation import'.
From the testbot log
Any idea?
Comment #73
clemens.tolboom#70: 1189184-gettext-parsing-70.patch queued for re-testing.
Comment #75
Gábor HojtsyClemens: if an overwrite mode was selected, new plural forms should overwrite old plural forms.
Comment #76
clemens.tolboomI added #1497230: Use Dependency Injection to handle object definitions to the patch from #70 as the test definitely will not work.
I refactored a lot by adding
- Interfaces: PoInterface, PoStreamInterface, PoReaderInterface, PoWriterInterface
- Class : POMemoryWriter
- Cleaned gettext.inc more
I changed locale.bulk.inc to use _locale_import_po straightaway ... I hope understood the batch intention enough.
Changed install.inc to use
_locale_files_to_memory()
as an initial test. But where is that tests?This still needs lots of work.
I intend to do much more but it takes time :(
Let's see what the testbot thinks now.
Comment #77
clemens.tolboomComment #78
clemens.tolboomHmmm ... I ran the tests locally on Mac OSX
- 17005 passes, 18 fails, 2 exceptions, and 3681 debug messages
Page cache test
Enable the page cache and test it with various HTTP requests.
73 passes, 6 fails, 2 exceptions, and 19 debug messages
drupal_render()
Performs functional tests on drupal_render().
50 passes, 2 fails, 0 exceptions, and 14 debug messages
Image dimensions
Tests that images have correct dimensions when styled.
47 passes, 9 fails, 0 exceptions, and 8 debug messages
Language dependency injection
Compares the default language from $GLOBALS against the dependency injected language object.
17 passes, 1 fail, and 0 exceptions
Testbot reports (from #76 )
- 35,271 pass(es), 64 fail(s), and 3 exception(s)
ExpandPlural handling (LocalePluralFormatTest) [Locale] 73 39 0
ExpandTranslation export (LocaleExportFunctionalTest) [Locale] 43 2 0
ExpandTranslation import (LocaleImportFunctionalTest) [Locale] 106 23 3
This is too weird for me ... I zap my drupal install then start all over with the patch from #76 .
Comment #79
clemens.tolboomCan someone please test the patch locally? I suspect something messing with this new Classes.
This patch fixes the installer ... just did an Afrikaans installation with the PoMemoryWriter :-)
The POFileReader had some bugs too with plural which are hopefully fixed now too.
What bothers me still are the exceptions from the testbot.
Comment #80
clemens.tolboom(sorry)
Comment #81
clemens.tolboomComment #82
clemens.tolboom[edit]
Test bot missed #79I missed browser refresh :/ [/edit]
Comment #83
clemens.tolboomRunning locally (output shortened)
As suggested by @Gábor Hojtsy on irc i should solve the local problems first as the testbot could be picky about NOTICES and others.
Comment #84
clemens.tolboomWow ... some subtle changes were needed.
The order of setters is imported for parsing the header. On could say the design of PODbWriter is bad. But this is necessary for the batch interface. We cannot have constructors with arguments as the next batch does not know how to recreate the object right?
Next the Plural-Forms was empty when writing a POHeader. Fixed that.
This was tricky ... the $langcode is an array ... not sure why other tests did not fail.
Lastly I reordered the 'Plural number changed' to match the po upload better. There was a unrelated drupalPost in between.
Comment #86
clemens.tolboomAttached current UML.
Note the three main Interfaces: BatchState, POReader|Writer, POStream
What is missing is a POMemoryReader. I haven't found a usecase for it. POMemoryWriter has a getData method which breaks symmetry.
I haven't got time to implement the batch due to the fails _ALL_ of the testbot. I suspect the testsuite not to find the new Gettext components somehow.
Comment #87
clemens.tolboomFrom irc ([edit:with some additions])
So need to
Comment #88
clemens.tolboomSome related issues:
#1337628: Enhance language select form with textbox and other tools
#568986: Dynamically update standard language list from localization server
Comment #89
jthorson CreditAttribution: jthorson commentedUnable to troubleshoot tonight, as my manual bot is running into APC errors ... if you could open an issue in the https://drupal.org/project/issues/testbot queue, that will help remind me to come back and re-visit this once I've got it behaving again.
Comment #90
clemens.tolboomI created #1548366: Locale related Exception in Review log of test. as requested by @jthorson
http://drupal.org/project/testbot states testbot runs with clean url turned off so when testing locally one should test without clean url too.
In #1548366: Locale related Exception in Review log of test. I added a comment #1539072: Support for disabled languages broken, drop it has the same exception.
I have (now) no time to run the full test-suite as that takes ages (it ran for 4+ hours :/ )... will do after May 5th.
Attached patch has some documentation added.
Comment #91
clemens.tolboomWhy I think the classloader could be causing this err is when developing and debugging with Netbeans the classloader does not load the file.
which assigned nada (NULL, FALSE?) to my $reader = new PoFileReader(); when not properly declared. I have to retry that after May 5th.
Comment #92.0
(not verified) CreditAttribution: commentedUpdated the gettext.inc function moves.
Comment #93
sunPlease make sure that all your namespaces and classes are using the same and sane letter-casing.
Some classes/namespaces in this patch are using "PO" while some others are using "Po".
PSR-0 is case-sensitive. Only use "Po" everywhere.
Comment #94
jthorson CreditAttribution: jthorson commentedYup ... the PDO Exception is a red herring, introduced by http://drupal.org/node/1497230 (and present in all D8 tests ever since, despite them passing).
Comment #95
Sutharsan CreditAttribution: Sutharsan commentedPatch modified to use "Po" everywhere as suggested by sun.
Comment #96
sunThanks - #95 passed the testbot now.
The patch still contains plenty of notes and @todos, is missing comments, phpDoc, etc and thus, overall doesn't seem to be ready for reviews yet.
However, some early feedback:
1) That looks like a crazy level of abstraction... I'd rather expect:
Gettext\DatabaseController
Gettext\FileController
Gettext\MemoryController
but if that level of abstraction is required, I'll let you guys roll...
2) Even when not using controllers but individual reader/writer classes, the class names could be simplified. They also should not contain abbreviations ("Db" vs. "Database").
Comment #97
clemens.tolboomJust a short reply @sun about class names.
I'm looking @ http://symfony.com/doc/current/book/translation.html and esp. https://github.com/symfony/symfony/tree/master/src/Symfony/Component/Tra... their implementation where there are Loaders and Dumpers.
I like the design of Symfony but still don't get their whole picture regarding translation.
@sun: I can install drupal in ie af / ar etc through the PoMemoryWriter but I'm not sure whether we test this. Do you have some hints?
@others : Should we target using Symfony translation framework? What impact could that have on our way of handling translations? See links mentioned above.
Comment #98
sunOh, wow. I wasn't aware of the Translation component in Symfony. I quickly glanced through it and couldn't find anything that would look problematic.
Seems to revolve around reading and writing gettext strings in various formats (storage is separate), and also translating strings at runtime (with plural support, though hard-coded plural rules). I don't think we have any intention to change our runtime translation t() for D8, but I wonder whether we could only leverage the reader and writer parts of it?
If we want to explore that, we might want to create a parallel issue to this (so this one isn't hi-jacked in case it doesn't work out).
Comment #99
Gábor Hojtsy@sun: there is some discussion about the Symfony components for .po reading above. The main issue as I've gathered it was that they did not support chunked reading (so you could import a huge file without your memory being blown away).
Comment #100
clemens.tolboomWhy is patch from #95 pass tests now. Is my local env doing different?
I couldn't apply patch from #95 due to one line in gettext.inc concerning menu_router_rebuild() (committed May 3) ... renaming files in a patch made some more work too for comparing changes. How should one take care of that when working on issue branch?
(so this patch is just to make sure testbot does not fail again)
Comment #101
clemens.tolboomComment #102
clemens.tolboomI just did an symfony patch to see how our parser behaves in their environment. See https://github.com/symfony/symfony/pull/4235
Some notes:
Regarding PoItem + PoHeader these classes are nicer then just arrays but they are tied to the Gettext interface / file format and thus cluttering the PoDbWriter. I think we should talk about 'LC_MESSAGES' instead.
Symfony uses a message structure between all their loaders. I was bothered by the fact all our Classes needed to know what a POHeader/POItem is which felt bad.
We should define a datastructure and document that. PoMemoryWriter somehow uses one.
Symfony uses
I'll create a new issue regarding symfony the moment that pull request is pushed to their master. And thus try to stop talking about symfony within this issue :p
Comment #103
clemens.tolboomFrom our office hours @irc #drupal-i18n http://groups.drupal.org/node/229008 :
We could try to write a StreamWrapper mimicking multiple files served one by one on each batch iteration to the symfony Translation\PoFileLoader component. That sounds like a nice solution.
But for this to work we need to adhere to symfony's message structure (see #102) ... I don't like the '|' separator used by symfony so we need to convince them to use our LOCALE_PLURAL_DELIMITER.
Symfony's plural handling http://symfony.com/doc/current/book/translation.html
construct is lacking our http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/format_... options.
I need to chew on this a little.
Comment #104
sunDo the trans() and transChoice() methods matter at all?
We're not going to replace our actual t() string translation with Symfony (yet). The idea is to merely leverage the Translation component for gettext import/export/parsing operations.
EDIT: That said, I'd still recommend to create a new issue for the Symfony based approach. 'cos if that doesn't work out, this issue won't be totally hi-jacked.
Comment #105
clemens.tolboom@sun Agreed
I start working on #1570346: Let Symfony Translation component handle language messages from now to see how that could work for Drupal.
This issue is now postponed in favor off #1570346: Let Symfony Translation component handle language messages.
Comment #106
Gábor HojtsyThis is in practice duplicate of #1570346: Let Symfony Translation component handle language messages. Should be reopened if that one is not feasible. Moving off sprint.
Comment #107
clemens.tolboomAs #1570346: Let Symfony Translation component handle language messages is now closed as it was to farfetched to implement within Symfony framework yet.
As I understood from @Sutharsan by a phone call he is sort of blocked by this issue as there is no API to code against. So the issue title does not match that goal either.
(I'll try to re-roll if needed the patch and get familiar with this issue before the sprint.)
Comment #108
Gábor HojtsyI don't understand what would Sutharsan be blocked about in regards to this issue, that would be good to know.
I think to successfully move forward with this patch, we should get this down to a level of abstraction that is not over the top (see Sun's comments) Can we simplify this based on what you learned in Symfony. What we have in D7 is no API, what this patch proposes seems like a very convoluted set of classes and interfaces. Is there a good middle ground?
Comment #109
clemens.tolboomThis patch needs a controller which stored translations in memory (with a batch interface?!?)
We should not name it Gettext or something but rather MessageCatalogController using a MessageCatalog (aka Symfony). I'm not sure about this but let's make the controller our new API.
The controller can then load/dump the messages into:
- load from file (*.po)
- dump to memory for the installer
- load from db
- dump to cache (weird thing)
- dump to file (*.po)
Needs feedback!
Comment #110
Gábor Hojtsy@Clemens: in earlier Drupal major releases, we found that loading in a whole .po file to memory is huge and might not fit under limits. Now that sounds like a good possibility again, especially if you want to represent components with the above documented wrapper classes (PoHeader, PoItem). So I'm not sure everything should evolve around an all-in-memory storage system.
Comment #111
clemens.tolboom@Gábor Hojtsy
The memory constraint puzzles me:
- Is ie install.nl.po supposed to be small? That would mean we get the Symfony domain 'problem'.
- As this is not about gettext msgctxt but a separate PO file (Symfony calls it domain) for the installer?
- Is http://localize.drupal.org taking care of that in some way?
- How should the message extract work?
You have a good point about PoItem if object memory is much bigger then an array.
Comment #112
Gábor Hojtsy@Clemens: your comment made it sound like you want to base *everything* on a memory storage based solution, which is what I commented on. If that was not the case, maybe I misunderstood your proposal.
Comment #113
clemens.tolboom#100: 1189184-gettext-parsing-100.patch queued for re-testing.
Comment #115
clemens.tolboom@Gábor Hojtsy could you please give some feedback on the installer questions from #111 ... guess you missed it as we commented within the minute :)
Note to self
... cannot merge with head
... not sure what git tries to tell here.
See #100
Comment #116
clemens.tolboomJust a rebase patch to feed the bot
Comment #117
clemens.tolboomComment #118
clemens.tolboomI've reread the whole issue and noted a lot of issues for this issue.
- the issue summary sucks
- a lot of comment from others are not addressed
- some question I asked are not answered.
So these thinks needs to be taken care of before moving this forward.
This issue was postponed May 10 #105 so I need to learn it again :(
So my battleplan for today is:
- read the code and hopefully fix the tests (morning).
- summarize all open comments and questions (afternoon).
Comment #119
clemens.tolboomThere was an old
menu_rebuild()
... so testbot be nice :)Comment #121
Gábor HojtsyThis is being worked on at http://drupalcode.org/sandbox/goba/1624820.git/shortlog/refs/heads/gette... in a sandbox branch for anybody who wants to follow the progress close.
Comment #121.0
Gábor HojtsyUpdated issue summary.
Comment #122
penyaskitoChanged summary for pointing out that downloading the translations is required on installing.
Comment #123
clemens.tolboomThe patch removed nplural knowledge from POItem which took me too much time to discover.
It used variable_get to iterate over its translation which is so against Separation of concern.
We must make sure somewhere higher up the chain POItem contains the correct data.
Thanks @penyaskito for your help :)
Comment #123.0
clemens.tolboomDownload install po files before installing the site on testing section
Comment #124
clemens.tolboomI've updated the issue summary to a v0.2 (that means more to come)
Comment #125
penyaskitoChanged POHeader and POItem to PoHeader and PoItem for consistency. Let's see if it's already green.
Comment #127
penyaskitoDon't panic, I think that I used wrong revisions when creating the patch.
Comment #129
penyaskitoThis is the last attempt, if it fails I get back to @clemens.tolboom tomorrow.
Comment #130
penyaskitoFeed the testbot.
Comment #131
penyaskitoRemoved the references to PoWriter, that was renamed to PoWriterInterface.
Comment #132
penyaskitoPer the quotes at
, looking that Symfony uses Loader and Dumper (#1189184-35: OOP & PSR-0-ify gettext .po file parsing and generation by @clemens.tolboom) and the terminology that @fubhy explains at #1189184-48: OOP & PSR-0-ify gettext .po file parsing and generation, maybe we should consider replacing the suffixes Writer and Reader to Loader and Dumper. Eventually, we could split Loader in Loader and Reader for sequential loads if needed.
Comment #133
penyaskitoFeeding the testbot. Added Gettext class used by the installer by Clemens and some refactoring done by Clemens and me.
Comment #134
clemens.tolboom(notes)
When we start working on the Batch interface we could try to do it for testing manually
- install_import_translations which uses "locale_translate_batch_import"
This code below is probably obsolete? (related to: Why are files imported twice?)
as install_import_translations_remaining does something similar.
But for debugging we can better use the UI interface for importing.
Comment #134.0
clemens.tolboom(v0.2) A rewrite with problems mapped to solutions.
Comment #134.1
clemens.tolboomDeleted code snippets which cluttered the text.
Comment #134.2
clemens.tolboomSome layout improvements
Comment #135
clemens.tolboomI updated the issue summary a little:
- removed irrelevant code snippets
- changed some styling
- added BatchStateInterface interface (does it help?!?)
Comment #135.0
clemens.tolboomRephrased BatchStateInterface a little (not sure whether that helps)
Comment #136
clemens.tolboomI'm not sure the Batch interpretation currently done is what we need:
- Say we have 10 *.po files to load by a module x
- Now each .po file should be loaded into smaller chunks say 5
The module does not care the files are loaded in batches and we don't care about multiple files.
That doesn't sound to good. So any help is welcome. What should we do?
Comment #137
Gábor Hojtsy@clemens.tolboom: I think the original idea and AFAIR in the contrib gettextapi module that was done to prototype this in D7 you get one batch item for each file. Then the batch items themselves can be progressive, so you can return from a batch item and ask for it to be rerun, at which point you get back to the same batch task with an updated batch sandbox. You can use the sandbox to store the batch state per file. See the gettextapi project in contrib.
Comment #138
attiks CreditAttribution: attiks commentedSummary of my talk with Clemens in random order:
Don't export if there's nothing to exportShow message if import succeededComment #139
attiks CreditAttribution: attiks commented#1630524: Don't create a .po file if it's empty
Comment #140
clemens.tolboom@atttiks thanks for the summary.
1. The BOM / Byte Order Marker is copy/paste code. (for me for now: won't fix :/)
2. I hope today with @attiks and @penyaskito to remove all export function. And hopefully the _locale_import_po too. Then it _is_ empty :)
To make that work we need a way to get 'rid' of the drupal_set_message stuff. Yesterday I tried to create a Gettext::fileToDatabase() to discover the caller needs both the PoFileReader (for failures on reading) as PoDatabaseWriter (for failure and statistics). So we should discuss this a little with the three of us.
3. Did we talk about that? Is this solved now?
4. See the statistics from 2
Your last patch is empty. Have you asked @Gábor Hojtsy for git access?
Comment #141
attiks CreditAttribution: attiks commented1/ see #1630568: Validate that uploaded .po files are UTF8
2/ todo
3/ fixed
4/ is a temp fix, will have a look
Comment #142
attiks CreditAttribution: attiks commentedtrying to import the same po file twice:
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'temporary://modules-block.nl_.po' for key 'uri': INSERT INTO {file_managed} (fid, uid, filename, uri, langcode, filemime, filesize, status, timestamp) VALUES (default, :db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7); Array ( [:db_insert_placeholder_0] => 1 [:db_insert_placeholder_1] => modules-block.nl_.po [:db_insert_placeholder_2] => temporary://modules-block.nl_.po [:db_insert_placeholder_3] => und [:db_insert_placeholder_4] => application/octet-stream [:db_insert_placeholder_5] => 15250 [:db_insert_placeholder_6] => 0 [:db_insert_placeholder_7] => 1339578176 ) in drupal_write_record() (line 483 of /var/aegir/platforms/i18n/core/includes/schema.inc).
Comment #143
attiks CreditAttribution: attiks commentedignore #142, file permission problem
Comment #144
clemens.tolboomRemove hasResults from PoDbReader as 'emptiness' is a business rule like
[edit] Think of PoFile|Database|Memory as Iterators which 'just' dry out.
Comment #145
clemens.tolboomMy idea for the batch is adding the following to Gettext.php
Comment #146
attiks CreditAttribution: attiks commentedClemens: the current batch is working, why do you want to change it?
Comment #147
clemens.tolboomThings to check for are:
What _is_ the new API
I somehow expect to have a single point in the code with a factory method to produce a reader or writer.
Issues named in this issue
- #1 #147915: Refactor locale import/export API to support non-local files and non-gettext formats (non-gettext formats) (we can load from remote)
- #2 #361597: CRUD API for locale source and locale target strings (crud would be cool especially when save multiple at once aka $writer->writeItems())
- #3 #420510: Possibly misleading documentation/func naming for developers on locale.inc functions (we have still a documentation problem over here)
- #6 #1219236: Locale module includes 1350+ lines of unneeded code on all page loads
- #21 #532512: Plural string storage is broken, editing UI is missing (I haven't seen that interface)
Possible design and bugs
- #18 Do we have a test for multilines
- #55 Our parser is from a refactoring try. We should check with the current code version.
- #69 Batch support is underway.
- Code is now located in code/lib/Drupal/Core but it should be in core/lib/Drupal/Component I guess
That's it for now.
Comment #147.0
clemens.tolboomFixed into {language}
Comment #148
penyaskitoLet's see some green here in the meantime.
Comment #149
penyaskitoOne thing that bothers me is that for exporting a PO/POT file we are now creating the physical file on the server and then reading and flushing it to the client.
Should we implement a PoStringWriter for this instead?
Comment #150
clemens.tolboom@penyaskito #149 that's performance related a good idea.
But why don't we do a redirect to the file written that is use a public:// file? Then it's up to apache to serve it.
Comment #151
penyaskitoOk, seems that having all the string in memory is not a good idea. We can continue the clean up and consider that later if needed.
Comment #152
penyaskitoSaving the file in public:// doesn't look good to me, it could be using disk space that can be restricted in some environments, and the file will always be regenerated. But the way, you reminded me that we should delete it once it is downloaded, I will commit this to the sandbox.
Comment #153
attiks CreditAttribution: attiks commentedtests added for multiline and allowed/blocked tags
Comment #154
attiks CreditAttribution: attiks commentedComment #155
penyaskitoI started the refactoring _locale_import_one_string_db. We need to get rid of the dependency from Gettext to locale module.
Comment #156
Gábor HojtsyI would guess at first that the locale module should implement the DB dumper / reader at the first place? If there is no DB definition to work with, how else could the dumper/reader work?
Comment #158
penyaskitoNote to self:
* Answer Gábor.
* Check with attiks why the 2 new tests are failing. I fixed them with
but not sure if the strings contained at files imported automatically should be imported marked as 'translated'. If the answer is not, the problem is at the test.
Comment #159
Gábor HojtsyYeah, if you import translations, they should appear with the translations :) Unless you import empty translations, which removes them, just like deleting them on the UI and submitting the form. I think the purpose of this whole issue generally is to replace what we have in an underlying layer **with the same functionality**, so the tests should equally pass as before, no?
Comment #160
penyaskitoSome pending tasks:
#156: We have to move PoDbReader and PoDbWriter to the Locale module.#159: We should take a look at the importing functionality when adding a new language, I think that we are not flagging the strings as 'translation'.#159: If I'm right with my previous affirmation, I'm scared that this issue didn't appeared before. Maybe we need more tests?#*: We should git mv core/lib/Drupal/Core/Gettext to core/lib/Drupal/Component/GettextComment #161
attiks CreditAttribution: attiks commented#158 is right
#18 test for multilines added
#55 ok
#69 Batch support is working, batch inside batch is handled in a follow-up
#6 ok
#1 is out of scope for this issue
so list in #160 wraps it up (for now ;p)
Comment #162
attiks CreditAttribution: attiks commentedslightly off topic: i created an overview off the current behaviour of the translation interface so we know which tests can pass: https://docs.google.com/spreadsheet/ccc?key=0Ar95pTGHJsoxdDMzbUl1Uk5aTGh...
Comment #163
penyaskitoOk, so all tests at green now. Those failing tests were new, and the behavior is not what @attiks nor I expected to be. @attiks gathered together that list, that maybe we can handle in a DX follow-up task. @attiks, could you create it and attach the document?
So now,
#160 is fixedComment #164
penyaskitoLet's see a green. Maybe?
Comment #166
penyaskitoRebased on branch 8.x.
Comment #167
penyaskitoComment #169
penyaskitoThere is a problem with d8mi sandbox 8.x branch (unwanted commits), I did the patch now against drupal/8.x and the size makes sense.
Comment #170
attiks CreditAttribution: attiks commentedminor changes:
* eb937ed - (HEAD, origin/gettext-1189184, gettext-1189184) Fixed some phpdocs and made array handling consiste
* 2f9c934 - Added some phpdocs. (14 hours ago)
* e8d69b6 - Removed params in importString. (14 hours ago)
Comment #171
attiks CreditAttribution: attiks commentedRandom design thoughts:
PO file without a header:
Notice: Undefined offset: 1 in Drupal\Component\Gettext\PoHeader->_locale_import_parse_header() (line 216 of /var/aegir/platforms/i18n/core/lib/Drupal/Component/Gettext/PoHeader.php).
PO file with only plural in header:
Notice: Undefined offset: 1 in Drupal\Component\Gettext\PoHeader->_locale_import_parse_header() (line 216 of /var/aegir/platforms/i18n/core/lib/Drupal/Component/Gettext/PoHeader.php).
PoHeader::compileHeader calls language_list()
should be passed as part of the header
only things needed are $language_name and $site_name
PoItem uses LOCALE_PLURAL_DELIMITER, should be a property
PoMemoryWriter uses LOCALE_PLURAL_DELIMITER, should be a property
isn't MemoryReader/Writer part of locale since it is Drupal specific?
Comment #172
attiks CreditAttribution: attiks commentedDiscussed with Christian: PoMemoryWriter can stay
Comment #173
vasi1186 CreditAttribution: vasi1186 commentedAfter a pretty short round of code review (the patch and issue are pretty big...), I found a few things that I think should require some attention (besides the overall code style that is probably not 100% Drupal compliant, and there are still lots of todos in code).
Do we need the empty constructor here?
This function is pretty big, and it has lots of if-else statements. Maybe some refactoring, to make it a bit more extensible, flexible, etc...?
Empty constructor again.
In the abstract Reader class. I think we should avoid having empty methods, or methods in abstract classes that return just empty strings, or empty arrays. Probably in most of the cases, if they do not make much sense in the abstract class, then they should be forced to be implemented by a real class.
Same thing for the abstract Writer class.
Comment #174
penyaskitoAbout the empty constructors: We'll add batch support in a follow up issue and we need to set the state in the constructor. It isn't already there, but it will be. We need to remove them and add them again? I think that we're fine with having them there.
Reader and Writer are being removed. We had them there as a reference, but I will remove them now. If we need to check them later we can do git checkout e9af636 in the sandbox.
I'll take a look at the readLine() method.
Comment #175
penyaskitoRebased patch.
Comment #176
penyaskitoTo get rid of the circular reference between Drupal\Component\Gettext\Gettext class and the locale module, we need to move it back to the locale module, or the static methods there don't make sense at all. The Drupal\Component\Gettext\Gettext is some kind of a facade of the subsystem, but references locale classes PoDbWriter and PoDbReader (assuming a valid Db connection, which is undesirable by comment #156) and locale constants.
I'd like a second opinion before doing this move.
Comment #178
attiks CreditAttribution: attiks commentedyes for moving gettext.php
Comment #179
penyaskito@attiks created two follow ups that shouldn't be missed if you are interested on this:
* #1637348: Import Gettext .po files in progressive batches to avoid time limits
* #1637334: PoDatabaseWriter needs Options set before Header
Comment #180
attiks CreditAttribution: attiks commentedlet's go
Comment #182
attiks CreditAttribution: attiks commentedtry again
Comment #183
Gábor HojtsyJust looked at the start, infer the rest from here :)
This whole file should not be here, right? It is not for core.
This todo is mentioned above too? At least link the issue and change to @todo if want to keep here.
What?!? What does this mean? Is this still true?
I think you can mention this, but let's not use this much space for it. You don't support flags either do you (#,).
Missing docs.
Missing docs.
At least document why is this.
Add docs. Also all other methods.
"as we are at BOF"? Explain this a bit more.
\Expection ?! Also single quotes.
Comment #184
vasi1186 CreditAttribution: vasi1186 commentedSome very small observations:
minor thing, $_size and $_fd are not documented... not sure if we must document every single class variable... Also, the PoHeader class has not documentation for its attributes.
MInor thing, the "." should be at the end of the sentences.
I think there is some code missing here, that should have in the end set the $_header attribute of the class to $header (at least this is what I would expect from this function...)
The class PoMemoryWriter class has lots of methods that are not yet implemented. Should this class be removed entirely, or maybe just those methods? As I talked with attiks, they are actually not needed in this class....
The main issues I found are the missing documentation and code that is not used yet...
Comment #185
attiks CreditAttribution: attiks commentedfollow-up #1637662: Clean up the Gettext PO parser
Comment #186
attiks CreditAttribution: attiks commenteddocs added, interface changed, ....
Comment #187
Gábor HojtsyCan we push this to a separate branch? Its easier to focus on stuff that we have than try to ignore stuff that we don't need. :/
@TODO should be @todo (applies everywhere where you use TODO or @TODO).
Not documented yet.
It does not seem hard to remove this unused code to me. Is it?
Lacks docs. Also other methods like this under there.
// Start reading the file with the header.
Sounds like a trivial comment :)
Remove \, single quotes.
We don't use this.
First line should be complete sentence with .
Text should be on new line, indented.
If todo, move up to phpdoc and @todo, otherwise throw an exception :D
This is not what the code does here.
Not used.
Dots at end of lines.
The current code does not support batched writing, and we don't seem to have a problem with that at all. We do have a problem with lack of batched reading, but not writing. So let's not focus on solving batched writing here, it complicates this quite a bit.
No need to keep a pointer, see above.
Gimme more stars! (At start of phpdoc). And later.
Single quotes.
Meaning?
Nice try :) We don't have author names in core like that. You'll be on the commit message and your name will be huge in the contributor cloud for D8MI :)
Lacks docs. Also, most of these are NEVER used in the code. I think we should limit this to the properties that Drupal uses. I *know* this does not sound like a nice reusable library then, but we found Symfony's not that one either. We are also allowed to focus on what we need :)
@see setDefaults(). Document langcode (yeah, I know trivial, yeah I know :)
Dox.
Only deal with what we support . Less code, happier reviewers :)
Dot at end of function sentence.
@todo if its really a todo, not TODO. Why do you need this? Is this a general wish, or a failure in the implementation? To me as a core reviewer, especially with ":(" it says "this is broken, DO NOT commit".
Also document $header is a PO format header, or something like that.
Document the function, if to do, then @todo. Document which keys are supported in $values. Or if you'd need to repeat that docs all the time at other places, figure out one place for it and @see to that.
Make the line longer as possible, not over the limit :) Too short lines are bad, too long lines are bad.
Let's put dots at the end of lines.
Put dots at comment line ends :) All the time, all the time :)
backwards compatible? token_get_all()? I think this is a pre-existing comment, but it sounds totally out of place.
Are these still stand? Batch related stuff should go away for now.
Maybe figure out a fancier doc for this :) Like "Methods required for both reader and writer implementations." if it fits on one line :)
"some transformation"? This should be more specific. Needs love should be more specific, @TODO should be @todo, @author should not be in core patches.
Most not documented. Clean up docs by adding dot on end of line, empty line before @see, etc.
phpdoc missing. This is accidentally named the same as the header one, or is it just a pattern? :)
For consistency, above we had setFromString, this one is fromArray. Should it be setFromArray()? Consistency is key.
phpdoc.
While this looks cool in fixed width, the supposed formatting for a list I think is - (hyphen) at each item's start and : (colon) inbetween the name of the item and the description. That is parsed better for api.d.o.
compileTranslation sounds like strange terminology (see also phpdoc for it). Instead of bikeshedding the terminology, since this is private, only called from __toString(), why not inline the whole thing there.
If we want to keep it as separate method, name it maybe formatItem() which would be consistent with the rest of the "formatters".
We can leave this here for the sake of not refactoring. But.... But, I have this condensed down to 2 lines in a comment above. This is pretty old PHP 3 code really.
Yes we need, later. Later.
Document it.
Yesss, remove it, remove it :)
Stores items in memory?
Of course it is context dependent, we imply that.
Yeah, would be cool to document it somewhere, like up there where $_items are defined for the class.
phpdoc.
doc does not match filename/classname.
Minor: leave a line between the { and the doc.
Document $reader. I know, I know it sounds trivial, but its useful to help when you code against it.
The gettext class is a gettext class :) Did you mean "Drupal specific functionality"? @attiks says you did :)
to a destination, *for example*:
Remove.
type => string?
Document them, document return values.
Remove comment IMHO.
Do we abbreviate exceptions like that?
Make it nicer by starting off with an M (vs. m).
IMHO remove the first comment line, leave the todo, rename to @todo :) And document what is "this" that has to be fixed.
Remove.
Copy paste docs? Segment as needed per properties. reformat phpdoc as appropriate (no @param).
Dot at end. Document that this is lid as in locales_source. (I guess).
Sounds like what you are doing is:
$this->_options = $options + array(
'override_options' => array(),
'customized' => LOCALE_NOT_CUSTOMIZED,
);
Is += not doing deep merge??!
Dropit.
Line ending spaces.
2-line function comment.
"this method it's required" => "is required". AND since this is going away, it is not required WOOOOO. Method can be removed altogether?
\Exception (again?)
These parameters don't exist on the method :) :)
Why not do these in setOptions like the 'customized' key is? Or in the constructor if we don't assume setOptions() is invoked, or in the variable def above?
It is already ordered by lid, why @todo? What does not work?! We don't need the batching stuff here.
langauge => language
Read one item at *a* time from the results and *store* the state.
BTW we read it all at once, and don't need to store the state (as in the lid) as per no batch support in here. The database query results are there and *are the state*, since we don't need to continue this in multiple requests, we can rely just on that.
Deleteit.
Temp code copy-paste?!
Well, we need this for the in-page reading process, not only for the batch. Is this an in-file batch or inbetween file batch that you need this for?
2 line comment => 1 line comment.
Do we need this for inbetween file batches or only in-file batches?
Which is text, or array, or...
drupal => Drupal
dots at end of line.
"weird to me still" is not the kind of comment we want to have in core :D Its pre-existing code, so we can work on refactoring that one later, no need to mention it is crap, we know it is crap. At least I feel with you.
Put empty line between two lines. Rethink first doc line.
Not enough whitespace in indent.
Dadadadada!
Comment #188
clemens.tolboom(Maybe I missed something the last 3 days then sorry for dups :p)
1. Just a quick comment on batches. Both reader and writer need to know whether they are 'in batch mode'. If the seekpos of PoFileWriter is not == 0 there is no need to write the header.
2. PoInterface should be GettextInterface as both PO and MO understand (afaik) header and language if we ever want to support MO files.
3. We now have a Component/Gettext but all files in it are named Po* (there is no README.txt explaining this :)
4. PoFileReader::readHeader() should have used PoFileReader::setHeader which makes the comment go away not using setHeader :)
5. All interface implementation method should have a @see as it's documentation right?
6. PoFileWriter opens in append mode. But there is no documentation the user should truncate the output file first if needed.
7. Is PoItem::mapping ever used?
8. Is moving PoDatabase* to locale.module not better implemented by adding an abstracted PoDatabaseReader then implemented by a LocalePoDatabaseReader. Currently modules cannot implement easily a similar storage. By only changing the table name we could gain a lot for l.d.o I guess.
9. Gettext.php should be in core/lib/Drupal/Component/Gettext as that is still abstract enough.
Comment #189
attiks CreditAttribution: attiks commentedMost of #187 is fixed, going for green
Comment #191
penyaskito#188:
This will be handled in follow-up #1637348: Import Gettext .po files in progressive batches to avoid time limits.
Gábor and Webchick thoughts are that we should refactor in this issue, and implement new stuff in a new one.
My thought was that Component\Gettext shouldn't know much about Drupal. That's why we moved PoDatabase* to Locale. l10n_server can have it's own classes that extend PoDatabaseReader and overwrite whatever method we have, none of them are marked as final.
See my answer to 8. Gettext.php has specific methods for locale and has knowledge about locale. BTW, moving it again there will reproduce the circular dependency between Gettext component and locale module.
Comment #192
attiks CreditAttribution: attiks commentedGo bot
Comment #193
attiks CreditAttribution: attiks commentedGets -> Get
Constructor, create ...
Create ...
PoInterface, not Reader
Create ....
PoStreamInterface, not PoReader
trailing space
trailing space
Comment #194
attiks CreditAttribution: attiks commentedcoding style fixes
Comment #195
clemens.tolboom(Just a bigger reminder)
As we are removing this function we need to check our new code landed in PoFileReader. I'm sure I fixed something over there (PoFileReader) but as @Sutharsan said in #55 I was using refactored code already :( :) ?!?
Comment #196
attiks CreditAttribution: attiks commented@clemens, I assume you compared the code your self? In #56 you admitted you didn't use Erik's code?
Back to NR
Comment #197
penyaskitoThis code is at Drupal\Component\Gettext\PoFileReader::readLine AFAIK.
Comment #198
penyaskitoComment #199
ArtusamakWhy all the private attributes in the classes are not written with $_name and with a getter/setter function? Only some are, has this been done on purpose?. The comment is not always describing the type either. Arguments /return values are not always documented.
Doxygen blocks around function should use "Sets", "Gets" instead of "Set" / "Get".
UCfirst + period at the end of the line.
Comment is too long, 80 chars max.
Comment is too long, 80 chars max.
Comment is too long, 80 chars max.
Missing end of line period.
Describe param.
Should be called getItems()?
Missing ending period.
Could use $this->setHeader($header) instead if implemented?
Should we throw an exception?
Typo in comment.
Comment #200
Gábor HojtsyTalked through the class and interface names with @attiks, with their purposes, etc. The inheritance/implementation tree was not very clean to avoid some empty method implementations. We need to experiment with this a little, here is the proposed naming for now.
- rename poItem to poMetadataInterface (it has nothing to do with .po per say)
- rename poFileReader/Writer to poStreamReader/Writer since the interface is for streams, not files (if it would be for files, we'd need to rename the other way around)
- go back to extending the poMetadataInterface with poWriterInterface (it looked ugly that only the db and file writers implemented it)
Comment #201
clemens.tolboom@attiks and @penyaskito (yes I used the in-between code :/)
I had the will but haven't had the time to do a line by line comparison between the old gettext.inc and new PoFileReader::readlIne so #55 and #195,6,7 are now reminders.
We should either update the issue summary by removing the reminder or do a line by line code review between the mentioned functions. It's not a big deal but has to be done.
The issue summary was update by me through #147.
(hope this makes things clearer :)
Comment #202
penyaskitoNeeds work yet.
Comment #203
penyaskitoComment #204
penyaskitoComment #205
attiks CreditAttribution: attiks commentedone for the testbot, rebased and conflicts removed
Comment #207
attiks CreditAttribution: attiks commentedTests should be ok
Comment #209
attiks CreditAttribution: attiks commentedInterface renamed
Comment #210
attiks CreditAttribution: attiks commentedComment #212
attiks CreditAttribution: attiks commentedfor the bot, we'll need to wait for #1642966: Typo: coddition instead of condition
Comment #213.0
(not verified) CreditAttribution: commentedPasted comment from #1189184: OOP & PSR-0-ify gettext .po file parsing and generation #147
Comment #213.1
attiks CreditAttribution: attiks commentedSummary updated to reflect reality
Comment #214
attiks CreditAttribution: attiks commentedwaiting for #1635084: Track import status of files in the locale .po file directory
Comment #215
Gábor HojtsyI started helping out with cleaning up more phpdoc. Found still several missing pieces, etc. Committed http://drupalcode.org/sandbox/goba/1624820.git/commitdiff/7f7fed55987648...
Figured out readItem() returns an array while writeItem() takes PoItem. Looks very-very strange. Why is the difference?
Comment #216
clemens.tolboomPoStreamReader::readItem calls PoStreamReader::readLine calls PoStreamReader::saveOneString() which created a PoItem so the documentation of PoReaderInterface is wrong.
Comment #217
Gábor HojtsyWell, I just carried that over from PoStreamReader's readItem:
Which definitely carries it over from the private property:
Are we looking at the same code?
Comment #218
clemens.tolboomAnother note on performance writing items through PoDatabaseWriter
I discussed this briefly with @penyaskito that when reading a PO file all items are in memory those need to be written to the database.
- is there an equivalent for db_update (see code below)?
- should we delete then insert multiple items like done below?
Taken from #932814: Error out when trying to masquerading as blocked user (#6)
Comment #219
clemens.tolboomIn #216 I tried to say the documentation is wrong.
Both items $_translation and function readItem should return a PoItem.
Comment #220
Gábor Hojtsy#212: i1189184-212.patch queued for re-testing.
Comment #222
attiks CreditAttribution: attiks commentedi will have a look later today
Comment #223
attiks CreditAttribution: attiks commentedtry again bot
Comment #225
attiks CreditAttribution: attiks commentedTimestamp wasn't set on batch import, should be fixed.
Comment #226
Gábor HojtsySuperb, thanks for the update! Let's keep cleaning up the code, eg. the misdocumentation discussed above and get it closer to done :) Thanks for sticking to this issue, its a huge change but its going to be great when it lands, opening up flexibility for so many things.
Comment #227
attiks CreditAttribution: attiks commentedComment #227.0
attiks CreditAttribution: attiks commentedBatch in separate issue
Comment #228
Gábor Hojtsy#225: i1189184-225.patch queued for re-testing.
Comment #230
attiks CreditAttribution: attiks commentedrebased patch
Comment #232
attiks CreditAttribution: attiks commentedComment #234
attiks CreditAttribution: attiks commentedComment #235
Gábor HojtsyOk I took several hours skipping some sleep to work on improving code style considerably, getting closer to making the patch committable. Attached interdiff, explained below. I went through all classes and interfaces in the Drupal gettext lib. I did not yet get to the locale implementations, those need some cleanup as well. Hopefully the code should still pass with my changes. @attiks can you help with rerolling the patch itself with my commit? (I committed this in the sandbox).
In this code style cleanup:
PoHeader:
- added @file comment
- shortened master comment
- added type explanations to properties
- got rid of mapping() and setDefaults() because they were overly complicated for just tracking the plural forms
- renamed getPlural to getPluralForms
- collapsed compileHeader() and __toString() into one, since there seemed to be no use for both being wrappers of each other
- dropped $filename from parsePluralForms() because it was not used there at all
- fixed several more type and function phpdocs
PoMemoryWriter
- fixed use statements
- grammar and phpdoc standards for interface implementation methods applied
- added phpdoc to all purposefully not implemented methods for api parser
PoMetadataInterface
- fixed use statements
- added plenty phpdoc for methods (these are referenced from "Implements" phpdocs)
PoReaderInterface
- fix readItem() docs, not an array but PoItem as discussed above
PoStreamInterface
- added plenty phpdoc for methods (these are referenced from "Implements" phpdocs)
PoStreamReader
- fixed use statements
- explained context better on the class property
- defined missing $this->plural as $this->_current_plural_index instead,
- renamed _current to _current_item and _translation to _last_item (although _current_item is not a PoItem per say)
- renamed file to stream in phpdoc as appropriate
- phpdoc standards for interface implementation methods applied
- streamlined readItem(), removed intermediary readTranslation()
- explained header reading in phpdoc
- explained readLine() state machine in phpdoc
- several code style fixes, minor code comment fixes and error message text improvements in readLine()
- add missing file name token in log(), automate line number handling since it was always provided
- renamed saveOneString() to setItemFromArray() for nicer API
- minor code style improvements in parseQuoted()
PoStreamWriter
- fixed use statements
- minor phpdoc tweaks, like above
- _seekpos was not a defined property, not used for anything, so removed
- hopefully explained write() better
- phpdoc standards for interface implementation methods applied
PoWriterInterface
- very minor phpdoc fixes
PoDatabaseWriter
- just apply the getPlural() => getPluralForms() rename and parsePluralForms() not getting a filepath
Comment #236
Gábor HojtsyRerolled with these code style changes.
Comment #237
Gábor HojtsyThree more fixes:
- PoStreamWriter did not declare that it implemented the PoStreamInterface (hah), although it implemented all methods proper; fix that
- log() in PoStreamReader is incompatible with string extraction (and only used from places where we can do that directly), so do that
- PoStreamReader did not have the errors property defined, define it now
Now to let the testbot do its magic :)
Comment #239
attiks CreditAttribution: attiks commentedStrange failing on Drupal\search\Tests\SearchCommentTest
Comment #240
Gábor HojtsyI doubt that is related to this patch (hopefully :). Worked more on cleanup of the locale defined code as well. Just cosmetic changes again and removing some unused code cruft:
PoItem:
- missing @file comment added
Gettext:
- missing @file comment added
- fixed missing use statement
- fixed missing explanations and improper types in phpdoc
PoDatabaseReader:
- missing @file comment added
- fixed $options documentation; this is *different* to the writer options
- also fixed setOptions() accordingly
- used proper "implements" phpdoc references to base interface
- buildQuery said it would return strings, which is not really what it does, fixed doc
PoDatabaseWriter:
- missing @file comment added
- explained options better
- explained _report better
- removed "ignored" key as it was not used for anything (and not present before the patch)
- removed hardwired location updates; the drupal.org provided files do not provide any location info anyway
- fixed indentation issues with queries
- removed batch related getState/setState that was not used
Comment #241
Gábor HojtsyAnd some readability / understandability fixes in the tests (plus a minor fix in install.inc where we added a CMI related line that should not have been part of this patch), so we don't have xyzz and xyzz2 type of values :) I did not actually run the tests locally, crossing fingers :)
The code definitely has some rough edges still, but after 240 comments, let's focus on getting it in, since it is leaps and bounds ahead of what core has now. Buzzword-enhanced the issue title for that.
Comment #243
Gábor HojtsyFound these (minor) reasons for all of the test fails:
- Gettext.php wanted to use the database writer from the wrong location (it is located with locale module, since it is reliant on its DB)
- the database writer did not save plural formulas properly since I forgot to rename one more $lang to $langcode, hah
- the database writer did not initialize its report array properly (it was indirectly initialized before via the batch related code that we don't need and was removed); added a direct constructor to init the reporting array
- I integrated the invalida HTML and the multiline text checks into the one test .po file but did not update the import success text check properly
- The multiline translation string was not properly set up for what was being tested
These are just side effects of minor changes. This patch now fixes all tests on my machine that I ran. Hopefully it will work here too.
Comment #243.0
Gábor HojtsyFixed remaining tasks which got removed through http://drupal.org/node/1189184/revisions/2150050/view
Comment #243.1
Gábor HojtsySerious update to the summary, include architecture picture.
Comment #244
penyaskitoReviewed all functional code (I have not been able of reviewing tests, sorry).
* Added two comments.
* Fixed one long line. There are some more at core/lib/Drupal/Component/Gettext/PoStreamReader.php, but they are long strings so I'm fine with it.
* Fixed a phpdoc typo.
For me is RTBC. Thanks everybody for your very hard work.
Comment #244.0
penyaskitoUpdated issue summary.
Comment #244.1
tobiasbUpdated issue summary.
Comment #245
attiks CreditAttribution: attiks commentedSome minor comments and one code style issue, but this should be good to go.
Comment #246
attiks CreditAttribution: attiks commentedFYI the interdiff is the other way around
Comment #247
Dries CreditAttribution: Dries commentedI skimmed this patch for 15 minutes and it looks sound. Let's wait for the testbot to come back with the results for the latest patch.
Comment #248
Dries CreditAttribution: Dries commentedOk, so the test bot came back green. Committed it to 8.x. Thanks.
Comment #249
sunComment #250
Gábor Hojtsy@Dries: woot, thanks!
@sun: Good tags :) Will follow up on this later this week. As long as the sprint tag is on it, its not off our board :)
Comment #251
Gábor HojtsyI think this definitely deserves a CHANGELOG.txt patch. Attached.
Added changenotice node at http://drupal.org/node/1703490, anybody missing details from there?
Comment #252
Gábor HojtsyHelps if I name it patch, although pretty unlikely it ever fails tests :D
Comment #253
webchickCommitted that follow-up as well. Thanks!
Comment #254
Gábor HojtsyThanks! Restore title.
Comment #255
sunOn the change notice (http://drupal.org/node/1703490), that rather looks like a handbook page to me.
Normally, change notices have the purpose of telling the affected developer/implementor of particular change "how to recover" ;) from the API change - i.e., explaining the change in a minimal way, but focusing on the important part; D7 code vs. D8 code -- what do I need to change in my code to upgrade it correctly?
It looks like most of this affected rather "low-level" functions. But since there never really was a proper API for performing such operations, it is possible that there might be modules/code out there, which (re-)used Locale module's functions.
The essential changes seem to be these:
PS: The
catch {}
line oftry...catch
statements in this code apparently violates coding standards ;) (should be on its own line)Comment #256
Gábor HojtsyUpdated the change notice with an import example and links to export changes. Since the "before" code is scattered among 3 functions its just not that I could throw up a few lines of standalone code and show it off.
I'll also submit a patch later to fix the try/catch code style issue.
Comment #257
Gábor HojtsyTrivial patch.
Comment #258
attiks CreditAttribution: attiks commenteddo we need this?
Comment #259
penyaskito@attiks Nice catch, I don't think so so new patch without the dumped exception.
Comment #260
Gábor HojtsyHa, cool :)
Comment #261
webchickWhile we're at it, can we make the $exc variable into $exception like the hunk below? We don't tend to abbreviate variable names.
I would just do this myself but I'm about to take off on an airplane and I'm not 100% positive I can safely rename that variable without testbot confirmation.
Comment #262
Gábor HojtsyAll right, I hoped to have this tiny fix in by the D8MI sprint, so we can clear this out of the sprint board and not confuse people. They don't need to figure out from a 262 comment thread that only some minor code style fixes are relevant at the end as of now. So in the interest of better understanding, I've moved this to #1737186: Fix code style issues in new OOP Gettext parser and closing this down as fixed as per the original goals. The remaining code style issues will be fixed there. It is tagged Novice and is on the sprint.
Comment #263
webchickCool, I'm following that issue so whenever it gets bumped to RTBC I'm happy to commit it.
Comment #264
Kristen PolAll I did was rename the
$exc
to$exception
per @webchick. Note that I simply edited the original patch directly and didn't create this patch via diff.Comment #265
Kristen PolWhoops... got a little crazy with the last patch (too many substitutions). This one should be correct.
Comment #266
penyaskitoKristen, this was already sorted at #1737186: Fix code style issues in new OOP Gettext parser
Comment #267
Kristen PolAh! Cool... sorry for the noise :)
Comment #268
andypostSite info already in CMI, probably needs test
Comment #269
Gábor HojtsyCan you please open this in a followup. Appreciated. Don't want to see comment #300.
Comment #270
andypostFollow-up #1751410: Fix site name retrieval in Gettext code for CMI conversion
Comment #271.0
(not verified) CreditAttribution: commentedUpdated issue summary.