php pdo category level access - php

i want category level access to users, i will give from admin side which categories users should access and which are not. Here i have trouble please help me, here is my code
In my database permission table there, in that userid and catids fields there so user if click on category function will see in permission table if user has permission are not then it will dipplay.
public function Grants($username)
{
$q = $this->db->prepare("select * from permissions where user = ?");
$q->bindParam(1, $username);
$q->execute();
$results = $q->fetchAll();
return $results;
}
category page
$check = new Access;
$data = $check->Grants($user);
foreach($data as $v)
{
if($v['catid'] == $_GET['p'])
{
foreach($nav as $list)
{
echo '' . '<li style="display:inline; padding:10px;">' . $list['catname'] . '</li>' . '';
}
}
else{
echo 'Access Denied'; }
}
if i had only one category in permission table it is working fine, if user had two or more catids not working.
Permission table example:
User>1 catid>1,2,3 array model giving problem how do i solve please help, if i place only one category it is working.

If your data is stored as I think it is from what you posted, it would look like this:
------------------------
| User | catid |
------------------------
1 1,2,3
Am I right? If that is the case. Then when you call this:
$check = new Access;
$data = $check->Grants($user);
Your $data variable would contain something like this:
1,2,3
and NOT an array as you think it would.
What you should do is use explode() to create that url:
$check = new Access;
$data = explode(',', $check->Grants($user));
Which, in turn; should give you an array like this:
Array (
[0] => 1,
[1] => 2,
[2] => 3,
)
Allowing you to iterate as you require.
EDIT
As per your comment, you need to access the catid array element. Provided you have the right php version, you could simple do this:
$check = new Access;
$data = explode(',', $check->Grants($user)[0]['catid']);
Or if that throws error, try this:
$check = new Access;
$cats = $check->Grants($user);
$data = explode(',', $cats[0]['catid']);

I have found simple solution for this.
$check = new Access;
$data = $check->Grants($user);
foreach($data as $result)
{
$str = $result['catid'];
$string = explode(',' , $str);
}
if(in_array($_GET['p'], $string))
{
foreach($nav as $list)
{
echo '' . '<li style="display:inline; padding:10px;">' . $list['catname'] . '</li>' . '';
}
}
else { echo "You dont have permission"; }

Related

Select one item from array

So, I wanna select item per item from this array ["A185","A740","A540"]
Like for example I wanna select
$cie[0] = A185 or A740
with something like $cie[0] = A185
This is my code so far, since I fetch that code from a row in a MySQL table.
while ($row = pg_fetch_array($resul)) {
$cie10 = array($row["cie"]);
}
$cie = ["A185","A740"];
$values = array_count_values($cie);
$top = array_slice($values, 0, 1);
print_r($top);
What I get:
Array ( [["A185","A740","A540"]] => 1 )
It just won't work.
I'm Sure you are looking to display the data that is in the array variable
$var = ["A185","A740","A540"]; // Asume as you stored the values in the array called var
foreach($var as $x){
print_r($x);
echo "<br/>";
}
EDIT: Highlighted the code
If i understand your problem. You are looking for this:-
$Fullarray = ["A185","A740","A540"];
$cie = array_slice($Fullarray,0,2);
foreach ($cie as $name) {
$d[] = '"' . $name . '"';
}
$implodekeys = "[".implode(',',$d)."]";
$newarray[$implodekeys] =1;
echo "<pre>"; print_r($newarray);
Hope it helps!

Codeigniter multi-dimensional array return only the first row

