Create trigger for adding new users to wordpress - php

I need to add a users full name to the buddy press extended profile field every time a new user is created. This is normal functionality, but we are syncing users from Active Directory and when that ran users names are not being populated. I have created a SQL query that works for combining first and last name and updating it to where i need. My issue comes when trying to create a trigger in phpMyAdmin.
This is the error i receive:
The following query has failed:
CREATE TRIGGER `update users`
AFTER UPDATE ON `wp_bp_xprofile_data`
FOR EACH ROW
CREATE TEMPORARY TABLE user_data AS
SELECT u.user_id
, (SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'first_name' LIMIT 1) AS first_name
, (SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'last_name' LIMIT 1) AS last_name
, (SELECT `value` FROM wp_bp_xprofile_data WHERE user_id = u.user_id AND field_id = '1' LIMIT 1) AS bp_name
, (SELECT CONCAT(first_name, ' ', last_name)) AS full_name
FROM wp_bp_xprofile_data u ;
UPDATE wp_bp_xprofile_data u JOIN user_data b ON u.user_id=b.user_id
SET u.value=b.full_name;"
MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE wp_bp_xprofile_data u JOIN user_data b ON u.user_id=b.user_id ' at line 12
Here is the code i used.
CREATE TEMPORARY TABLE user_data AS
SELECT
u.user_id,
(SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'first_name' LIMIT 1) AS first_name,
(SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'last_name' LIMIT 1) AS last_name,
(SELECT `value` FROM wp_bp_xprofile_data WHERE user_id = u.user_id AND field_id = '1' LIMIT 1) AS bp_name,
(SELECT CONCAT(first_name, ' ', last_name)) AS full_name
FROM
wp_bp_xprofile_data u
;
UPDATE wp_bp_xprofile_data u
JOIN user_data b
ON u.user_id=b.user_id
SET u.value=b.full_name;
Trigger Inputs

You haven't entered a BRGIN or ENd
Try
DELIMITER //
CREATE TRIGGER `update users`
AFTER UPDATE ON `wp_bp_xprofile_data`
FOR EACH ROW
BEGIN
CREATE TEMPORARY TABLE user_data AS
SELECT u.user_id
, (SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'first_name' LIMIT 1) AS first_name
, (SELECT meta_value FROM wp_usermeta WHERE user_id = u.user_id AND meta_key = 'last_name' LIMIT 1) AS last_name
, (SELECT `value` FROM wp_bp_xprofile_data WHERE user_id = u.user_id AND field_id = '1' LIMIT 1) AS bp_name
, (SELECT CONCAT(first_name, ' ', last_name)) AS full_name
FROM wp_bp_xprofile_data u ;
UPDATE wp_bp_xprofile_data u JOIN user_data b ON u.user_id=b.user_id
SET u.value=b.full_name;
END //
DELIMITER ;
But i am not sure that trigger will even work, it only removes the syntax errors.
As far as i know, you can't update the table that invoked the Trigger, because your update would also invoke a new trigger and so on.

Related

Specify columns in INNER JOINed table

