While working on an hook_update_N() I needed to pragmatically add a new custom menu. This patch allows doing it using an API.

CommentFileSizeAuthor
#113 drupal.menu-custom-dbmerge.patch1.89 KBsun
#87 menu_delete.patch687 bytessalvis
#101 menu_delete.473082.100.patch882 bytessalvis
#100 theme_username.565792.44.patch1.97 KBsalvis
#94 menu_delete.patch687 bytessalvis
#92 drupal.menu-delete-fix.patch902 bytessun
#80 drupal.menu-custom-api.80.patch19.77 KBsun
#78 drupal.menu-custom-api.78.patch19.66 KBsun
#77 drupal.menu-custom-api.77.patch16.31 KBsun
#76 drupal.menu-custom-api.76.patch18.66 KBsun
#73 drupal.menu-custom-api.73.patch19.34 KBsun
#69 drupal.menu-custom-api.69.patch18.73 KBsun
#66 drupal.menu-custom-api.66.patch18.73 KBsun
#61 drupal.menu-custom-api.61.patch18.25 KBsun
#58 drupal.menu-custom-api.58.patch18.25 KBsun
#53 drupal.menu-custom-api.patch15.31 KBsun
#47 473082-custom-menu-API-47.patch7.14 KBamitaibu
#41 custom-menu-API-41.patch7.95 KBamitaibu
#40 473082-custom-menu--api-38.patch7.92 KBamitaibu
#38 473082-custom-menu--api-38.patch7.92 KBamitaibu
#37 custom-menu-API-37.patch7.98 KBdropcube
#36 473082-36-custom-menu-API.patch7.42 KBPasqualle
#31 473082-31-custom-menu-API.patch7.17 KBPasqualle
#30 custom-menu-API-30.patch7.35 KBdropcube
#23 custom-menu-API-23.patch7.35 KBdropcube
#20 custom-menu-API.patch7.6 KBdropcube
#17 menu-custom-save-17.patch3.43 KBamitaibu
#15 menu-custom-save-15.patch3.44 KBamitaibu
#8 menu-custom-save-8.patch3.7 KBamitaibu
#5 menu-custom-save-4.patch3.55 KBamitaibu
#3 menu-custom-save-3.patch3.55 KBamitaibu
#1 menu-custom-save-2.patch3.98 KBamitaibu
menu-custom-save-1.patch2.71 KBamitaibu
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amitaibu’s picture

FileSize
3.98 KB

Test added to patch.

Berdir’s picture

Status: Needs review » Needs work
+function menu_custom_save($menu = array()) {
+  $menu += array('description' => '');
+  $menus = menu_get_menus();
+  if (empty($menus[$menu['menu_name']])) {
+    db_insert('menu_custom')
+      ->fields(array(
+        'menu_name' => $menu['menu_name'],
+        'title' => $menu['title'],
+        'description' => $menu['description'],
+      ))
+      ->execute();
+  }
+  else {
+    db_update('menu_custom')
+      ->fields(array(
+        'title' => $menu['title'],
+        'description' => $menu['description'],
+      ))
+      ->condition('menu_name', $menu['menu_name'])
+      ->execute();    
+  }

If we explicitly only use title, description and menu_name, why not use menu_custom_save($menu_name, $title, $description = '') ?

amitaibu’s picture

Status: Needs work » Needs review
FileSize
3.55 KB

10x Berdir, here's the patch according to your comments.

Berdir’s picture

looks better now :)

Optioanl

:)

amitaibu’s picture

FileSize
3.55 KB

Fix typo.

chx’s picture

The tests should use random string/name.

moshe weitzman’s picture

What's the advantage of a random string? Seems equivalent to me.

amitaibu’s picture

FileSize
3.7 KB

Test is now with random strings.

catch’s picture

Status: Needs review » Reviewed & tested by the community

Looks great.

amitaibu’s picture

chx in IRC asked if we really need to have this function - maybe just a drupal_write_record() is ok. I think that maybe it's better to have this API function for DX. Any thoughts?

tic2000’s picture

For me the function name doesn't sound right. menu_save_item, menu_set_item maybe?

catch’s picture

We have menu_link_save() for custom menu links, this is for top level menus.

