php/Drupal - list all nodes that a given user to permission to edit - api

I have a function that lists all nodes on the system. I would like to refine this to show only nodes that current user is able to edit - either with API or SQL statement. (Drupal 6)
function fnGetNodeTypes($typeOfNodes) {
$string = "";
$types_of_nodes = array_keys(node_get_types());
$string .= "<select name='typeOfNodes'>";
$string .= "<option value=''>Please select</option> ";
$string .= "<option value='all'>All</option> ";
foreach($types_of_nodes as $node){
if($typeOfNodes == $node ){
$selected = "selected";
}
else{
$selected = "";
}
$string .= "<option $selected value=\"" . $node . "\">" . $node ;
$string .= "</option>\n";
}
$string .= "</select\n>";
return $string;
}
Update:
Following #chx suggestion I tried messing around with users, users_roles and permissions. Let me know if there is a more Drupal way of doing this.
//----------------------------------------------
// Contruct select/option box of node types
//----------------------------------------------
function fnGetNodeTypes($typeOfNodes) {
$string = "";
$types_of_nodes = array_keys(node_get_types());
$string .= "<select name='typeOfNodes'>";
$string .= "<option value=''>Please select</option> ";
//$string .= "<option value='all'>All</option> ";
foreach($types_of_nodes as $node_type){
if (fnInArray($node_type))
{
if($typeOfNodes == $node_type ){
$selected = "selected";
}
else{
$selected = "";
}
$string .= "<option $selected value=\"" . $node_type . "\">" . $node_type ;
$string .= "</option>\n";
}
}
$string .= "</select\n>";
return $string;
}
//---------------------------------------------------------------------
// function fnInArray - see if user is allowed to edit this node type
//---------------------------------------------------------------------
function fnInArray($node_type)
{
global $user;
if ($user->name == 'admin') { return TRUE; }
// get list of all nodes that user is allowed to access
//
$string = " SELECT permission.perm as permission_perm " .
" from users " .
" join users_roles on ( users_roles.uid = users.uid ) " .
" join permission on (permission.rid = users_roles.rid) " .
" where users.name = '" . $user->name . "'";
$result = db_query($string);
while ($row = db_fetch_object($result)) {
$pieces = explode(", " , $row->permission_perm);
$node_name = "edit any " . trim($node_type) . " content";
if (in_array($node_name, $pieces ))
{
return TRUE;
}
return FALSE;
}
}

This is fairly impossible to do. Node access can be specified by a hook so the only generic way to do that would be to retrieve every. single. node. and run node_access($node, 'update') on them. That's not too fast. You can mess around with node types, permissions, the node access table etc depending on how your site is set up and modules are used. If we presume that the only thing controlling your nodes are the permissions and understand please this presumption is not always true by far, then in Drupal 6 and below (I suspect from node_get_types() you are not using D7) you would indeed iterate over node_get_types()and check user_access("edit own $type content") || user access("edit any $type content") but this won't go too far.

Not quite sure of the proper method for Drupal 6 (check db_rewrite_sql) but for Drupal 7, while you are building your query add addTag('node_access') to the query and that will limit it to only nodes that the user has permission to edit. If you go to the link for db_rewrite_sql above make sure to take a look at the comments.

db_query + db_rewrite_sql: Returns only the rows the logged-in user is allowed to view.
$results = db_query(db_rewrite_sql($query), $args);

This is what the Module Grants Monitor module is for http://drupal.org/project/module_grants. From the project page: "Clicking on it reveals a summary of all the content the logged-in user has access to (i.e. view, edit) after access controls have been applied by the content access modules installed on your site". I installed and tested this today and it seems to work. Does anyone have comments or experience with this module?
It seems like this should also be possible with Views or Rules... but maybe that's just because everything seems possible with them...

Related

posts_orderby not displaying the posts