comment table and post table both has column named user_id
I cannot specify both table's user_id
for using some if else condition later I need both the user_id as a different name (I'm trying to use AS).
I tried different way but query not working:
$sql="SELECT `post_id`, `comment_id`, `comment`, `user_id`, `username`,
`is_marked` `post`.`user_id` AS `p_uid` FROM `comment` INNER JOIN `user` ON
`comment`.`user_id` = `user`.`id` INNER JOIN `post` ON
`user`.`id`=`post`.`user_id` ORDER BY `comment_id` DESC";
$result = mysqli_query($con, $sql);
if ($result) {
while ($row=mysqli_fetch_assoc($result)) {
$post_user_id = $row['p_uid'];
You could alias table name with other name and get column. View example:
SELECT C.comment_id, U.user_id
FROM comment C INNER JOIN user u ON C.user_id = U.id
I would do:
SELECT c.post_id,
c.comment_id,
c.comment,
c.user_id AS c_uid,
c.username,
c.is_marked,
p.user_id AS p_uid
FROM comment c
INNER JOIN user u ON c.user_id = u.id
INNER JOIN post p ON c.user_id = p.id
ORDER BY c.comment_id DESC
Define aliases for the tables, and the selected fields. It makes it simpler to read than putting the table names all the time.
In your PHP you can then reference $row['c_uid'] or $row['p_uid'].

MYsql Query Error Join with Group by not working

Table -1 : Comment id, comment,user_id,comment Date
Table -2: Users id, user_name, full_name, password
now i want to get user detaiils records who is last comment
like
query is :
select c.*,
(select user_name
from users
where id = c.user_id
) as user_name,
(select full_name
from users
where id = c.user_id
) as full_name
from comment as c, users as u
group by c.user_id
order by comment_date DESC
SELECT Users.*,
Comment.*
FROM Users
INNER JOIN Comment ON (Comment.user_id = Users.id)
GROUP BY Users.id
ORDER BY Comment.id DESC
that should work
Here is your query
select users.* from users inner join comments on
users.user_id = comments.user_id
order by comments.comment_date desc limit 1
Another way to do this
select * from users where user_id =
(select user_id from comments order by comment_date desc limit 1)

Sort mysqli from a many-to-many table

I'm trying to make a internal web based message system, with a *amp system, primarily for learning purposes. I don't know if this is a trivial topic, but I'm having difficulties so please bear with me.
The goal is to list all the contacts ordered by the last message sent / received.
Currently without sorting it the SQL looks like this
$query = "SELECT username, user.id as user_id,
(SELECT COUNT(message_read)
FROM message_user
WHERE message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM user
WHERE user.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
;";
The structure of the tables are:
The user table has an id,
That links to the message_user table which has a sent_id and a receive_id,
The message_user has a message_id that corresponds to the message.id,
The message table has a timestamp.
I would like this to be done in SQL but if it comes down to PHP I resign to resort to that.
This works.
SELECT `u`.`id` AS user_id, username,
(SELECT COUNT(message_user.message_read)
FROM message_user
WHERE message_user.message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu`
ON
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`sent_id`
WHEN `mu`.`sent_id` = {$userId} AND `mu`.`receive_id` = {$userId}
THEN `u`.`id` = `mu`.`sent_id`
END)
OR
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`receive_id`
END)
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
WHERE u.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
GROUP BY u.id
ORDER BY MAX(`m`.`timestamp`) DESC;
This broke down the problem I was having.
#Andreas thanks for time and help.
Use 2 LEFT JOIN with a DISTINCT (untested):
SELECT DISTINCT `u`.`id`
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu` ON `u`.`id` = `mu`.`sent_id` OR `u`.`id` = `mu`.`receive_id`
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
ORDER BY `m`.`timestamp` DESC;

How to speed up this MySQL query? Latest messages query

i need speed up this query for list latest messages. This query running too long (eg. 10 seconds ...)
SELECT datas.uid,
datas.message,
datas.date,
CONCAT(conv.first_name, ' ', conv.last_name) AS conversation_name
FROM (SELECT m.message_id,
m.message,
IF (m.from_uid = 1, m.to_uid, m.from_uid) AS uid,
m.readed,
m.sended AS `date`
FROM users u
LEFT JOIN messages m
ON m.from_uid = u.user_id
WHERE m.message_id IN (SELECT MAX(message_id)
FROM messages
WHERE to_uid = 1
OR from_uid = 1
GROUP BY LEAST(from_uid, to_uid),
GREATEST(from_uid, to_uid))) datas
LEFT JOIN users conv
ON conv.user_id = datas.uid
ORDER BY datas.date DESC
LIMIT 5
This query use 2 tables (users and messages).
Table users:
user_id (primary, autoincrement)
login
pass
first_name
last_name
....
Table messages:
message_id (primary, autoincrement)
from_uid (sender message, reference to table users -> user_id)
to_uid (receiver message, reference to table users -> user_id)
sended (timestamp)
message (varchar)
EDIT
I added indexes to messages:
- from_uid
- to_uid
- sended
and this is without efect...
Try creating indexed on the id's you're checking.
In this case you might want to create an index on: conv.user_id, datas.uid, m.message_id, messages.to_uid, messages.from_uid, and datas.date might be a good idea as well, since you're sorting on that.
Add indexes on from_uid and to_uid to speed up the SELECT MAX(message_id) subquery. Otherwise, it has to do a full scan of the table.
I would try and remove the sub query(s)
You can clean it up a bit by joining against users twice when getting the user details from te from and to uid. This way the joins can use indexes effectively. Then just use IF in the SELECT to decide which one to return:-
SELECT IF (m.from_uid = 1, m.to_uid, m.from_uid) AS uid,
m.message,
m.sended AS `date`,
IF (m.from_uid = 1, CONCAT(to_conv.first_name, ' ', to_conv.last_name), CONCAT(from_conv.first_name, ' ', from_conv.last_name)) AS conversation_name
FROM users u
LEFT JOIN messages m
ON m.from_uid = u.user_id
LEFT JOIN users to_conv
ON to_conv.user_id = m.to_uid
LEFT JOIN users from_conv
ON from_conv.user_id = m.from_uid
WHERE m.message_id IN
(
SELECT MAX(message_id)
FROM messages
WHERE to_uid = 1
OR from_uid = 1
GROUP BY LEAST(from_uid, to_uid),
GREATEST(from_uid, to_uid)
)
ORDER BY date DESC
LIMIT 5
The sub query to check the message id is a bit more difficult to remove. Generally IN performs badly. Might be worth changing it to use EXISTS (although this will require the check in the HAVING clause which might not be good)
SELECT IF (m.from_uid = 1, m.to_uid, m.from_uid) AS uid,
m.message,
m.sended AS `date`,
IF (m.from_uid = 1, CONCAT(to_conv.first_name, ' ', to_conv.last_name), CONCAT(from_conv.first_name, ' ', from_conv.last_name)) AS conversation_name
FROM users u
LEFT JOIN messages m
ON m.from_uid = u.user_id
LEFT JOIN users to_conv
ON to_conv.user_id = m.to_uid
LEFT JOIN users from_conv
ON from_conv.user_id = m.from_uid
WHERE EXISTS
(
SELECT MAX(message_id) AS max_message_id
FROM messages
WHERE to_uid = 1
OR from_uid = 1
GROUP BY LEAST(from_uid, to_uid), GREATEST(from_uid, to_uid)
HAVING m.message_id = max_message_id
)
ORDER BY date DESC
LIMIT 5

PHPExcel Column not found: 1054

I'm trying to export a mysql query table to an excel file. I have it working on another page on my site however it seems to be having trouble with this particular query.
I'm getting this error:
Warning: PDO::query() [pdo.query]: SQLSTATE[42S22]: Column not found: 1054
Unknown column 'u2.confirmed_cash' in 'field list' in
/home2/jtdsdevc/public_html /rbk/usage-v3/inc/excel-exporter
/MySqlExcelBuilder.class.php on line 130
This is my code.
// Setup the SQL Statements
$sql_statement = getReport($idLeague, $idTeam);
function getReport($idLeague, $idTeam){
global $connect;
$sql = "
SELECT idPlayer AS id,
(SELECT CONCAT_WS(' ', location, name) FROM `team` WHERE `team`.id = u.idTeam) AS team,
(SELECT CONCAT_WS(' ', first_name, last_name) FROM `player` WHERE `player`.id = u.idPlayer) AS name,
(SELECT u2.confirmed_cash FROM `usage` u2 WHERE u.idPlayer = u2.idPlayer ORDER BY date DESC LIMIT 1) AS total_cash,
(SELECT u2.confirmed_product FROM `usage` u2 WHERE u.idPlayer = u2.idPlayer ORDER BY date DESC LIMIT 1) AS total_product,
max(date) AS last_entry
FROM `usage` u INNER JOIN `team` t ON u.idTeam =t.id INNER JOIN `league` l ON t.idLeague =l.id WHERE (t.idleague =".$idLeague." or l.pID =".$idLeague." )
";
return $sql;
}
// Add the SQL statements to the spread sheet
$mysql_xls->add_page('Report',$sql_statement);
// Get the spreadsheet after the SQL statements are built...
$phpExcel = $mysql_xls->getExcel(); // This needs to come after all the pages have been added.
....
That's where the error happens. The exact line in the MySqlExcelBuilder.class.php file is:
if ($sh = $this->pdo->query($sql))
The $sql variable above comes out to be
SELECT idPlayer AS id,
(SELECT CONCAT_WS(' ', location, name) FROM `team` WHERE `team`.id = u.idTeam) AS team,
(SELECT CONCAT_WS(' ', first_name, last_name) FROM `player` WHERE `player`.id = u.idPlayer) AS name,
(SELECT u2.confirmed_cash FROM `usage` u2 WHERE u.idPlayer = u2.idPlayer ORDER BY date DESC LIMIT 1) AS total_cash,
(SELECT u3.confirmed_product FROM `usage` u3 WHERE u.idPlayer = u3.idPlayer ORDER BY date DESC LIMIT 1) AS total_product,
max(date) AS last_entry
FROM `usage` u
INNER JOIN `team` t ON u.idTeam =t.id
INNER JOIN `league` l ON t.idLeague =l.id
WHERE (t.idleague =1 or l.pID =1 )
Edit: It is also worth noting that the query by itself works fine in phpMyAdmin.
Problem Solved! I was calling the wrong database, rookie mistake.

Categories