To explain this title a little bit...

What I am trying to accomplish here is to hook on the "create product page" event. Or in other words - when a user creates his/her own product page (I'm using Ubercart Marketplace), I would like to detect if the entered product name is already stored in the default Ubercart SQL table and if so, to duplicate (or simple store) this new product info (price and SKU) to different SQL table and to display them beneath the product info on the product page.

I would just need some guidance for the start, how and with what code from Drupal API could I connect to the "create product page" EVENT? Any ideas, links or suggestions?

Thanks!

Comments

nevets’s picture

I would create a module that implements hook_nodeapi() and the case where $op equals 'submit' and 'view'. As part of this I would implement a custom table (using the modules .install file) that has two columns, 'nid' and 'related_nid'. In the case of 'submit' I would check to see if is a duplicate and if so I would add/update a record in the table with 'nid' being the node currently being saved and 'related_nid' being the existing product this duplicates. In the case of 'view' I would check in the table to see if there is a record and if so add the desired information to the nodes content (for viewing).

Drug-pal’s picture

Hook_nodeapi is definitely what I needed here, thanks! I already have in mind what I want to do with the tables and how to name them but thanks a lot for the insight!

Drug-pal’s picture

I have a problem with the further development of my module so I am "unsolving" this topic to avoid opening multiple topics with same related problems, I hope this is not a wrong thing to do here?

So, first step was to use hook_nodeapi and to hook on event with it. That was not a problem, I used this hook to connect with the "product page creation" event. For testing purposes I used case "insert" (I'll later use case "presave"). What I am trying here is to check if there is any content in the SQL table and to DSM 'true' or 'false' message into product page node. Once I do that I plan to make the search through my table data in order to check if the newly entered term (product name) already exists and then save it (presave case) to the new table.

So, here is the code with which I am trying to get the 'true' DSM:


  function module_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
    
     if ($op == 'insert' && $node->type == 'product') {
        switch($op){

        case 'insert':
    
            function module_duplicate_checker() {
    
                $result = db_query("SELECT title FROM {node} WHERE title = %s");
    
                 while ($data = db_fetch_object($result)) {
                 $data->title;
              } 
    
                return db_result($result);
   }
              
          if (!empty($result)) {    // if any data in $result
             return dsm('$result contains data!');  // TRUE
           }
  
          else {
            return dsm('FALSE!');
           }
  
          break;


        case 'view':
       
          return dsm('Hello View!');
        
          break;
 
     }
   }
 }

I keep getting FALSE message, is my syntax alright here?

da_solver’s picture

Hi,
You've declared a function inside a function. Unusual for Drupal, but apparently OK per php.net http://php.net/manual/en/functions.user-defined.php.

How are you diagnosing this issue? Are you looking at the intermediate results? You've declared a function module_duplicate_checker(). However you aren't calling it. What's the logic supposed to be? Why declare a function, but then not call it (I.E. use it) ?

I would strongly recommend you use a normal source code debugger like XDEBUG. Trying to diagnose a "process" issue with "data" dumps is getting you nowhere fast. If you use a normal source code debugger, issues of "process" are diagnosed right away.

Hope that helps :)

Drug-pal’s picture

So, you say I should avoid using functions inside of other functions while programming in PHP? I'm new in PHP so any advice as such is welcome. :)

As for module_duplicate_checker function, it should return SQL results data; "return db_result($result);" which would be used in the IF function. What exactly did I do wrong with it?

I have a strange problem when debugging Drupal modules. No matter where I put the breakpoint(s), when I click on debug project button it always opens index.php page and marks the "require_once './includes/bootstrap.inc';" line? Can you explain to me what am I doing wrong here?

nevets’s picture

This code is buggy

            function module_duplicate_checker() {
   
                $result = db_query("SELECT title FROM {node} WHERE title = %s");
   
                 while ($data = db_fetch_object($result)) {
                 $data->title;
              }
   
                return db_result($result);
   }
             
          if (!empty($result)) {    // if any data in $result
             return dsm('$result contains data!');  // TRUE
           }
 
          else {
            return dsm('FALSE!');
           }

Besides be unconventional since it declares a function in a function, module_duplicate_checker() is never called. I suspect you want something like for the insert case

$result = db_query("SELECT title FROM {node} WHERE title = %s");
if ( empty($result) ) {
  dsm("No match");
}
else {
  while ($data = db_fetch_object($result)) {
    dsm("Title: $data->title");
}
Drug-pal’s picture

Yes, that code was just what I needed! Although I had to change the "SELECT title FROM {node} WHERE title = %s" to "SELECT title FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')" in order to make it work.

Can you please tell me what is the best way to go through those titles and compare them with the field entry in order to get the positive duplicated entry check? Should I use foreach or? I was searching for some code examples that I could use to solve this, but no such luck. And unfortunately my PHP knowledge is still limited, although I am constantly learning. :)

nevets’s picture

I would think title = '%s' or LOWER(title) = LOWER('%s') if you want to check for an exact match (or in the later case if you do not care about case). (The original code is missing the single quotes).

Drug-pal’s picture

I see, but how can I get, for example, dsm("No match") ONLY if the entered term has no duplicate/twin already stored in the database? For now I get that dsm message if the SQL is empty (no entries at all).

Also, in ELSE statement I need to get dsm("$data->title") of that duplicated item only.

nevets’s picture

If you use an equal sign (=) and not LIKE you should only get records returned when they match.

Drug-pal’s picture

So, I tried 4 different code lines.

1. "SELECT title FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')" - As said before, it shows all product titles after I submit the form.

2. "SELECT title FROM {node} WHERE LOWER(title) = LOWER('%s%%')" - Nothing happened expect the standard product creation action with no additional messages.

3. "SELECT title FROM {node} WHERE title LIKE '%s'"

4. "SELECT title FROM {node} WHERE title = '%s'"

When using 3 and 4, same thing happens: DSM shows only the blank titles (titles of products with no name entered in the Name field).

Here is the complete code, just in case:


function module_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
    
    if ($op == 'presave' && $node->type == 'product') { 
       switch($op){

     case 'presave':
         
        
     $result = db_query("SELECT title FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')"); // - the line I have been changing
         
          if ( empty($result) ) {
             dsm("No match");

          }

          else {
             while ($data = db_fetch_object($result)) {
             dsm("$data->title");
          }
    }       
  
     break;

     
     case 'view':
       return dsm('Hello View!');
        
         
     break;
 
     }
   }
 } 

nevets’s picture

Ok, I missed this last time, you need to pass the title to db_query you want to search for, like

     $result = db_query("SELECT title FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')", $node->title);
Drug-pal’s picture

Yes, that was it! One last thing (for now), can you please tell me how to make only the first title from the title list to be displayed? So that no matter if I have 1 or 1 million duplicates, users will see only one duplicate title instead of all the titles which are actually the same. Also, a cool bonus would be a number of products by that name already in the database like so: %title has %num matches in the databse.

nevets’s picture

You could change

          if ( empty($result) ) {
             dsm("No match");

          }

          else {
             while ($data = db_fetch_object($result)) {
             dsm("$data->title");
          }
    }

to

          if ($data = db_fetch_object($result)) {
             dsm("$data->title");
          }
          else {
              dsm("No match");
          } 

If those are response the user sees I would suggest using drupal_set_message() instead of dsm()

Drug-pal’s picture

Thanks a ton, good job as always! :)