I'm pretty sure I've seen people ask how to make top level menus before, it'd be nice for them to find (or be directed) to an API function even if it's as light as this one.

bjaspan’s picture

chx asked for my opinion on this but my battery is dying, will check in later

(translation: "subscribe")

Status: Reviewed & tested by the community » Needs work

The last submitted patch failed testing.

amitaibu’s picture

Status: Needs work » Needs review
FileSize
3.44 KB

re-roll.

Status: Needs review » Needs work

The last submitted patch failed testing.

amitaibu’s picture

Status: Needs work » Needs review
FileSize
3.43 KB

hmm, I still need to learn how to patch with git... I hope Testbot will like this one.

dropcube’s picture

Title: Add menu_custom_save API » Add custom menu API
Category: feature » task
Priority: Normal » Critical
Status: Needs review » Needs work
Issue tags: +DX (Developer Experience), +API change, +API addition

For API consistency, we should also have a menu_custom_delete() function. Also, this API function should be in menu.module, the module that allows custom menus, not in menu.inc.

This API would be a great addition, to be used in install profiles, ... etc., and for a better developer experience. Tagging accordingly.

dropcube’s picture

Assigned: Unassigned » dropcube

I will take care of it.

dropcube’s picture

Status: Needs work » Needs review
FileSize
7.6 KB

Added the following changes to the patch at #17.

- menu_custom_save() moved from menu.inc to menu.module, the module that allows custom menus.
- added menu_custom_delete() to delete custom menu and menu links associated.
- menu_custom_save() should receive a $custom_menu object, for consistency with others API in core.
- Used menu_custom_save() in menu.install, and toolbar.install instead of manually executing queries.
- Used menu_custom_delete() in the menu delete form submit handlers in menu.admin.inc.

davyvdb’s picture

Looks great. Have been creating some menu and items. Didn't find any other referentes to menu_custom either.

Pasqualle’s picture

