在PHP和MySQL中级联WHERE子句

时间:2017-08-29 15:24:39

标签: php mysql

我正在寻找有关我的解决方案的反馈,因为我在这个项目中有点过头了。这是在Wordpress中。我从标准wp_postwp_postmeta表中抓取。我正在编写与另一个程序的接口,因此可以在Wordpress消息传递应用程序和我的练习管理软件之间共享数据。此功能清除消息,然后在线程清除完毕后发送方和接收方都标记要删除的消息后,将其永久删除。

我有一种情况需要使用不同的WHERE子句级联长时间重复的MySQL SELECT语句。我尝试了两次使用$query语句,但最终只是将where语句添加到彼此之上。我的解决方案是,第二次在$query变量中复制我的SELECT语句,然后连接这样的WHERE子句:

function action_delmessage($messageid) {
  global $wpdb, $out, $admin_user_login;
  // Get message attributes so we can figure out what to do.

  //Current provider ID 
  $curID = convertToID($admin_user_login);

  $query =  "SELECT uf.user_login AS from_login, ut.user_login AS to_login, pm_clear.meta_key AS clear_p, " .
        "pm_delete1.meta_key AS delete_1 , pm_delete2.meta_key AS delete_2, pm_to.post_id AS parent " .
        "FROM {$wpdb->prefix}posts AS p " .
        "JOIN $wpdb->postmeta pm_to " .
        "ON ((p.post_parent = pm_to.post_id AND p.post_parent <> 0) " .
        "OR (p.id = pm_to.post_id AND p.post_parent = 0)) " .
        "AND pm_to.meta_key = '_fep_participants' " .
        "AND pm_to.meta_value <> p.post_author " .
        "LEFT JOIN $wpdb->postmeta AS pm_delete1 " . 
        "ON ((pm_delete1.post_id = p.post_parent AND pm_delete1.meta_key = CONCAT('_fep_delete_by_', p.post_author) ) " . 
        "OR (pm_delete1.post_id = p.id AND pm_delete1.meta_key = CONCAT('_fep_delete_by_', p.post_author) )) " . 
        "LEFT JOIN $wpdb->postmeta AS pm_delete2 " . 
        "ON ((pm_delete2.post_id = p.post_parent AND pm_delete2.meta_key = CONCAT('_fep_delete_by_', pm_to.meta_value) ) " . 
        "OR (pm_delete2.post_id = p.id AND pm_delete2.meta_key = CONCAT('_fep_delete_by_', pm_to.meta_value) )) " . 
        "LEFT JOIN wp_postmeta AS pm_clear " .
        "ON ((pm_clear.post_id = p.post_parent AND pm_clear.meta_key = CONCAT('_oemr_fep_clear_', p.id)) " .
        "OR (pm_clear.post_id = p.id AND pm_clear.meta_key = CONCAT('_oemr_fep_clear_', p.id))) " .
        "LEFT JOIN $wpdb->users AS uf ON uf.ID = p.post_author " .
        "LEFT JOIN $wpdb->users AS ut ON ut.ID = pm_to.meta_value ";
    $query2 = $query;

    $query .= "WHERE p.id = %d";

  $row = $wpdb->get_row($wpdb->prepare($query, array($messageid)), ARRAY_A);
  if (empty($row)) {
    $out['errmsg'] = "Cannot delete, there is no message with ID $messageid.";
    return;
  }

  $parent = $row['parent'];
  $timestamp = idate("U"); 

  if ($row['from_login'] == $admin_user_login) {
      //clear the record if admin is from
      add_post_meta($messageid, '_oemr_fep_clear_' . $messageid, $timestamp);
  }   

  else if ($row['to_login'] == $admin_user_login) {
      //clear the record if admin is to
      add_post_meta($messageid, '_oemr_fep_clear_' . $messageid, $timestamp);
  } 

  $query2 .=  "WHERE (p.id = %d OR p.post_parent = %d) AND pm_clear.meta_key IS NULL AND p.post_type <> 'attachment'";

  $row2 = $wpdb->get_row($wpdb->prepare($query2, array($parent, $parent)), ARRAY_A);

  if (empty($row2)) {
      add_post_meta($parent, '_fep_delete_by_' . $curID, $timestamp);
  }


    $row3 = $wpdb->get_row($wpdb->prepare($query, array($parent)), ARRAY_A);

  if (($row3['delete_1'] !== NULL) && ($row3['delete_2'] !== NULL)) {
    $query4 = $wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts " .
    "WHERE (ID = %d OR post_parent = %d) and post_type = 'fep_message'", $parent, $parent);
    $row4s = $wpdb->get_results($query4, ARRAY_A);
    foreach ($row4s as $row4) {
        $query5 = $wpdb->prepare("SELECT ID, post_mime_type, guid " .
        "FROM {$wpdb->prefix}posts " .
        "WHERE post_parent = %d AND post_type = 'attachment'", $row4['ID']);
        $row5s = $wpdb->get_results($query5, ARRAY_A);
        foreach ($row5s as $row5) {
            $url = $row5['guid'];
            $filename = basename($url);
            $path  = parse_url($url, PHP_URL_PATH); // just the path part of the URL
            $parts = explode('/', $path);           // all the components
            $parts = array_slice($parts, -6);       // the last six
            $path  = implode('/', $parts);  
            $filepath = ABSPATH . $path;
            unlink($filepath); //Delete the file from the server.
            $wpdb->query($wpdb->prepare("DELETE p FROM {$wpdb->prefix}posts AS p WHERE p.id = %d",$row5['ID']));            
        }
        $wpdb->query($wpdb->prepare("DELETE p, pm FROM {$wpdb->prefix}posts AS p " .
        "INNER JOIN {$wpdb->prefix}postmeta AS pm ON pm.post_id = p.ID " .
        "WHERE p.ID = %d OR p.post_parent = %d AND pm.post_id = %d",$row4['ID'],$row4['ID'],$row4['ID']));
    }
  }  
}

这是我的hacky解决方案。我想知道管理这些级联WHERE语句的正确方法。我在想,我将$query复制到$query2的方式与再次写出select语句基本相同,可能不是完成工作的最有效方法。或者,我真的偶然发现了一个合理的解决方案吗?

0 个答案:

没有答案