One day I'm on this problem and I cant find the solution.
My goal is to return a list of links from an ID (the father). So I want all his childs.
But in the view, I only have on result (the 1st one...).
I have in my controller :
$data['list_link'] = $this->menuManager->list_link();
In my Model :
function list_link($fatherid=0){
$r = array();
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
// stock results in array
$r[] = $query->result_array();
foreach ($query->result() as $row) {
// let's find the childs
$this->list_link($row->id,$loop);
}
return $r;
}
If I "for each" the $r here, all looks good.
So, $data['list_link'] shoud now have all the rows.
In my view :
foreach ($list_link as $link){
foreach ($link as $row){
echo $row['name'];
}
}
But, I only have the first links (first childs), not the other one. Any help would be greatly appreciated as I'm on that problem for days...
You're not storing any values in the recursive calls (though I'm still not sure you'd get what you expect). You'd need to populate $r with each function call:
$r[] = $this->list_link($row->id,$loop);
However, either I missed something or you're overcomplicating things, but I think you could simply return the result array and use it:
function list_link($fatherid=0,$loop=0){
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
return $query->result_array();
}
UPDATE
Your latest version still doesn't collect the data from recursive calls, here is the full function, see if it works:
function list_link($fatherid=0){
$r = array();
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
$result = $query->result_array();
// stock results in array
$r[$fatherid] = $result;
foreach ($result as $row) {
// let's find the children
$r[$fatherid][$row['id']] = $this->list_link($row['id']);
}
return $r;
}
Note that I've added $r[$fatherid][$row['id']] so the end result should be an array with a branching structure. If you don't want that, just do $r[] instead.

getting list of users in Drupal 7 using PHP

How can I fetch user names from a Drupal 7 database using PHP?
See this:
Is it possible to use the Drupal api to get a list of users?
This is for Drupal 6 and I have tried this but it says
Call to undefined function db_fetch_object()
Here is my code:
$result = db_query("SELECT name AS users_name FROM {users}");
while($row = db_fetch_object($result)) {
print_r($row);
}
Lets give it a try
$query = db_select('users', 'u');
   $query->fields('u', array('name'));
   $result = $query->execute();
   while($record = $result->fetchAssoc()) {
        print_r($record['name']);
   }
In Drupal 7 you can fetch all the users using entity_load,
To get the user names alone use the following,
$users = entity_load('user');
$user_names = array();
foreach ($users as $user_id => $user) {
$user_names[] = $user->name;
}
user_load_multiple
Example from modules\profile\profile.pages.inc :
$users = user_load_multiple($uids);
$content = '';
foreach ($users as $account) {
$profile = _profile_update_user_fields($fields, $account);
$content .= theme('profile_listing', array('account' => $account, 'fields' => $profile));
}
Note that in drupal 7 all things happen via entity. It's not so fast, but flexible...
$query = db_select('users', 'u');
$query
->condition('u.uid', 0, '<>')
->fields('u', array('name'));
$result = $query->execute();
Here's the whole documentation for Drupal 7 Database api
Your code was almost correct if you had changed your while statement to read
while ($result as $row)
db_fetch_object is no longer needed in d7
it would have worked. Although db_select calls specified in this post will work, they require more overhead and should be avoided unless you are trying to generate dynamic queries. Also see: http://drupal.org/node/224333 for info on how the apis have chaned between d6 and d7. A search for db_fetch_object on this page would've given this info.
My example code to get the list of users from drupal site,
$all_users = entity_load('user');
foreach($all_users as $value) {
$user_list = (array)$value;
$users[$user_list['uid']] = $user_list['name'];
}
Now you can get the answer from the array variable $users.
For example if you want to list all the user other than administrator (default user) means use the below example:
$all_users = entity_load('user');
foreach($all_users as $value) {
$user_list = (array)$value;
if($user_list['uid'] > 1) {
$users[$user_list['uid']] = $user_list['name'];
}
}
In the above both example, the id of each user is placed as array index and the name of each usder is saved as array value.
Drupal 7 introduces a new concept of Entity.
User also included in Entity now.
You can use following function entity_load() to get the details of all entities.
To fetch the usernames in array :
$users = entity_load('user');
$usernames = array();
foreach($users as $id => $user){
$usernames[$user->uid] = $user->name;
}
print_r($usernames);
Thanks
A Better way
function GetAllActiveUsers() {
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'user')
->propertyCondition('status', 1);
$results = $query->execute();
$uids = array_keys($results['user']);
return $uids;
}
This will return all active users and use the code in a function to use it as a helper
Try this:
$query = db_select('users', 'u')
->fields('u')
->execute();
while($result = $query->fetchAssoc()) {
print_r($record['name']);
}
You can try this as well,
$query = db_select('users', 'u');
$query->fields('u', array('uid, name'));
$result = $query->execute();
while($record = $result->fetchAssoc()) {
$account = user_load($record['uid']);
if($account->uid){
print $account->name;
}
}
Simplified example with fetchAll():
$users = db_select('users', 'u')
->fields('u', array('uid'))
->execute()
->fetchAll();
foreach ($users as $user) {
$full_user = user_load($user->uid);
//do your stuff here
}