I would like to customize my wordpress search page
First, i used the "posts_where" to modify the clause
function search_posts_where ($where) {
global $wp_query, $wpdb;
// Searching and not in admin
if (!is_admin() && $wp_query->is_search && isset($wp_query->query_vars['s'])) {
// Tables names
$post_title = "{$wpdb->prefix}posts.post_title";
$post_excerpt = "{$wpdb->prefix}posts.post_excerpt";
$post_content = "{$wpdb->prefix}posts.post_content";
$post_type = "{$wpdb->prefix}posts.post_type";
$post_status = "{$wpdb->prefix}posts.post_status";
$post_author = "{$wpdb->prefix}posts.post_author";
$post_ID = "{$wpdb->prefix}posts.ID";
$post_date = "{$wpdb->prefix}posts.post_date";
// Get the 's' parameters
$wp_query->query_vars['s'] ? $search_text = $wp_query->query_vars['s'] : $search_text = 'IS NULL';
// Write the where clause
$where = " AND ((($post_title LIKE '%$search_text%')";
$where .= " OR ($post_excerpt LIKE '%$search_text%')";
$where .= " OR ($post_content LIKE '%$search_text%')))";
$where .= " AND $post_type IN ('parcours')";
$where .= " AND $post_status = 'publish'";
$where .= " GROUP BY $post_ID";
}
return $where;
}
add_filter('posts_where', 'search_posts_where', 10, 2);
It works fine. All posts belonging to my custom post type 'parcours' are shown, depending on what I entered for the 's' query.
Second, i used the "posts_join" to add the meta table (not used yet !)
function search_posts_join ($join) {
global $wp_query, $wpdb;
// Searching and not in admin
if (!is_admin() && $wp_query->is_search && isset($wp_query->query_vars['s'])) {
// Tables names
$post_meta = "{$wpdb->prefix}postmeta";
$post_ID = "{$wpdb->prefix}posts.ID";
$post_meta_ID = "{$wpdb->prefix}postmeta.post_id";
// Join clause
$join .= "LEFT JOIN $post_meta ON ($post_ID = $post_meta_ID)";
}
return $join;
}
add_filter('posts_join', 'search_posts_join', 10, 2);
Still works perfectly !
Now the problem, i would like to order my posts in ascending direction (default is descending). So, i added the "posts_orderby" hook.
function search_posts_orderby ($orderby) {
global $wp_query, $wpdb;
// Searching and not in admin
if (!is_admin() && $wp_query->is_search) {
// Tables names
$post_title = "{$wpdb->prefix}posts.post_title";
$post_date = "{$wpdb->prefix}posts.post_date";
$post_ID = "{$wpdb->prefix}posts.ID";
// Order by clause
$orderby .= " ORDER BY $post_title ASC,";
$orderby .= " $post_date DESC";
}
return $orderby;
}
add_filter('posts_orderby', 'search_posts_orderby', 10, 2);
And here is the problem. All posts disapeared. Removing the "orderby" and they come back.
Looking at the SQL query, i have
"SELECT SQL_CALC_FOUND_ROWS wp_128444_posts.* FROM wp_128444_posts LEFT JOIN wp_128444_postmeta ON (wp_128444_posts.ID = wp_128444_postmeta.post_id) WHERE 1=1 AND (((wp_128444_posts.post_title LIKE '%tour%') OR (wp_128444_posts.post_excerpt LIKE '%tour%') OR (wp_128444_posts.post_content LIKE '%tour%'))) AND wp_128444_posts.post_type IN ('parcours') AND wp_128444_posts.post_status = 'publish' GROUP BY wp_128444_posts.ID ORDER BY wp_128444_posts.post_title LIKE '{5a35f6e9144541f93e08829126b2cb633436cebf95d774062fff749a12e6a465}tour{5a35f6e9144541f93e08829126b2cb633436cebf95d774062fff749a12e6a465}' DESC, wp_128444_posts.post_date DESC ORDER BY wp_128444_posts.post_title ASC, wp_128444_posts.post_date DESC LIMIT 0, 6"
I don't know why WP is adding the default ORDER BY, that i don't want.
Is is possible to remove it ?
I tried to replace my hook with "pre_get_posts" hook
function order_posts_by_title( $query ) {
if ( $query->is_search() && $query->is_main_query() ) {
$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'order_posts_by_title' );
With this hook, it works !! Sounds very strange to me
Any explanation ?
Thanks

how to get wordpress post with by category with images

I have installed wordpress and opencart in same database. Trying to get wordpress posts table inside opencart module. got the mysql query to fetch all information except image. I dont why images are different from the post in loop of result. Kindly guide, following is the code.
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "tablename";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {die("Connection failed: " . $conn->connect_error);}
$sql = "SELECT * FROM wp_posts WHERE post_type = 'attachment' ORDER BY ID DESC LIMIT 3";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo '<div class="col-sm-4">';
echo "Post ID: " . $row["ID"] . " / ";
echo "Post Title: " . $row["post_title"] . " / ";
echo "Post Title: " . $row["post_date"] . " / ";
echo '<img src="' . $row['guid'] . '" class="img-responsive">';
echo '</div>';
}
} else {
echo "0 results";
}
Run your query in phpMyAdmin and check if result you got is the same as you want (you get those pictures that you want).
Then I advise you to set the checkpoint inside the loop and look at the data. Debugging is a very powerful thing in finding errors, it's time to start using it