+ * @param $custom_menu
+ *   The custom menu object or array to be saved.
+ * @return
+ *   Status constant indicating if role was created or updated.
+ *   Failure to write the user role record will return FALSE. Otherwise.
+ *   SAVED_NEW or SAVED_UPDATED is returned depending on the operation 
+ *   performed.
+ */
+ function menu_custom_save($custom_menu) {

1. I do not like when a function parameter type is not specified exactly. Would it be a problem to allow only array type $custom_menu? As I see it is used as array everywhere.
2. I do not see any return statement in this function.

dropcube’s picture

FileSize
7.35 KB

@Pasqualle, thanks for the review.

1. I do not like when a function parameter type is not specified exactly. Would it be a problem to allow only array type $custom_menu? As I see it is used as array everywhere.

An object is being used for consistency with other module_*_save() API functions in core. IMO, it's PHP, we do not need strict type checking.

2. I do not see any return statement in this function.

No, no return statement , removed the comment.

Pasqualle’s picture

That's right, we do not need strict type checking, as it is PHP, but it would be nice to have. So when I see a variable named $custom_menu then I would know what type should I expect.
As I see (http://api.drupal.org/api/search/7/_save) there is only 1 *_save() function (file_save) where different variable types are allowed, and I would rather fix that also than creating a new one..

Pasqualle’s picture

the file_save() issue #561520: $file is an object

dropcube’s picture

Well, I suggest to leave it as an object, and do the typecasting so that we don't have to change everywhere an array is used. Then, we can convert the other structures to stdClass if you prefer.
4 days to code freeze!!!

Pasqualle’s picture

I do not know which issue are you referencing to. The $custom_menu is an array everywhere, so the function parameter should be an array. The $file is an object everywhere so the function parameter should be an object. I do not understand what else do you want to change..
I am happy with array and object variables as function parameters, I just want the type to be specified, as it is specified (mostly?) everywhere in Drupal.

amitaibu’s picture

Status: Needs review » Needs work

In #2 Berdir asked
> why not use menu_custom_save($menu_name, $title, $description = '') ?

Which in terms of DX I think is better in this situation.

The name of the custom menu to be deleted..

Nit pick - Two dots(..)

Also, how about adding a test for the menu delete? (I don't have a dev enviorement on this computer so can;t re-roll myself...)

Pasqualle’s picture

@Amitaibu: only one variable should be used for the item to be inserted into db. that is the common format of *_save functions..

dropcube’s picture

Status: Needs work » Needs review
FileSize
7.35 KB

For consistency with other *_save() API functions in core, we should use an object as the parameter to that function.
It's easy to read, can be modified inside the function and the changes persists without requiring to be passed by reference, etc...

- Removed the trailing dot in the docs.

Pasqualle’s picture

changed the menu_custom_save() function to accept array type parameter only. $menu and $custom_menu is used as array, so the function parameter should be an array. There are many *_save() functions with array parameters, so the function is consistent with the rest of core..

moved menu_custom_save() and menu_custom_delete() into menu.inc as these functions should be accessible even the menu module is disabled.

dropcube’s picture

Custom menus are handled by menu.module, which in fact, creates the table {menu_custom}. So, those API functions should live in menu.module, not in menu.inc. If the menu.module is not installed, you probably don't need to use those functions.

Note, for example, that toolbar.module has menu.module as a dependency.

About the parameter as array or as object, I do not think that is something worth further discussion, whatever the decision, for me is fine. The most important is to get this API in before the freeze.

Pasqualle’s picture

you are right, the table is created with menu.module therefore the functions should be in menu module.

but we should decide which form should be used:

function mymodule_install() {
  menu_custom_save(..)
}
function mymodule_uninstall() {
  menu_custom_delete(..)
}

vs

function mymodule_install() {
  if module_exists('menu') {
    menu_custom_save(..)
  }
}
function mymodule_uninstall() {
  if module_exists('menu') {
    menu_custom_delete(..)
  }
}
function mymodule_modules_installed($modules) {
  if (in_array('menu', $modules)) {
    menu_custom_save(..)
  }
}

I think 99% of Drupal sites have the menu module enabled, so moving the creation of menu_custom table to system.install is still an option, to make the code cleaner.. If it is too much here, then a new issue should be created, and menu_save() and menu_delete() should be moved back to menu.module for this patch..

dropcube’s picture

I think 99% of Drupal sites have the menu module enabled, so moving the creation of menu_custom table to system.install is still an option, to make the code cleaner..

No. On the contrary, each module should be responsible of installing it's own tables and stuff, handling it's updates, etc... I don't want that table created if I don't 'want' menu.module enabled in my application/site/install profile, etc... Well, that's not the point of that issue.

@Pasqualle, can we mark one the patchs in this issue as RTBC ? Code freeze is here ;). It's a valuable addition, and it's is a really simple patch. So, let's go on.

Pasqualle’s picture

as I see #31 is the closest to RTBC, I will just move the functions back to menu.module..

Pasqualle’s picture

dropcube’s picture

FileSize
7.98 KB

I think it's ready to go.

- Updated the tests to check that all menu links associated to a menu were removed from database when then menu is deleted.

amitaibu’s picture

I've added a test to the custom_menu_delete()

dropcube’s picture

Status: Needs review » Reviewed & tested by the community

Ok, all test passed. I think it is RTBC.

amitaibu’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
7.92 KB

hmm, it didn't upload my patch.

amitaibu’s picture

FileSize
7.95 KB

* Test from #40 was already covered.
* Fixed a query placeholder (menu_name >> :menu_name)
* Fixed a typo in the toolbar.install (Admininstration >> Administration).

dropcube’s picture

Status: Needs review » Reviewed & tested by the community
pwolanin’s picture

Category: task » feature

This looks sensible - it should indeed be in menu module, and an API for this is one of those things that we just didn't have time for in D6.

Status: Reviewed & tested by the community » Needs work

The last submitted patch failed testing.

lilou’s picture

Status: Needs work » Reviewed & tested by the community
webchick’s picture

Status: Reviewed & tested by the community » Needs work
+++ modules/menu/menu.module	30 Aug 2009 07:00:56 -0000
@@ -496,3 +496,38 @@
+/**
+ * Save a custom menu.
+ *
+ * @param $custom_menu
+ *   The custom menu array. Keys are:
+ *   - menu_name    Unique key for menu.
+ *   - title        Menu title; displayed at top of block.
+ *   - description  Menu description.
+ */
+function menu_custom_save(array $custom_menu) {

If those are the only keys, I think I'd prefer to enumerate the parameters ($name, $title, $description). That'd be more user-friendly for people using IDEs.

Also, I'd prefer names like menu_save_custom_menu() and menu_delete_custom_menu() since they're more descriptive.

+++ modules/menu/menu.test	30 Aug 2009 07:01:00 -0000
@@ -87,6 +87,34 @@
+  /**
+   * Add custom menu using API.
+   */
+  function addCustomMenuApi() {

That function name is confusing; it makes it sound like you're adding your own custom menu API. :P Maybe add a Via or With or something in there to make it more clear?

+++ modules/menu/menu.test	30 Aug 2009 07:01:00 -0000
@@ -87,6 +87,34 @@
+    $menu_name = substr(md5($this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI);

Why 16 and not a constant like you have with MENU_MAX_MENU_NAME_LENGTH_UI?

I'm on crack. Are you, too?

amitaibu’s picture

Status: Needs work » Needs review
FileSize
7.14 KB

Patch addresses #46 comments.

> Why 16 and not a constant like you have with MENU_MAX_MENU_NAME_LENGTH_UI?

I kept it as is, to follow addCustomMenu() which uses '16'. I went over quickly on other tests and saw the use of explicit numbers (testPagePreviewWithRevisions() in node.test for example).

pwolanin’s picture

Should we not call the functions menu_custom_menu_save()? Generally we put the verb last like, node_save(), menu_link_save(), etc.

pwolanin’s picture

Status: Needs review » Needs work
Issue tags: +API clean-up

see above - let's be more consistent in terms of funciton naming. Otherwise this is essentially done

sun’s picture

@webchick: That's inconsistent.

I agree with pwolanin in #48. We always use the pattern [object]_[action]() for CRUD functions in core.

We also use single arguments for CRUD functions throughout core. Only the loader function usually takes an ID instead of an object.

And we already have http://api.drupal.org/api/search/7/menu_load --

Hence, I don't see why these couldn't be simply named menu_save() and menu_delete() ? Only the last one needs a special validation to not delete system menus.

Anything else would be a DrupalWTF.

pwolanin’s picture

@sun - the table is {menu_custom} and there MUST be a significant distinction made between what these functions are operating on and hook_menu, hook_menu_alter, which are operating on the router.

so, I'd suggest going back to menu_custom_save() or menu_custom_menu_save(), or something like that.

sun’s picture

Assigned: dropcube » sun
sun’s picture

Status: Needs work » Needs review
FileSize
15.31 KB

Alright, so our [object] is 'menu_custom'. ++consistency

Here we go.

dropcube’s picture

+++ modules/menu/menu.module	24 Sep 2009 01:43:37 -0000
@@ -198,12 +198,68 @@ function menu_overview_title($menu) {
+  // Delete all links from the menu.
+  db_delete('menu_links')
+    ->condition('menu_name', $menu['menu_name'])
+    ->execute();

I think we should use API function menu_link_delete here, mainly because it invokes hook_menu_link_delete(), but this function also clear caches, update parental status for menu links, etc... so that may be an expensive operation. Thoughts ?

sun’s picture

aha! I think that's the same mess that's happening in http://api.drupal.org/api/function/menu_delete_menu_confirm_submit/7 before the menu is deleted? ;)

sun’s picture

Assigned: sun » Unassigned

Doesn't seem so. However, we could load all items before deleting them and invoke hook_menu_link_delete() manually.

We should additionally clear the caches in the API function to make it consistent with other CRUD functions.

Interesting: http://api.drupal.org/api/function/menu_delete_menu_confirm_submit/7 and http://api.drupal.org/api/function/_menu_delete_item/7 invoke different functions to clear the caches.

pwolanin’s picture

Did Rickard's hook get in to act each time we delete a menu link?

If the cache is already clear, additional calls to clear it shoudl be relatively fast right? Deleting should be a very rare operation.

sun’s picture

Since we need to fetch the list of items anyway, we could simply set $item['plid'] = 0 and $item['has_children'] = FALSE before invoking _menu_delete_item(), so we skip the expensive and senseless operations here:

- Re-parenting of children

- _menu_update_parental_status() [which somehow looks very similar to _menu_delete_item()'s re-parenting, just acting on a different column... but anyway]

I also see that both cache clearing functions invoked by _menu_delete_item() take special care for multiple invocations:

http://api.drupal.org/api/function/menu_cache_clear/7
http://api.drupal.org/api/function/_menu_clear_page_cache/7

Which means that we actually do not have to clear the cache on our own, since _menu_delete_item() will clear all caches in case the menu contained some links.

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review

Disabled slave #44, since it returned strange results for a couple of patches.

sun’s picture

sun’s picture

Anyone up for approving this patch?

pwolanin’s picture

Does it make sense to use the API function during the install hook?

sun’s picture

Of course! It's the main reason why we want to do this after all: Stop writing raw stuff into the database and use proper API functions instead.

Instead of questioning this, we should move forward, and provide and use more API functions in installers/uninstallers and installation profiles. Text formats, filters, user roles, user permissions, and with this patch also custom menus can finally all be handled with proper functions instead of raw database queries.

pwolanin’s picture

+ * Delete a custom menu.

The _delete function doxygen is incomplete - it should make very clear that it both deletes the custom menu AND all menu links associated with that custom menu.

sun’s picture

Clarified PHPDoc - although we aren't so verbose in other API functions that delete user data...

Needed re-roll due to #508570: Restore URL consistency for node types and menus anyway... :)

Status: Needs review » Needs work

The last submitted patch failed testing.

pwolanin’s picture

Well, we don't necessarily delete lots of other data do we? e.g. if I delete a user, I think their content is may be retained.

sun’s picture

Status: Needs work » Needs review
FileSize
18.73 KB

Fixing the tests as well. :)

Dave Reid’s picture

Subscribing. This is so very handy for some contrib modules (devel, admin_menu, etc).

Dave Reid’s picture

+++ modules/menu/menu.api.php	29 Sep 2009 01:04:06 -0000
@@ -220,5 +220,57 @@ function hook_menu_link_delete($link) {
+ * @return
+ *   None.

Pretty sure we don't document @return if there is no return value.

This review is powered by Dreditor.

Dave Reid’s picture

Status: Needs review » Needs work
sun’s picture

Status: Needs work » Needs review
FileSize
19.34 KB
Dave Reid’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, bot likes and lots of concern has gone into this.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

node_save()
user_save()
comment_save()
menu_custom_save()

"One of these things is not like the other...."

I don't like "custom" being in the function name:

1) These are not for just "custom" menus, but also system-defined menus such as Navigation, Management, etc.
2) As a developer, the function I'm going to search api.drupal.org for is "menu_save", for compatibility with our other CRUD API function names. When I don't find it, I'm going to resort to db_insert() and db_delete() like our .profile file currently does.
3) Our functions map to the data concept, not to the table name. It's not users_save() even though the table is called users. It's not node_revisions_save(). Etc.

If anything, I'd rename the menu_custom table to menu if we really care about the discrepancy. But the number of people with innate knowledge of Drupal's DB internals vs. those searching through api.drupal.org is probably a 1:10000000 ratio, so I'm not that fussed about it.

sun’s picture

First of all, straight re-roll due to conflicts.

sun’s picture

Status: Needs work » Needs review
FileSize
16.31 KB

I agree with webchick, and I already wondered when I saw the naming request above (which didn't contain any reasoning).

I double-checked that these function names do not clash with other functions.

sun’s picture

chx additionally asked in IRC, why we don't follow the usual hook_*_insert() and hook_*_update() pattern here. I replied that we couldn't, because we don't know.

But sleeping over that question helped.

Given this patch, we might even remove that man-made limitation in a follow-up issue.

RobLoach’s picture

Applied the patch, played around in the menu administration, added some menu items, deleted others. Looked at the code and really liked how clean it made the code. The thing I like most about it is how it moves the Block Menu handling code from the Menu module into the Block module. I'm inclined to set this to RTBC, but chx said he wanted to discuss some stuff. So, in the mean time, I'll just subscribe.

sun’s picture

chx requested to squeeze a @todo into menu_save() to remind us to replace that 'old_name' condition with the proper db_merge() result, which should tell us whether the query inserted or updated something, which is currently not the case.

So this patch should be ready to fly.

Dave Reid’s picture

+++ modules/menu/menu.module	6 Oct 2009 20:52:27 -0000
@@ -198,12 +198,98 @@ function menu_overview_title($menu) {
+  db_merge('menu_custom')
+    ->key(array('menu_name' => $menu['menu_name']))

If we're renaming an existing menu, won't this create a new record instead of updating the old one? Shouldn't the merge be on $menu['old_name']? Do we test when this happens?

I'm on crack. Are you, too?

sun’s picture

@DaveReid:

+++ modules/menu/menu.api.php	6 Oct 2009 20:49:04 -0000
@@ -358,5 +358,77 @@ function hook_menu_link_delete($link) {
+ * @param $menu
...
+ *   - old_name: The current 'menu_name'. Note that internal menu names cannot
+ *     be changed after initial creation.
...
+function hook_menu_update($menu) {
+++ modules/menu/menu.module	6 Oct 2009 20:52:27 -0000
@@ -198,12 +198,98 @@ function menu_overview_title($menu) {
+function menu_save($menu) {
...
+  // Since custom menus are keyed by name and their machine-name cannot be
+  // changed, there is no real differentiation between inserting and updating a
+  // menu. To overcome this, we define the existing menu_name as 'old_name' in
+  // menu_edit_menu().

What's unclear here?

Dave Reid’s picture

Status: Needs review » Reviewed & tested by the community

@tha_sun: Listen up kids, don't drink and review!

My only concern is taken care of, code is good, love the APIs, test bot likes...RTBC'd!

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs documentation

Good stuff. Committed to HEAD!

This needs to be documented in the upgrade guide.

amitaibu’s picture

Status: Needs work » Needs review

It seems I can't edit the convert 6 to 7 page, so here's it is. Someone with better English should go over it :)

---

In Drupal 6 in order to create a custom menu (i.e. a menu you would create via admin/build/menu/add) you had to query the {menu_custom} table yourself.

In D7 several API functions to create, update and delete custom menus and related hooks were added.


function foo() {
  $menu = array(
    'title' => 'My menu',
    'menu_name' => 'my_menu',
    'description' => 'My custom menu',
  );
  // Add a new custom menu.
  menu_save($menu);

  // Delete the custom menu.
  // Although only the 'menu_name' key is required, we pass the full
  // $menu, so other modules may act on it.
  menu_delete($menu);
}

function foo_menu_delete($menu) {
  if ($menu['menu_name'] == 'my_menu') {
    drupal_set_mesasge(t('You have deleted the foo custom menu.'));
  }
}

Priority: Critical » Normal

The last submitted patch failed testing.

salvis’s picture

Category: feature » bug
Priority: Normal » Critical
Status: Active » Needs review
FileSize
687 bytes

[EDIT: This has become obsolete — skip to #473082-105: Add custom menu API]

Has anyone actually run this?

function menu_delete($menu) {
  // Delete all links from the menu.
  $links = db_query("SELECT * FROM {menu_links} WHERE menu_name = :menu_name", array(':menu_name' => $menu['menu_name']));
  foreach ($links as $link) {
    // To speed up the deletion process, we reset some link properties that
    // would trigger re-parenting logic in _menu_delete_item() and
    // _menu_update_parental_status().
    $link['has_children'] = FALSE;
    $link['plid'] = 0;
    _menu_delete_item($link);
  }

  // Delete the custom menu.
  db_delete('menu_custom')
    ->condition('menu_name', $menu['menu_name'])
    ->execute();

  module_invoke_all('menu_delete', $menu);
}

This crashes because $link is an object. The attached patch fixes it.

Dave Reid’s picture

Category: feature » bug
Priority: Normal » Critical
Status: Needs review » Needs work

@salvis: That's not going to work because _menu_delete_item() expects an array.

salvis’s picture

Status: Needs work » Needs review

@Dave Reid: Look at the code of _menu_delete_item(). I did run it...

Dave Reid’s picture

Well we could avoid the additional array -> object processing if we just fetch objects. For large menus maybe it would make a difference.

salvis’s picture

Yes, for those sites that keep deleting menus day in and day out over and over again. ;-)

I actually tried PDO::FETCH_ASSOC, but I prefer nice and clean code.

sun’s picture

FileSize
902 bytes

There you go.

Now we need tests.

Status: Needs review » Needs work

The last submitted patch failed testing.

salvis’s picture

FileSize
687 bytes

@sun:

What you meant was

  $links = db_query("SELECT * FROM {menu_links} WHERE menu_name = :menu_name", array(':menu_name' => $menu['menu_name']), array('fetch' => PDO::FETCH_ASSOC));

but as I said, I prefer #87. It's easier to get right, easier to read, it builds on the chosen default behavior of db_query() and thus helps to reinforce the fact that we get back objects by default.

Adding obscure flags in obscure places keeps us from developing a natural code flow, as you've demonstrated very nicely.

Setting back to needs review for #87.

salvis’s picture

Status: Needs work » Needs review
Berdir’s picture

@salvis

While your code might look cleaner, there was a decision to use arrays inside menu.inc/menu.module. Not very concistent with the rest of core, I know, but now is probably not the right time to change that.

sun’s picture

By all means, PDO fetch modes are not obscure at all. You are just not used to them - but you definitely will in D7. We use them in many more places throughout core.

Whether ->fetch() or using third argument to db_query() doesn't matter for me. Maybe Berdir can clarify about which of both "should rather" be used. :)

salvis’s picture

@sun: You didn't get it to work in two attempts. That tells me it's too difficult to get right. Can't you see that?

pwolanin’s picture

Status: Needs review » Needs work

menu links and router items should always be arrays - this was a D6 core design decision. you can argue if it's wrong, but then you need to change all of the rest of core to match.

salvis’s picture

Status: Needs work » Needs review
FileSize
1.97 KB

Ok, if that's how we want to have it...

salvis’s picture

FileSize
882 bytes

Oops, sorry, wrong file...

pwolanin’s picture

looks fine

webchick’s picture

Let's get a test for this.

Status: Needs review » Needs work

The last submitted patch failed testing.

salvis’s picture

Category: bug » feature
Priority: Critical » Normal
Status: Needs work » Active

Committing #511286: D7UX: Implement customizable shortcuts fixed the bug I reported in #87 above — thanks.

I'm resetting the flags to what they were in #87 (#473082-85: Add custom menu API) above, except NR would fall back to NW right away. That's where we stand now.

@Amitaibu: Can you pick it up again, please?

amitaibu’s picture

Category: bug » feature
Priority: Critical » Normal
Status: Needs review » Active

I either need to get rights to add the docs + code example from #85, or someone with those rights should do it.

sun’s picture

Status: Active » Needs work
Issue tags: +Needs tests
amitaibu’s picture

Can anyone grant me access to add the docs from #85?

webchick’s picture

I just fixed the permissions again on http://drupal.org/update/modules/6/7, you should be good to go. Thanks, Amitaibu!

amitaibu’s picture

catch’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

sun’s picture

Category: feature » task
Status: Closed (fixed) » Needs review
FileSize
1.89 KB

Just noticed that Damien included a fix for the introduced workaround here in #576290: Breadcrumbs don't work for dynamic paths & local tasks

Let's rather fix it here.

Pasqualle’s picture

I guess in (menu.admin.inc) menu_edit_menu() the $form['old_name'] should be removed also..

sun’s picture

I considered that but didn't remove those, because I wasn't sure whether they might be helpful for hook implementations. Not sure. For now, I'd prefer to go without removing them.

Pasqualle’s picture

Status: Needs review » Reviewed & tested by the community

ok, the patch is good

I do not understand why the return value of db_merge is not documented
http://api.drupal.org/api/function/db_merge/7

sun’s picture

.

pwolanin’s picture

#113: drupal.menu-custom-dbmerge.patch queued for re-testing.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Committed to HEAD. Thanks!

Status: Fixed » Closed (fixed)
Issue tags: -Needs tests, -DX (Developer Experience), -Needs documentation

Automatically closed -- issue fixed for 2 weeks with no activity.