Need help with PHP homework - friend matching algorithm

I'm totally new to php and have started learning it. I have two homework assignments in php and html.
Assignment 1:
I have to store some people's names and all of their friends names. I have to list only people who have common friends. My problem is that if a person has no friends in common with someone else I get a message "Rana has 0 friends in common with Roni. I do I prevent this:
Assignment 2:
I have a html form to search for a person from the last php file
When I will search for Rana the PHP form will open and and print:
Rana have 4 friends and he has a common friend with Nandini and Mamun.
When I search for Tanmoy the page will be open and print:
Tanmoy is Rana’s friend who has 4 friends and common friends with Nandini and Mamun.
For this I have to used the function “post/get/request”
Here is my code so far:
<?php
# Function: finfCommon
function findCommon($current, $arr) {
$cUser = $arr[$current];
unset($arr[$current]);
foreach ($arr As $user => $friends) {
$common = array();
$total = array();
foreach ($friends As $friend) {
if (in_array($friend, $cUser)) {
$common[] = $friend;
}
}
$total = count($common);
$add = ($total != 1) ? 's' : '';
$final[] = "<i>{$current} has {$total} friend{$add} in common with {$user}.</i>";
}
return implode('<br />', $final);
}
# Array of users and friends
$Friends = array(
"Rana" => array("Pothik", "Zaman", "Tanmoy", "Ishita"),
"Nandini" => array("Bonna", "Shakib", "Kamal", "Minhaj", "Ishita"),
"Roni" => array("Akbar", "Anwar", "Khakan", "Pavel"),
"Liton" => array("Mahadi", "Pavel"),
"Mamun" => array("Meheli", "Tarek", "Zaman")
);
# Creating the output value
$output = "<ul>";
foreach ($Friends As $user => $friends) {
$total = count($friends);
$common = findCommon($user, $Friends);
$output .= "<li><u>{$user} has {$total} friends.</u><br /><strong>Friends:</strong>";
if (is_array($friends) && !empty($friends[0])) {
$output .= "<ul>";
foreach ($friends As $friend) {
$output .= "<li>{$friend}</li>";
}
$output .= "</ul>";
}
$output .= "{$common}<br /><br /></li>";
}
$output .= "</ul>";
# Printing the output value
print $output;
?>
For the assignment 1.1: You have just to filter out the unwantend responses with an
if ($total>0) {
$output .= "<li><u>{$user} has {$ ...
}
clause.
For the second assignment:
You have to create a page that expects a parameter to be read via $_GET or $_POST or $_REQUEST (call it name, for example). They are not functions, are arrays and you can access them from every scope in you program (they are superglobals and you don't need to declare them with gobals).
I would just print a select with the known people if the name (eg. $_REQUEST['name'] )is missing just print the form, otherwise find the person indicated by the input and print the result of the search.
EDIT:
For the second assignment, you will have to figure how to get the input data.
Probably I will use an approach a bit different
Provided that you have a form similar to this
<form action="homework.php" method="get">
Person: <select name="searchperson" />
<option> </option>
...
<option> </option>
</select>
</form>
you will have to get the list of all the known peoples in a manner similar to this:
$friends = array(
"Rana" => array("Pothik", "Zaman", "Tanmoy", "Ishita"),
"Nandini" => array("Bonna", "Shakib", "Kamal", "Minhaj", "Ishita"),
"Roni" => array("Akbar", "Anwar", "Khakan", "Pavel"),
"Liton" => array("Mahadi", "Pavel"),
"Mamun" => array("Meheli", "Tarek", "Zaman")
);
// create a flat array with all the known peoples
$knownPeople = array_reduce(
$friends,
function($current, $result) {
return array_merge($result, $current);
},
array_keys($friends)
);
$knownPeople = array_flip(array_flip($knownPeople)); //get rid of duplicates
asort(knownPeople); // sort the names
$knownPeople = array_values($knownPeople); // normalize the array indexes
and then get the form you need with a function like this:
function theForm($people) {
$options = '<option>'.join("</option>\n<option>",$people). '</option>';
echo "
<form action=\"homework.php\" method=\"get\">
<h2>Chose the people you want investigate on:</h2>
Person: <select name=\"person\" />
$options
</select>
</form>";
}
Whenever you get a grasp on the previous code or not, you have to evaluate the input and take the opportune actions:
Let say that your script is called homework.php (you will see the name into the action of the form) and it is located ad http://example.com. His URI will be http://example.com/homework.php
There are several possible scenarios:
the user call the script for the first time
the user choose a person from the select
the user invoke your script manually with a known person as parameter
the user invoke your script manually with a person you don't have in your list
Let's review the different cases:
the user call the script for the first time
What appened: the user go to http://example.com/homework.php crossing a link or writing the URI into the browser address bar.
How you detect this scenario: Given the form above you can check $_GET['person']. if it is not isset or empty or not array_key_exists you can state you are into the first scenario.
To do: Just output the form and exit.
the user choose a person from the select
What appened: the user get the form (first scenario) and choose a name from the select.
How you detect this scenario: The detection of the first scenario fails and you can find the name contained into $_GET['person'] into the knownPeople array.
To do:
sanitize the input (remove any spurious character)
find the name into the knownPeople array to be sure you are not serving a forged request
apply your functions to the person in input in order to get the desired output
output the result you got
the form for a new query or a link to http://example.com/homework.php
the user invoke your script manually with a known person as parameter
What appened: the user use a URI like http://example.com/homework.php?person=Rana to reach the script
How you detect this scenario: If the method you use in the form is get you can't (at least not using this simple scenarion) and you won't bother to as it can be considered a legal request as this is an homework and you don't have requirements about it. If you used the method post you have the chance to detect the forgeries as the parameter passed with that method are usually stored into the $_POST array. You can still find the name contained into $_GET['person'] into the knownPeople array.
To do: Same as second scenario
sanitize the input (remove any spurious character)
find the name into the knownPeople array to be sure you are not serving a forged request
apply your functions to the person in input in order to get the desired output
output the result you got
the form for a new query or a link to http://example.com/homework.php
the user invoke your script manually with a person you don't have in your list
How you detect this scenario: The detection of the first scenario fails and you can not find the name contained into $_GET['person'] into the knownPeople array.
To do:
sanitize the input (remove any spurious character)
find the name into the knownPeople array to be sure you are not serving a forged request
as the check fails output an error messages stating the user is unknown and let the user go to the correct uri with a link to http://example.com/homework.php.
Not all forgeries are bad. Consider an user that make a legal search and bookmark the result. If the list of friends change and then he returns to the page using the bookmark. He will fall straight into the fourth scenario
Hope this will help you to comprehend how the php scripting works.
change findCommon function from
function findCommon($current, $arr) {
$cUser = $arr[$current];
unset($arr[$current]);
foreach ($arr As $user => $friends) {
$common = array();
$total = array();
foreach ($friends As $friend) {
if (in_array($friend, $cUser)) {
$common[] = $friend;
}
}
$total = count($common);
$add = ($total != 1) ? 's' : '';
$final[] = "<i>{$current} has {$total} friend{$add} in common with {$user}.</i>";
}
return implode('<br />', $final);
}
to
function findCommon($current, $arr) {
$cUser = $arr[$current];
unset($arr[$current]);
foreach ($arr As $user => $friends) {
$common = array();
$total = array();
foreach ($friends As $friend) {
if (in_array($friend, $cUser)) {
$common[] = $friend;
}
}
$total = count($common);
$add = ($total != 1) ? 's' : '';
if ( $total > 0 ) $final[] = "<i>{$current} has {$total} friend{$add} in common with {$user}.</i>";
}
return implode('<br />', $final);
}
The change is i added a if ( $total > 0 ) before $final[] = ..
for the second one.
<?php
function searchPerson($person, $friends){
$direct = false;
$found = false;
if ( in_array ($person, array_keys($friends) ) ){
list($total, $common_friends) = commonFriend ($person, $friends);
$direct = true;
$found = true;
}
else{
foreach ( $friends as $friend => $his_friends ){
if ( in_array ( $person, $his_friends ) ){
list($total, $common_friends) = commonFriend ($friend, $friends);
$direct = false;
$found = true;
$friend_person = $friend;
break;
}
}
}
if ( !$found ) return false;
$output = $person . " ";
if ( $direct ){
$output .= " has " . $total . " friends";
}
else{
$output .= " is " . $friend_person . "'s friend who has " . $total . " friends";
}
if ( isset($common_friends[0]) ) $output .= " and common friends with " . $common_friends;
return $output;
}
function commonFriend ($person, $friends){
$my_friends = $friends[$person];
unset($friends[$person]);
$total_friends = count($my_friends);
$common_with = array();
foreach ( $friends as $friend => $his_friends ){
foreach ( $my_friends as $my_friend ){
if ( in_array ($my_friend, $his_friends) ){
$common_with[] = $friend;
}
}
}
$common_with = array_unique ($common_with);
$common_friends = "";
if ( count($common_with) > 0 ){
$common_friends = join (", ", $common_with );
}
return array ( $total_friends, $common_friends );
}
$friends = array(
"Rana" => array("Pothik", "Zaman", "Tanmoy", "Ishita"),
"Nandini" => array("Bonna", "Shakib", "Kamal", "Minhaj", "Ishita"),
"Roni" => array("Akbar", "Anwar", "Khakan", "Pavel"),
"Liton" => array("Mahadi", "Pavel"),
"Mamun" => array("Meheli", "Tarek", "Zaman")
);
$person = $_GET['person'];
$output = searchPerson($person, $friends);
if ( $output === false ) print $person . " is not on the list";
else print $output;
?>
What you have to do with the second assignment is you need a form.
lets say the above code was named searchPerson.php
then add a html page like
<html>
<head>
<title>Search for friend</title>
</head>
<body>
<form action="searchPerson.php" method="get">
Person: <input type="text" name="person" /><input type="submit" value="search" />
</form>
</body>
</html>
or run directly like
searchPerson.php?person=Rana
And why you get a message like that is because $person = $_GET['person']; gets the person name from the url, and u must have run it like searchPerson.php, so their is no value for $person to check.
-- EDIT
Chaged the code to work with people not in the list

how to loop over looped elements in Php?

I'm creating a tree-structure of categories with parentid's which can be called from children in such a way:
ID | Name | ParentID
1 1 0
2 2 1
3 3 2
4 4 1
Resulting in this:
1 = 1
2 = 1 -> 2
3 = 1 -> 2 -> 3
4 = 1 -> 4
which means 3 is a child of 2, which is a child of 1.
when trying to get this idea (with the -> to show what relations are set) I only get to the second grade (1 -> 2) but not to the third (1->2->3) because of the looping function I use for it.
//put all ID's in an array
while ($row2 = $connector->fetchArray($result2)){
$id = $row2['ID'];
$parents[$id] = $row2['name'];
}
// show the tree-structure
while ($row = $connector->fetchArray($result)){
if($row['parentid']!=0)echo $parents[$row['parentid']].' -> ';
echo $row['name'].' - ';
echo '<br>';
}
I'd like two things to change:
have the code automatically generate a tree sized as necessary.
in the while-loops i have to select the $result twice (once as $result, once as $result2) to make it work. these $result's have exactly the same database-query:SELECT ID,name,parentid FROM categories
to fetch results from. I'd like to only declare this once.
Thanks for all the good answers. I've gone with the easiest, less-code-to-implement approach:
$result = $connector->query('SELECT ID,name,parentid FROM categories');
// Get an array containing the results.
$parents = array();
while ($row = $connector->fetchArray($result)){
$id = $row['ID'];
$parents[$id] = array('ID' => $row['ID'],'name' => $row['name'],'parentid' => $row['parentid']);
}
foreach ($parents as $id => $row){
$pid=$id;
$arrTmp= array();
do { // iterate through all parents until top is reached
$arrTmp[]=$pid;
$pid = $parents[$pid]['parentid'];
}while ($pid != 0);
$arrTmp = array_reverse($arrTmp);
foreach($arrTmp as $id){
echo $parents[$id]['name'].' -> ';
}
echo '<br>';
}
Rather than have PHP organize the items into a tree, why not ask the database to do it for you? I found this article on hierarchical data to be very good and the examples are almost identical to yours.
EDIT
The SQL for getting the full tree using the Adjacency Model is not ideal. As the article explains it requires rather a lot of joins for even a small hierarchy. Is it not possible for you to use the Nested Set approach? The SQL stays the same regardless of the size of the hierarchy and INSERT and DELETE shouldn't be very difficult either.
If you really want to do hierachies with parent ids(suitable only for small number of items/hierachies)
I modified your code a little bit(I did not test it so there may be some syntax errors):
//put all recordsets in an array to save second query
while ($row2 = $connector->fetchArray($result2)){
$id = $row2['ID'];
$parents[$id] = array('name' => $row2['name'],'parent' => $row2['parentid']);
}
// show the tree-structure
foreach ($parents as $id => $row){
$pid = $row['parentid'];
while ($pid != 0){ // iterate through all parents until top is reached
echo $parents[$pid]['name'].' -> ';
$pid = $parents[$pid]['parentid'];
}
echo $parents[$id]['name'].' - ';
echo '<br>';
}
To answer your comment:
$parents = array();
$parents[2] = array('ID'=>2,'name'=>'General','parentid'=>0);
$parents[3] = array('ID'=>3,'name'=>'Gadgets','parentid'=>2);
$parents[4] = array('ID'=>4,'name'=>'iPhone','parentid'=>3);
foreach ($parents as $id => $row){
$pid=$id;
$arrTmp= array();
do { // iterate through all parents until top is reached
$arrTmp[]=$pid;
$pid = $parents[$pid]['parentid'];
}while ($pid != 0);
$arrTmp = array_reverse($arrTmp);
foreach($arrTmp as $id){
echo $parents[$id]['name'].' -> ';
}
echo '<br>';
}
Prints out:
General ->
General -> Gadgets ->
General -> Gadgets -> iPhone ->
Maybe easier with OOP. Just sort the query by parentId
Note: The listChildren method and the printout at the bottom is just there to show it is listed correctly. I did not interpret the question that the display was important.
class Element {
public $id;
public $name;
public $parent = null;
public $children = array();
public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
public function addChild($element)
{
$this->children[$element->id] = $element;
$element->setParent($this);
}
public function setParent($element)
{
$this->parent = $element;
}
public function hasChildren()
{
return !empty($this->children);
}
public function listChildren()
{
if (empty($this->children)) {
return null;
}
$out = array();
foreach ($this->children as $child) {
$data = $child->id . ':' . $child->name;
$subChildren = $child->listChildren();
if ($subChildren !== null) {
$data .= '[' . $subChildren . ']';
}
$out[] = $data;
}
return implode(',', $out);
}
}
$elements = array();
$noParents = array();
while ($row = $connector->fetchArray($result)) {
$elements[$row['id']] = $element = new Element($row['id'], $row['name']);
if (isset($elements[$row['parent']])) {
$elements[$row['parent']]->addChild($element);
} else {
$noParents[] = $element;
}
}
foreach ($noParents as $element) {
if ($element->hasChildren()) {
echo "Element {$element->id} has children {$element->listChildren()}.\n";
} else {
echo "Element {$element->id} has no children.\n";
}
}
If you are using PostgreSQL as the database, you can use the connectby() function to create the record set:
SELECT *
FROM connectby('tableName', 'id', 'parent_id')
AS t(keyid text, parent_keyid text, level int);
I love this function, and use all the time in my code. It can do some very powerful things, very quickly, and you don't have maintain the left/right values like the (adjacency model).

Categories