How to set function in HTML while outputing HTML with PHP

Sorry for little weird tittle, english is not my native language, and its little hard for me to express myself about this, so I hope i'll get clearer in explanation :)
I have this piece of code, to fetch all rows from MYSQL db, and when it fetch it out, i want to do some action on everyone of that row. (I want to display different PDF files stored in DB).
Take a look
include_once 'dbcon.php';
$query = mysql_query(" SELECT email, name FROM upload_jezici ");
while ($row = mysql_fetch_array($query)) {
echo $row['email']. " " . $row['name'] . "<input type='button' name='' value= 'button' > <br />";
}
How to increment title of button name, on every row, so I can use it later to access it via POST method to display PDF?
I want something like this...
1st row : name='button1'
2nd row : name ='button2' etc etc..
When im outputing HTML with PHP it only allow me to read some variables, not some functions stored in quotation marks.
Please help guys! Thanks
You can end the string and concatenate it with an expression. In this case, I use $i++ which works like a counter. It returns the value of $i and then increments $i for the next iteration:
$i = 1;
while ($row = mysql_fetch_array($query)) {
echo $row['email']. " " . $row['name'] . "<input type='button' name='button" . $i++ . "' value= 'button' > <br />";
}
But 'row 1' doesn't always have to be the same row. Due to rows being added and removed you may get a different result, so 'button1' isn't a very good name. It would be better if you could use the name or id of the row. So if the person table has a numeric id as well, you could use that:
$query = mysql_query(" SELECT id, email, name FROM upload_jezici ");
while ($row = mysql_fetch_array($query)) {
echo $row['email']. " " . $row['name'] . "<input type='button' name='button{$row['id']}' value= 'button' > <br />";
}
As you can see here, I didn't concat, but instead embedded the array variable in the string. This works similar to normal variables, except you have to put braces around the variable. Of course, you could still concatenate the value as in the first example.
We use [] to create an array of the buttons
I'm not in a live environment so I can't test it.
Accessing via $_POST:
$size = sizeof($_POST['button']);
for($i = 0; $i < $size; $i++){echo $_POST['button'][$i];}
// Code
include_once 'dbcon.php';
$query = mysql_query(" SELECT email, name FROM upload_jezici ");
while ($row = mysql_fetch_array($query)) {
echo $row['email']. " " . $row['name'] . "<input type='button' name='button[]' value= 'button' > <br />";
}
$query = mysql_query(" SELECT id, email, name FROM upload_jezici ");
while ($row = mysql_fetch_array($query)) {
echo $row['email']. " " . $row['name'] . " ";
}
Yes, i've tried to increment with for loop, but no luck.. This is doing a job very well :)
Good idea. Thanks guys very much!

How can I convert this to use PDO?

