Mugo has a tool that we use internally to help with the main aspects of a developer's life: development, debugging and maintenance. The tool is called "eep", short for "Ease eZ Publish". It's a command line tool which provides many functions and allows for accomplishing tasks quickly by integrating with tools like awk, grep and xargs for powerful one-liners and supports rapid development of powerful bash scripts by leveraging eep as a library of eZ Publish specific operations.
eep is a standalone script, however it can hook in any 4.x kernel in order to operate on a particular eZ instance.
eep is intended to be useful to developers; not content managers or what have you. It is a little dangerous and focuses on getting the job done.
> cd http/dbx > eep use ezroot . msg:: Reseting ezroot > > ## Danger! Danger! > eep contentclass deleteclass folder
The output format is modeled after mysql output:
> eep contentnode info 8405 +--------------------------+----------------------------------+ I contentnode info [8405] | +--------------------------+----------------------------------+ I key | value | +--------------------------+----------------------------------+ | Name | Frequently Asked Questions | | ContentObjectID | 8503 | | MainNodeID | 8405 | | ClassIdentifier | downloadable_file | | PathIdentificationString | frequently_asked_questions | | PathString | /1/2/8405/ | | ParentNodeID | 2 | | CurrentLanguage | eng-US | | ContentObjectVersion | 1 | | RemoteID | 68e90a5f7fe2370a73374da2a3435634 | | IsHidden | 0 | | IsInvisible | 0 | | ContentObjectIsPublished | 1 | | Reverse related count | 1 | | Children count | 0 | | URL Alias | Frequently-Asked-Questions | +--------------------------+----------------------------------+
The basic concept of eep is to:
The guiding values have thus far been:
eep is available on github at: https://github.com/mugoweb/eep
Installation is documented in install.txt and amounts to causing "eep" to simply invoke the script. Note that for linux installs, the command line completion stuff is very nice; even now with just basic functionality it's big help.
In addition to leveraging all the standard tools, making eep a command line tool provides a couple sweet benefits. The first is that spreading a heavy processing load across multiple CPUs is trivial. The second takes advantage of a custom daemon to schedule and control large lists of tasks; the daemon also provides operability via the eZ admin interface. We aren't releasing the daemon at this time; we are still rolling it into a production setting.
And now for some examples.
> eep list contentclasses +----------------------------+----+------+----------------------------------+--------+------------------------------------+---------+ I list content classes | +----------------------------+----+------+----------------------------------+--------+------------------------------------+---------+ I Identifier | Id | # | RemoteID | Lang | Name | Group | +----------------------------+----+------+----------------------------------+--------+------------------------------------+---------+ | announcement | 59 | 2 | 4508764cae43f93a9a17480685168739 | eng-US | Announcement | DBX | | article | 16 | 0 | c15b600eb9198b1924063b5a68758232 | eng-US | Article | | | asset_class | 57 | 5 | 851dade1c910ad26700b30a2c70ca4b2 | eng-US | Asset Class | Content | | banner | 45 | 10 | 9cb558e25fd946246bbb32950c00228e | eng-US | Banner | Content | | common_ini_settings | 14 | 1 | ffedf2e73b1ea0c3e630e42e2db9c900 | eng-US | Common ini settings | Setup | | custom_error | 91 | 2 | fe2fd148254033388798af7b6218d35d | eng-US | Custom Error | DBX | | deployment | 97 | 11 | 6e686a81fb81d07e9ff535effa86391f | eng-US | Deployment | Content | | disclaimer | 90 | 12 | 390e0f705816c632e56abd419c792e64 | eng-US | Disclaimer | Content | | product_disclosures | 73 | 11 | 4a1ed1df1cdb1846d6893a9b10c0687d | eng-US | Disclosures | Content | | product_distributions | 68 | 21 | 358c65fae841d33e28f4ee9476214058 | eng-US | Distributions | Content | | downloadable_file | 89 | 1393 | ceb50523639d1b2c1f5c76c817508ae6 | eng-US | Downloadable File | Media | | product_downloads | 70 | 53 | b4f38188ebe5d44d624c12890f83a20c | eng-US | Downloads | Content | | faq_item | 82 | 25 | b34c64ee3ee76964b25d8202eabd7e7f | eng-US | FAQ Item | DBX | | file | 28 | 1 | 637d58bfddf164627bdfd265733280a0 | eng-US | File | Media | | flash | 29 | 0 | 6cd17b98a41ee9355371a376e8868ee0 | eng-US | Flash | Media | | flash_recorder | 30 | 0 | e349c947fd306299418be35b07b9a940 | eng-US | Flash recorder | Media | | focus | 56 | 8 | be8710cb34466d9460e207c35d8e951b | eng-US | Focus | Content | | folder | 1 | 368 | a3d405b81be900468eb153d774f4f0d2 | eng-US | Folder | Content | | windows_media | 36 | 0 | 223dd2551e85b63b55a72d02363faab6 | eng-US | Windows media | Media | +----------------------------+----+------+----------------------------------+--------+------------------------------------+---------+
(note that the output is truncated for the blog post)
> eep list contentclasses | awk '$6==0' | article | 16 | 0 | c15b600eb9198b1924063b5a68758232 | eng-US | Article | | | flash | 29 | 0 | 6cd17b98a41ee9355371a376e8868ee0 | eng-US | Flash | Media | | flash_recorder | 30 | 0 | e349c947fd306299418be35b07b9a940 | eng-US | Flash recorder | Media | | gallery | 38 | 0 | 6a320cdc3e274841b82fcd63a86f80d1 | eng-US | Gallery | Content | | global_layout | 32 | 0 | f0271811b913befa8f062527e909f15e | eng-US | Global layout | Content | | infobox | 25 | 0 | 0b4e8accad5bec5ba2d430acb25c1ff6 | eng-US | Infobox | Content | | link | 34 | 0 | 74ec6507063150bc813549b22534ad48 | eng-US | Link | Content | | multicalendar | 26 | 0 | 99aec4e5682414517ed929ecd969439f | eng-US | Multicalendar | Content | | poll | 27 | 0 | 232937a3a2eacbbf24e2601aebe16522 | eng-US | Poll | Content | | quicktime | 35 | 0 | 16d7b371979d6ba37894cc8dc306f38f | eng-US | Quicktime | Media | | real_video | 37 | 0 | dba67bc20a4301aa04cc74e411310dfc | eng-US | Real video | Media | | silverlight | 47 | 0 | 8ab17aae77dd4f24b5a8e835784e96e7 | eng-US | Silverlight | Media | | flash_player | 31 | 0 | 20b2ed0982343e6e0a550f7f0c137e06 | eng-US | Video/Flash Player | Media | | windows_media | 36 | 0 | 223dd2551e85b63b55a72d02363faab6 | eng-US | Windows media | Media |
> eep list contentclasses | awk '$6==0 {print $2}'
article
flash
flash_recorder
gallery
global_layout
infobox
link
multicalendar
poll
quicktime
real_video
silverlight
flash_player
windows_media
> eep list contentclasses | awk '$6==0 {print $2}' | xargs -IOID eep contentclass deleteclass OID
Deleting 0 objects.
Done deleting objects.
PHP Fatal error: Call to a member function isClassAttributeRemovable() on a non-object in /home/dfp/http/dbx/kernel/classes/ezcontentclass.php on line 815
PHP Stack trace:
PHP 1. {main}() /home/dfp/eep/eep.php:0
PHP 2. require_once() /home/dfp/eep/eep.php:130
PHP 3. contentclass_commands->run() /home/dfp/eep/modules/contentclass/index.php:311
PHP 4. contentclass_commands->deleteClass() /home/dfp/eep/modules/contentclass/index.php:256
PHP 5. eZContentClass->remove() /home/dfp/eep/modules/contentclass/index.php:145
PHP 6. eZContentClass->isRemovable() /home/dfp/http/dbx/kernel/classes/ezcontentclass.php:758
PHP 7. eZContentClass->removableInformation() /home/dfp/http/dbx/kernel/classes/ezcontentclass.php:774
Fatal error: eZ Publish did not finish its request
The execution of eZ Publish was abruptly ended, the debug output is present below.
xargs: eep: exited with status 255; aborting
Well, that's annoying. I wanted to remove all the unused content classes; but it appears that the first useless content class has a problem. My guess is that it's because the "article" class makes use of an attribute that is not actually in the system.
> eep list attributes article +-----------------+--------+-----+------------+------+------+------+-----+-----------------+ I list attributes of class: article | +-----------------+--------+-----+------------+------+------+------+-----+-----------------+ I Identifier | Lang | Id | Type | Srch | Reqd | Info | Pos | Name | +-----------------+--------+-----+------------+------+------+------+-----+-----------------+ | title | eng-US | 183 | ezstring | 1 | 1 | 0 | 1 | Title | | short_title | eng-US | 184 | ezstring | 1 | 0 | 0 | 2 | Short title | | author | eng-US | 185 | ezauthor | 0 | 0 | 0 | 3 | Author | | intro | eng-US | 186 | ezxmltext | 1 | 1 | 0 | 4 | Summary | | body | eng-US | 187 | ezxmltext | 1 | 0 | 0 | 5 | Body | | enable_comments | eng-US | 188 | ezboolean | 0 | 0 | 0 | 6 | Enable comments | | image | eng-US | 189 | ezimage | 0 | 0 | 0 | 7 | Image | | caption | eng-US | 190 | ezxmltext | 1 | 0 | 0 | 8 | Caption (Image) | | publish_date | eng-US | 191 | ezdatetime | 1 | 0 | 0 | 9 | Publish date | | unpublish_date | eng-US | 192 | ezdatetime | 1 | 0 | 0 | 10 | Unpublish date | | tags | eng-US | 193 | ezkeyword | 1 | 0 | 0 | 11 | Tags | | star_rating | eng-US | 194 | ezsrrating | 0 | 0 | 0 | 12 | Star Rating | +-----------------+--------+-----+------------+------+------+------+-----+-----------------+
It could only be 'star rating'. What is the status of the extension:
> eep list extensions +--------------------+--------------------+----------------+---------------+---------------+ I list extensions | +--------------------+--------------------+----------------+---------------+---------------+ I folders | ActiveExtensions | A.A.Extensions | design | modules | +--------------------+--------------------+----------------+---------------+---------------+ | contentdeployment | | | | | | ezjscore | ezjscore | | ezjscore | ezjscore | | ezodf | | | | | | ezcomments | | | | | | ezscriptmonitor | | | | | | ezsi | | | | | | ezie | | | | | | data_import | | | | | | ezmultiupload | ezmultiupload | | ezmultiupload | ezmultiupload | | ezstarrating | | | | | | dbx | dbx | | dbx | dbx | | ezfind | ezfind | | ezfind | ezfind | | ezwebin | ezwebin | | ezwebin | | | ezflow | ezflow | | ezflow | ezflow | | ezmbpaex | | | | | | ezformtoken | | | | | | ezoe | ezoe | | ezoe | ezoe | | ezwt | | | | | | ezprestapiprovider | ezprestapiprovider | | | | | ezless | | | | | | ezgmaplocation | | | | | | rautils | | | | | +--------------------+--------------------+----------------+---------------+---------------+
So, the "ezstarrating" extension is not enabled. Let me hack that into settings/override/site.ini.append.php.
> eep list extensions | grep star | ezstarrating | ezstarrating | | ezstarrating | |
And then try to delete the content class:
> eep contentclass deleteclass article Deleting 0 objects. Done deleting objects.
and then delete all the useless content classes again, and confirm:
> eep list contentclasses | awk '$6==0 {print $2}' | wc -l
0
Ok, ok; using wc was a little bit unnecessary, but it did generate a nice "0".
> eep list contentclasses +---------------------+----+--------+----------------------------------+--------+---------------------+-----------+ I list content classes | +---------------------+----+--------+----------------------------------+--------+---------------------+-----------+ I Identifier | Id | # | RemoteID | Lang | Name | Group | +---------------------+----+--------+----------------------------------+--------+---------------------+-----------+ | onix_bisac_category | 55 | 2733 | 85d41773c35f29bcbe41aea2eaec93c9 | eng-CA | BISAC category | Bookshelf | | blog | 19 | 1 | 3a6f9c1f075b3bf49d7345576b196fe8 | eng-CA | Blog | Content | | blog_post | 20 | 6 | 7ecb961056b7cbb30f22a91357e0a007 | eng-CA | Blog post | Content | | book_annotation | 71 | 671 | f29e51311e8aa9821ef98e78f6c00a4b | eng-CA | Book Annotation | Bookshelf | | book_folder | 49 | 27 | acaee61d5596130a584cae3d91ee53d3 | eng-CA | Book Folder | Bookshelf | | common_ini_settings | 14 | 1 | ffedf2e73b1ea0c3e630e42e2db9c900 | eng-CA | Common ini settings | Setup | | contributor_folder | 50 | 26 | 80ec2434df8e66d72baa99f1a1079733 | eng-CA | Contributor Folder | Bookshelf | | documentation_page | 24 | 12 | d4a05eed0402e4d70fedfda2023f1aa2 | eng-CA | Documentation page | Content | | file | 28 | 4 | 637d58bfddf164627bdfd265733280a0 | eng-CA | File | Media | | flash_recorder | 30 | 1 | e349c947fd306299418be35b07b9a940 | eng-CA | Flash recorder | Media | | folder | 1 | 302 | a3d405b81be900468eb153d774f4f0d2 | eng-CA | Folder | Content | | frontpage | 23 | 6 | e36c458e3e4a81298a0945f53a2c81f4 | eng-CA | Frontpage | Content | | game_cover | 73 | 48 | 3101958361cf3b76b9c804ccc0aab1b8 | eng-CA | Game Cover | Bookshelf | | giveaway | 76 | 34 | 00edae306718c75cabbfcb738a6c0df1 | eng-CA | Giveaway | Bookshelf | | global_layout | 32 | 1 | f0271811b913befa8f062527e909f15e | eng-CA | Global layout | Content | | image | 33 | 918 | f6df12aa74e36230eb675f364fccd25a | eng-CA | Image | Media | | list | 65 | 332 | faa59e289d6d7fb6636ea2d33fc92f41 | eng-CA | List | Bookshelf | | list_bisac_category | 75 | 851 | 6ca9b6c4ac241ff77d2f9cfe0566c17c | eng-CA | List BISAC category | Bookshelf | | message | 67 | 34 | 1db77616a9436fdb19d8d836c66dd8db | eng-CA | Message | Bookshelf | | otp_post | 64 | 178 | 1bd7e59a75b52e276b0755aa62e089db | eng-CA | Off The Page post | Bookshelf | | onix_contributor | 54 | 27524 | 6885e3e3d924dd57e12019a56a7fa716 | eng-CA | ONIX Contributor | Bookshelf | | onix_mediafile | 56 | 37415 | 658867ac3bd41a95e71eee070b0542e5 | eng-CA | ONIX MediaFile | Bookshelf | | onix_othertext | 57 | 134714 | 9daf9eb9ff4f79f51ac58bd8441f3562 | eng-CA | ONIX OtherText | Bookshelf | | onix_prize | 62 | 9481 | d37435393a5d53231e188edeb1b93f1d | eng-CA | ONIX Prize | Bookshelf | | onix_product | 52 | 52364 | fdbb7e3150f22c72f5fadb8963ffc045 | eng-CA | ONIX Product | Bookshelf | | onix_publisher | 53 | 745 | d0287045337b0f2fc9c9e03d188f23e6 | eng-CA | ONIX Publisher | Bookshelf | | onix_series | 61 | 1961 | d492b9b7a14b8e0e64ad129270f67f7c | eng-CA | ONIX Series | Bookshelf | | onix_supplydetail | 59 | 53704 | f91869f0f114a08b8b3a1842709fc665 | eng-CA | ONIX Supply Detail | Bookshelf | | onix_website | 58 | 4841 | b5acae96ec526d0bdb0c0d7996b1ffd7 | eng-CA | ONIX Website | Bookshelf | | publisher_folder | 51 | 27 | e7f78d2f9c8a7bb10d5afc57092dc0c7 | eng-CA | Publisher Folder | Bookshelf | | report_message | 72 | 274 | 64eeb2569da631066cb024b85a812af2 | eng-CA | Report Message | Bookshelf | | review | 70 | 95 | 3331aaebb0ca37e1834d0bcc3ccabfcf | eng-CA | Review | Bookshelf | | review_folder | 69 | 86 | 63b33166599d4b499b62ac76b12a89c5 | eng-CA | Review Folder | Bookshelf | | series_folder | 60 | 27 | 5b140326284981ede98b9bb6d1ed3cba | eng-CA | Series Folder | Bookshelf | | simple_content | 74 | 2 | 690aa81fdb1ca8b18a4f84a37f2e2ccb | eng-CA | Simple content | Bookshelf | | template_look | 15 | 1 | 59b43cd9feaaf0e45ac974fb4bbd3f92 | eng-CA | Template look | Setup | | user | 4 | 1398 | 40faa822edc579b02c25f6bb7beec3ad | eng-CA | User | Users | | user_affiliation | 63 | 4 | 91f4a128ca662425698c314ac38fc1b0 | eng-CA | User Affiliation | Bookshelf | | user_group | 3 | 6 | 25b4268cdcd01921b808a0d854b877ef | eng-CA | User group | Users | +---------------------+----+--------+----------------------------------+--------+---------------------+-----------+
That's 134714 instances of onix_othertext. Handling this many instances in PHP is something of a problem because memory leaks will crash your script well before you've handled all those objects.
> eep contentclass fetchallinstances onix_othertext
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 71 bytes) in /home/dfp/eep/lib/eepHelpers.php on line 352
PHP Stack trace:
PHP 1. {main}() /home/dfp/eep/eep.php:0
PHP 2. require_once() /home/dfp/eep/eep.php:130
PHP 3. contentclass_commands->run() /home/dfp/eep/modules/contentclass/index.php:311
PHP 4. contentclass_commands->fetchallinstances() /home/dfp/eep/modules/contentclass/index.php:265
PHP 5. eep::displayNonObjectList() /home/dfp/eep/modules/contentclass/index.php:171
Fatal error: eZ Publish did not finish its request
The execution of eZ Publish was abruptly ended, the debug output is present below.
So eep supports limit and offset:
> eep contentclass fetchallinstances onix_othertext --limit=100000 --offset=40000 +---------+-----+---+----------------------------------+---------------------------------------------+ I All instances of content class 'onix_othertext' | +---------+-----+---+----------------------------------+---------------------------------------------+ I Object | Sid | V | Remote Id | Name | +---------+-----+---+----------------------------------+---------------------------------------------+ | 3044426 | 1 | 1 | b5a96b469819f9f752bf8f4118ff25ba | Main description | | 3044427 | 1 | 1 | b67005432cac1b0afd231f60c1a6ba2c | Review text | | 3044431 | 1 | 1 | 6e57bd7c41b752e9bca9b085ce0d1281 | Main description | | 3044435 | 1 | 1 | 8e88848541395e344384f2b65e67f3e0 | Main description | | 3044439 | 1 | 1 | de8550226af4248bd951a775acee4545 | Main description |
... and so on, generating 100,000 rows of data.
eep wraps the lovely toString() and fromString() API functions. This is the built-in 'help' output:
> eep attribute Available commands:: help, delete, fromstring, tostring, migrate, newattributexml, update delete - deletes an attribute from class and objects eep use ezroot <path> eep use contentclass <class identifier> eep attribute delete <attribute identifier> fromstring - calls FromString() on the attribute eep use contentobject <object id> eep attribute fromstring <attribute identifier> <new value> or eep attribute fromstring <content object id> <attribute identifier> <new value> tostring - calls ToString on the attribute eep use contentobject <object id> eep attribute tostring <attribute identifier> or eep attribute tostring <content object id> <attribute identifier> migrate - copies data from one attribute to another within a content class - todo, report available conversions currently supported are "rot13" for testing and "time2integer" eep use ezroot <path> eep use contentclass <class identifier> eep attribute migrate <src attribute> <conversion> <dest attribute> newattributexml - dumps xml that can be edited and then imported eep attribute newattributexml update - updates objects with new attribute and also the class; will resume after a partial update eep use ezroot <path> eep use contentclass <class identifier> eep attribute update <path to newattributexml file>
Download and contribute to eep on GitHub: https://github.com/mugoweb/eep
Read a case study on solving a client problem with eep.
We're a group of web experts who solve complex web problems.
Learn more about us »Many years of experience with complex websites allows us to offer total solutions.
Learn more about what we can do »We've solved problems across North America and around the world.
Learn more about what we've done »
Comments
blog comments powered by Disqus