Closed (works as designed)
Project:
Drupal.org security advisory coverage applications
Component:
module
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
28 Nov 2012 at 23:26 UTC
Updated:
5 Dec 2012 at 19:05 UTC
When creating a new custom menu via the Add Menu form, this module
provides an option to copy all of an existing custom menu's items to it.
for drupal 7.
http://drupal.org/sandbox/kris-o3/1853420
git clone --recursive --branch master http://git.drupal.org/sandbox/kris-o3/1853420.git menucopy
while similar to "menu clone" -- http://drupal.org/project/menu_clone -- this module only does what i've said above... copies an existing custom menu's items to a new custom menu on creation... nothing more, nothing less.
Comments
Comment #1
monymirzaHi,
This project needs much work. (please check the Drupal coding standards)
try to resolve erros and warnings.
http://ventral.org/pareview/httpgitdrupalorgsandboxkris-o31853420git
Comment #2
kris-o3 commenteddo you have a more specific criticism?
i did run the Coder module on 'menucopy' prior to committing...
even now, it says:
Coder found 1 projects, 1 files, 0 warnings were flagged to be ignored
menucopy.module
No Problems Found
visiting your link...
"Files must end in a single new line character"
that's interesting, because for another project i committed to a sandbox, someone insisted i convert LF to CRLF.
as for spaces before/after opening and closing ('s... i would insist that's personal preference.
i prefer the whitespace to more easily see all function parameters
instead($of,$having,$them,$all,$jammed,$together)
similar story with spacing $in[ 'array' ] indices.
can we agree there are no Serious violations or warnings?
or are you implying that you won't bother until this/your script generates a clean/empty/mostly-empty report?
Comment #3
kris-o3 commentedi don't know why you set Priority to critical, but i've set it back to normal.
i've also (begrudgingly) reformatted my code until PAReview.sh generated an empty/clean report.
http://ventral.org/pareview/httpgitdrupalorgsandboxkris-o31853420git
please review.
Comment #4
mohs3n71 commentedin your .module file :
you can remove blank lines in lines : 2 , 3 , 11 , 40
in lines 13 , 14 , 15
and also in lines 42 , 43 , 44
you wrote a comment for explaining about your functions but please read http://drupal.org/coding-standards/docs#hooks it's better that you use a standard way to explain about yout functions
Comment #5
kris-o3 commentedsomething something splitting hairs something something.
Comment #6
kris-o3 commentedanyway,
i've "fixed" the "problems" and recommitted.
clean report still from:
http://ventral.org/pareview/httpgitdrupalorgsandboxkris-o31853420git
Comment #7
klausihttp://drupal.org/project/menu_clone
This sounds like a feature that should live in the existing menu_clone project. Module duplication and fragmentation is a huge problem on drupal.org and we prefer collaboration over competition. Please open an issue in the menu_clone issue queue to discuss what you need. You should also get in contact with the maintainer(s) to offer your help to move the project forward. If you cannot reach the maintainer(s) please follow the abandoned project process.
If that fails for whatever reason please get back to us and set this back to "needs review".
Comment #8
kris-o3 commentedthe mechanism to copy a menu is Fundamentally different in my opinion. (it's a slight difference, yes, but a very important one.) the author of menu_clone chose to add the Clone link/option to the list of defined menus amongst the other Operations (Copy/Delete/etc.). whereas, menucopy adds the option to copy an existing, user-defined (Only those with the 'menu-' prefix in menu_name) menu Only to the Add Menu form.
menu_clone has additional options to change i18n settings of a menu before being copied, ignoring certain menu items before being copied, etc. all of which appear to have introduced points of failure and bugs. these are SERIOUS bugs for something so simple as copying a menu!
http://drupal.org/project/issues/menu_clone?status=All&categories=All
i kept the scope of menucopy Quite small, in the interest of a simplified use case, WITH NO BUGS.
just copies items from one user-defined (custom) menu to a new one. period.
Comment #9
kris-o3 commentedwith due respect, setting this back to needs review.
Comment #10
kris-o3 commentedin case there's any doubt that this module solves a Real and Important need in Drupal...
http://api.drupal.org/api/drupal/includes!menu.inc/function/menu_links_c...
http://drupal.org/node/252200#comment-5892570
Comment #11
malc0mn commentedmenu_clone began as a very simple module that would clone an existing menu into a new one. It was abandoned by it's original author (Garrett Albright) so I took over and rewrote the whole thing from scratch fixing all of the bugs in D6. Some non-reproducible issues have been reported for D6.
The ability to edit the menu before creating the actual clone just integrated the whole process: instead of cloning then editing, this is now done in one go.
Someone approached me to do a D7 port, which I gladly welcomed: I always appreciate collaboration. Unfortunately this was a really bad port omitting all the important stuff about the tricky Drupal menu handling (let's hope the menu system finally gets a full rewrite in D8). All of these issues have been addressed in the version I made in July of this year.
The core of the cloning process in menu_clone uses Drupal Core code (all documented in the module) that up until now works like a charm.
The most critical code, that effectively fixed 90% of the problems with the original menu_clone module resides in
menu_clone_clone_form_submit()in the menu_clone.admin.inc file. In the bad D7 port this code was completely omitted causing a lot of problems and bug reports. Also note the big blob of comment there.The open issues in the queue have so far not been reproducible and appear to be single occurances.
Menucopy looks more like the first D6 version of menu clone also mentioned in the links you post: http://drupal.org/node/252200#comment-1568986 . That's how it starded and it ended where it is now, due to feature requests etc.
I have no problem with criticism whatsoever, but I do think menucopy should be able to handle all kinds of menu's (even the very complex admin menu) if it aims to be a fully supported and mature contrib module that covers all it's bases making me think that, by community requests and support, it will end up very close to what menu_clone is now.
Again, I always appreciate collaboration and am happy to make anyone a co-maitainer to help advance menu_clone.
Comment #12
klausi@kris-o3: there are only 5 open bug reports against the 7.x version of menu_clone: http://drupal.org/project/issues/search/menu_clone?status[]=Open&version...
Only one of them is critical and could not be reproduced by the maintainer, so I do not see any serious bugs. I also don't see any bug reports submitted by you in that queue, so it looks like you did not try the module at all.
malc0mn has also stated that he is open about collaboration, so I can only repeat myself: Module duplication and fragmentation is a huge problem on drupal.org and we prefer collaboration over competition. Please open an issue in the menu_clone issue queue to discuss what you need. You could even get co-maintainership, just post your plans to that queue and ask.
If that fails for whatever reason please get back to us and set this back to "needs review".
Comment #13
kris-o3 commentedmalc0mm, firstly, let me say thank you so much for the thorough explanation and analysis.
looking at the reply here:
http://drupal.org/node/252200#comment-5892570
it seems to me that that poster implemented a similar method of updating the foreign keys after insert's, as i did in my module's submit handler... with the important difference that it only updates 'plid' and 'mlid', and not 'p1' through 'p9'...
when i first started research/vetting for my module, one of the things i noticed early on was, if you manually insert rows into the {menu_links} table (in your favorite mysql admin gui or what have you) that refer to a different menu_item, if you don't update the references in 'p1' through 'p9', and 'mlid' and 'plid' (simple child/parent relationship), menu items will appear in the list, but start to break and otherwise disappear when editing the menu at all... (either by editing an item or reordering them and saving changes.)
so i assumed those were 'important' foreign keys, and then wrote a loop to insert new rows, get the new ids with each inserted row, update an array that mapped the pre-existing menu's mlid to the new menu item's mlid, then wrote another loop to update those inserted rows, modifying the values of plid and p1 through p9... like so:
assuming that the schema for {menu_links} doesn't change, this should work sufficiently/reliably well...
apart from the potential (not likely?) for the schema to change and other foreign keys to be introduced in {menu_links}, what are some other reasons to use menu_link_save instead?
also, is there anything in menu_link_save that would make this method Not work? i see lots and lots of calls to update functions.
http://api.drupal.org/api/drupal/includes%21menu.inc/function/menu_link_...
i had originally included a call to menu_cache_clear but found it to not be necessary (?) when i tested with/without it.
Comment #14
kris-o3 commentedre: limiting the module to only those menus whose menu_name is prefixed by 'menu-', custom menus, when i inspected the {menu_links} i couldn't for the life of me determine why, the 'navigation' menu_name had so many rows, and yet, when editing that menu (/admin/structure/menu/manage/navigation) you are shown only 5 items...
i didn't want to break anything in Core. and thus the limitation of my module's scope; to leave the system/default menus alone.
Comment #15
kris-o3 commentedall that being said, i will have a more thorough look at the menu_clone module as there may indeed be a real possibility here of getting it 'past beta'... as i mentioned, i needed something simpler and more reliable (that i alone would answer for) for a client project *immediately* and will continue using it for that project for now... i put it up as a sandbox on drupal.org in case it was considered 'different enough' than menu_clone and would be useful to someone one else besides myself. you know, the whole reason for contrib modules in the first place.
Comment #16
malc0mn commentedI see two fundamental things in your code (just reading it, not actually testing it):
1. Any menu should have an entry in the menu_custom table. Menus created by users are prefixed with menu-, the others are system and/or 'special' menus, not created using the interface. Your code does not seem to update that table.
2. The big blob of comment I was referring to is:
My module has a form from which the menu data is taken (same as core) and is then ordered and saved properly (again as Drupal core does). You simply save the items as you receive them from the database.
I'm curious to know if you have tested this code with big and complex menu's (may not at all be the scope of your usecase)? The bad D7 port I mentioned before appeared to work like a charm to the person that ported it (especially for the usecases he needed it for), but when let loose in the community, cloning any kind of more complex menu with hierarchy and what not, it went hopelessly wrong because of the way the menu items were saved to the database.
The advantage of using menu_link_save() is that it handles all sort of Drupal Core stuff for you, such as:
- calling the right hooks so that other modules can act on the menu links that you are creating (e.g. hook_menu_link_alter but also in our case hook_menu_link_insert)
- handling the menu caching
- handling the paths for the menu link
- ...
There are tons and tons of ways to do things in Drupal, also by completely bypassing the Drupal API in various ways (often making it seem easier to code), but when creating a Drupal contrib module, it is important to integrate properly with the Core so that any module can be easily extended and maintained. When using the API and available core functions you cover most (if not all) of that. It would also allow users to attach themselves to your module without having to modify the module's code.
Take the hook_menu_link_alter. You could implement that in any module and thus alter the links that menu_clone creates. In your module that would not be possible and could easily come up as a feature request by users, causing you to implement your own invocation, rewriting the code to use menu_link_save() or dismissing the issue since it is not in your scope.
Ofcourse, you always need to keep your target ahead. Bypassing the API is sometimes necessary to avoid huge performance issues that could be caused by hook invocations.
In the end: your module may work perfectly fine for your particular use case, but when you want to release it in contrib, all sorts of stuff starts to happen :-D
Comment #17
kris-o3 commented1. creation of the new menu is already provided by the submit function of the menu module itself. which is another reason i "bolted on" my 'copy menu items from existing menu' option as a field to the menu_edit_menu form (only when $form['#insert'] is TRUE)... it doesn't matter the order in which my submit function or the form's existing submit handler are called, since menu_name is the primary key in both {menu_custom} and {menu_links}
2. what you cite could very well be the reason for the 'secret sauce' provided by the 'p1' through 'p9' columns. since my module is merely replacing the existing menu's mlid in these fields with each corresponding new mlid, is see no reason that those relationships would not remain intact. (and as we know, mlid is just a primary key so its ordinal value doesn't matter.)
menu path remains the same since they were copied from existing menu links.
now, as you mentioned, invoking all hooks for menu_link_insert and menu_link_update Does bring up a valid concern for which my submit handler does not account.
module_invoke_all($hook, $item);
re: caching, i didn't see that including/excluding menu_cache_clear had any effect.
Comment #18
kris-o3 commentedbeing an extension of the existing Add Menu process, menu_save would be triggered as it always did, which makes calls to menu_cache_clear_all(); -- which might explain my experiments with including/excluding it in my submit handler (is already being done?) -- and module_invoke_all('menu_insert', $menu); / module_invoke_all('menu_update', $menu);... so any hooks that are concerned with the creation of a new menu would still be triggered...
now, a fair question, would you necessarily Want a hook triggered for every new *item* that is copied? (notices, warnings, probably not. other use cases, maybe?)
Comment #19
malc0mn commentedIf the original submit handler is being called still, then that would explain perfectly why you do not need the cache clear. But the hooks that are fired there will not allow users to modify the menu items that you insert into the database directly...
As said before, you can implement your own invocations of existing hooks. But that requires more maintenance on your side if, for whatever reason, new hooks are introduced in Core. You would have to add them in the right spot as well.
Fair question indeed, but this is directly aimed at the Drupal Core: this is just the way Core does it and, in my personal opinion, a conrtib module should follow core behaviour unless there is a true valid reasoning to step away from this, other then 'I don't like the Core way of doing things' (lol).
The reason for these specific hooks being in core really do serve a purpose; I'm convinced of that even if I cannot come up with examples of use cases right now. And that's just it: the community has so many use cases to throw at you (have you seen this one [still can't find a use case for it myself] or this one requested by a client, and there was me just wanting to clone menu's :-D).
Bottom line stays the same: if your module serves what you aim at, then it it is just fine. But when released in the community you will be confronted with feature requests and other silly things that will require you to eventually kill your darlings to keep the module usefull for all.
Comment #20
kris-o3 commentedLOL at "kill your darlings"
for the time being, i'm modifying my project (for myself, and for anyone experimenting with/using this sandbox who prefer to be silent) to employ the use of menu_save_link in place of my ham-fisted db_query to insert the new menu items. which will effectively also reinstate the invocation of any/all insert/update hooks, cache clear and menu rebuild.
i've had a closer look at menu_clone and for the most part i appreciate the extra features and could see why they were requested, etc.
i see a Number of areas for improvement and will be in touch to discuss them.
setting this project to 'needs work', possibly to 'postponed' or 'closed (works as designed)' in the near future if working on menu_clone, well, works out :)
Comment #21
klausiThanks Kris! I'm sure any of your input will be highly appreciated for menu_clone.
I'm closing this project application, feel free to open a new application whenever you want to promote a new project.
Comment #22
malc0mn commentedYou know where to find me :-)