I would like to use PDO for selecting (searching) a database.
The search 'form' has MULTIPLE fields that can be used.. 1 or many can be filled in to help refine the search. (or there can be many o them left blank/empty)
here is what I have been using (locally):
//localhost details
$db_username="root"; //database user name
$db_password="";//database password
$db_database="test"; //database name
$db_host="localhost";
mysql_connect($db_host,$db_username,$db_password);
#mysql_select_db($db_database) or die("Unable to connect to database.");
if(isset($_POST['submit'])) {
// define the list of fields
$fields = array('first', 'trialdate', 'wcity', 'wstate', 'plantif');
$conditions = array();
//loop through the defined fields
foreach($fields as $field){
// if the field is set and not empty
if(isset($_POST[$field]) && $_POST[$field] != '') {
// create a new condition while escaping the value inputed by the user (SQL Injection)
$conditions[] = "`$field` LIKE '%" . mysql_real_escape_string($_POST[$field]) . "%'";
}
}
//build the query
$query = "SELECT * FROM myTable ";
// if there are conditions defined
if(count($conditions) > 0) {
// append the conditions
$query .= "WHERE " . implode (' OR ', $conditions); // you can change to 'OR', but I suggest to apply the filters cumulative
}
$result = mysql_query($query);
if(isset($_POST['submit'])) {
while($row = mysql_fetch_array($result)) {
echo $row['first'] . "<br />"; //individual value
//build panels that displays everything from row..etc
}
}
}
this has been working fine... but I'd like convert to using the PDO approach.
I gave it a few tries...but am missing something here..
heres what I've tried so far..
//localhost details
$db_username="root"; //database user name
$db_password="";//database password
$db_database="test"; //database name
$db_host="localhost";
//PDO DB connection
$conn = new PDO('mysql:host='.$db_host.'dbname='.$db_database.'charset=utf8', $db_username, $db_password);
if(isset($_POST['submit'])) {
$stmt = $conn->prepare('SELECT * FROM myTable WHERE first LIKE :first OR trialdate LIKE :trialdate OR wcity LIKE :wcity OR wstate LIKE :wstate OR plantif LIKE :plantif');
//build query placeholders (*note: use bindValue for $_POST values)
$stmt->bindValue(':first', '%' . $_POST['first'] . '%');
$stmt->bindValue(':trialdate', '%' . $_POST['trialdate'] . '%');
$stmt->bindValue(':wcity', '%' . $_POST['wcity'] . '%');
$stmt->bindValue(':wstate', '%' . $_POST['wstate'] . '%');
$stmt->bindValue(':plantif', '%' . $_POST['plantif'] . '%');
$stmt->execute();
foreach ($stmt as $row) {
// do something with $row
echo $row['first'] . "<br />"; //individual value
}
}
I could use help on getting the PDO example working with a displayed result/row/value?

How to save a date from php to SQL table?

i have a php file that works OK.
That php makes recursive search in a local folder, and calculates the last modification DATE of those files.
My question: Every time that i open that php file i want that date to be stored in a SQL table.
-i have created a table with 2 columns (ID, date) where ID=1 then go and update the date field.
but how can i call FROM php file to save the date into sql field?
My php file:
<?php
// LAST FILES UPDATE
function getAllFiles($directory, $recursive = true) {
$result = array();
$handle = opendir($directory);
while ($datei = readdir($handle))
{
if (($datei != '.') && ($datei != '..'))
{
$file = $directory.$datei;
if (is_dir($file)) {
if ($recursive) {
$result = array_merge($result, getAllFiles($file.'/'));
}
} else {
$result[] = $file;
}
}
}
closedir($handle);
return $result;
}
function getHighestFileTimestamp($directory, $recursive = true) {
$allFiles = getAllFiles($directory, $recursive);
$highestKnown = 0;
foreach ($allFiles as $val) {
$currentValue = filemtime($val);
if ($currentValue > $highestKnown) $highestKnown = $currentValue;
}
return $highestKnown;
}
echo '<div align="center" style=" padding-top:5px; margin-top:5px; border-top:dotted #777; border-width:1px;">Last Update Date:<br>';
date_default_timezone_set('Europe/Athens');
setlocale(LC_ALL, array('el_GR.UTF-8','el_GR#euro','el_GR','greek'));
echo strftime('%d %b %Y, %H:%M:%S', getHighestFileTimestamp('../'));
echo '</div>';
$host="localhost"; // Host name
$username="..."; // Mysql username
$password="..."; // Mysql password
$db_name="..."; // Database name
$tbl_name="..."; // Table name
// Connect to server and select database.
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
// update data in mysql database
$sql="UPDATE $tbl_name SET date='HUMMMM HERE HOW TO PULL THE VALUE?' WHERE id='1'";
$result=mysql_query($sql);
// if successfully updated.
if($result){
echo "Successful";
echo "<BR>";
}
else {
echo "ERROR";
}
?>
Try something like this:
// use the function to calculate highest timestamp
$highestdate = getHighestFileTimestamp("../");
// Insert the highest timestamp into the db
$sql= sprintf("UPDATE $tbl_name SET date='%s' WHERE id='1'",
$highestdate);
--EDIT-- merged with Hiroto's answer
You can use these other styles to concatenate string constants with variables
$sql = "UPDATE {$tbl_name} SET date='{$date}' WHERE id='{$id}';";
Or, you could use concatenation.
$sql = "UPDATE " . $tbl_name . " SET date='" . $date . "' WHERE id='1';";
$sql = "UPDATE {$tbl_name} SET date='{$date}' WHERE id='{$id}';";
Or, you could use concatenation.
$sql = "UPDATE " . $tbl_name . " SET date='" . $date . "' WHERE id='1';";