Get all permissions provided by given module via hook_permission() - drupal-7

How to list all permissions enabled by given module(s)?

I might be over simplifying the solution but to retrieve the permissions of a module you only need to execute the modules hook_permissions. e.g. call views_permission()
If your looking for all the permissions in the system then you can try calling user_permission_get_modules() which is part of the user module in core.
/**
* Determine the modules that permissions belong to.
*
* #return
* An associative array in the format $permission => $module.
*/
function user_permission_get_modules() {
$permissions = array();
foreach (module_implements('permission') as $module) {
$perms = module_invoke($module, 'permission');
foreach ($perms as $key => $value) {
$permissions[$key] = $module;
}
}
return $permissions;
}

Related

Eloquent - groupBy and sum() of hasManyThrough relationship

I have 3 models Job, Diary, Resource.
Jobs has relation with Diary and Diary has relation with Resource.
I wanted to get all Resource associated with a Job and did this using
public function labourers()
{
return $this->hasManyThrough(Resource::class, Diary::class, 'job_id');
}
On my Job class.
Now I want to group the results by User who's user_id is a column in Resource and then show the total hours.
This is the closest I can get.
$job = Job::where('job_number', 3007)->first();
$labour = $job->labourers()->get();
$results = $labour->groupBy('user_id');
echo $results;
foreach($results as $result)
{
$hours = $result->sum('hours');
echo $result[0]->user_id." - ";
echo $hours.". ";
}
This gets me the user_id and the sum of the hours but I am unable to access the user name through the relationship set up on the resource model
public function user()
{
return $this->belongsTo(User::class);
}
with
$result->user->name;
This produces
Property [user] does not exist on this collection instance.
How can I return a collection which allows me to access the users name and the sum of the hours.
The reason you're not able to access the user like that is because (in this case) groupBy is a method on the collection that returns another collection.
Firstly, eager load the user relationship on so that your code is a bit more efficient:
$labour = $job->labourers()->with('user')->get();
Secondly, since you have a collection you can use first() instead of [0]:
$result->first()->user_id
Lastly, you would have to access the user in the same way you're accessing the user_id:
$result->first()->user
So, you would end up with something like:
$job = Job::where('job_number', 3007)->first();
$labourers = $job->labourers()->with('user')->get();
$results = $labourers->groupBy('user_id');
foreach($results as $result)
{
echo $result->first()->user->name . ' - ' . $result->sum('hours') . '.';
}
You can try this
$job = Job::where('job_number', 3007)->with(['labourers' => function($query){
$query->select('id','user_id', DB::raw('sum(hours) as hours'))->groupBy('user_id');
}, labourers.user])->first();
$results = $job->labourers;
foreach($results as $result){
print_r($result->user);
print_r($result->hours);
}

Indirect modification of overloaded element of Illuminate\Support\Collection has no effect

im quite new in laravel framework, and im from codeigniter.
I would like to add new key and value from database
static function m_get_promotion_banner(){
$query = DB::table("promotion_banner")
->select('promotion_banner_id','promotion_link','about_promotion')
->where('promotion_active','1')
->get();
if($query != null){
foreach ($query as $key => $row){
$query[$key]['promotion_image'] = URL::to('home/image/banner/'.$row['promotion_banner_id']);
}
}
return $query;
}
that code was just changed from codeigniter to laravel, since in codeigniter there are no problem in passing a new key and value in foreach statement
but when i tried it in laravel i got this following error :
Indirect modification of overloaded element of Illuminate\Support\Collection has no effect
at HandleExceptions->handleError(8, 'Indirect modification of overloaded element of Illuminate\Support\Collection has no effect', 'C:\xampp\htdocs\laravel-site\application\app\models\main\Main_home_m.php', 653, array('query' => object(Collection), 'row' => array('promotion_banner_id' => 1, 'promotion_link' => 'http://localhost/deal/home/voucher', 'about_promotion' => ''), 'key' => 0))
please guide me how to fix this
thank you (:
The result of a Laravel query will always be a Collection. To add a property to all the objects in this collection, you can use the map function.
$query = $query->map(function ($object) {
// Add the new property
$object->promotion_image = URL::to('home/image/banner/' . $object->promotion_banner_id);
// Return the new object
return $object;
});
Also, you can get and set the properties using actual object properties and not array keys. This makes the code much more readable in my opinion.
For others who needs a solution you can use jsonserialize method to modify the collection.
Such as:
$data = $data->jsonserialize();
//do your changes here now.
The problem is the get is returning a collection of stdObject
Instead of adding the new field to the result of your query, modify the model of what you are returning.
So, assuming you have a PromotionBanner.php model file in your app directory, edit it and then add these 2 blocks of code:
protected $appends = array('promotionImage');
here you just added the custom field. Now you tell the model how to fill it:
public function getPromotionImageAttribute() {
return (url('home/image/banner/'.$this->promotion_banner_id));
}
Now, you get your banners through your model:
static function m_get_promotion_banner(){
return \App\PromotionBanner::where('promotion_active','1')->get();
}
Now you can access your promotionImage propierty in your result
P.D:
In the case you are NOT using a model... Well, just create the file app\PromotionImage.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PromotionImage extends Model
{
protected $appends = array('imageAttribute');
protected $table = 'promotion_banner';
public function getPromotionImageAttribute() {
return (url('home/image/banner/'.$this->promotion_banner_id));
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'promotion_banner_id','promotion_link','about_promotion','promotion_active'
];
just improving, in case you need to pass data inside the query
$url = 'home/image/banner/';
$query = $query->map(function ($object) use ($url) {
// Add the new property
$object->promotion_image = URL::to( $url . $object->promotion_banner_id);
// Return the new object
return $object;
});
I've been struggling with this all evening, and I'm still not sure what my problem is.
I've used ->get() to actually execute the query, and I've tried by ->toArray() and ->jsonserialize() on the data and it didn't fix the problem.
In the end, the work-around I found was this:
$task = Tasks::where("user_id", $userId)->first()->toArray();
$task = json_decode(json_encode($task), true);
$task["foo"] = "bar";
Using json_encode and then json_decode on it again freed it up from whatever was keeping me from editing it.
That's a hacky work-around at best, but if anyone else just needs to push past this problem and get on with their work, this might solve the problem for you.

Different Views for connected Users in CakePHP

I got 3 controller/tables Users / Adresses / AdressesUsers
This is my Adresses View function
/**
* View method
*
* #param string|null $id Adress id.
* #return \Cake\Network\Response|null
* #throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$this->viewBuilder()->layout('user');
$uid = $this->request->session()->read('Auth.User.id');
$adress = $this->Adresses->get($id, [
'contain' => ['Users']
]);
$counter = 0;
foreach($adress['users'] as $userid){
$users[$counter] = $userid['id'];
}
if(in_array($uid, $users)) {
$adress['dabei'] = 1;
} else {
$adress['dabei'] = 0;
}
$this->set('adress', $adress);
$this->set('_serialize', ['adress']);
}
I want all the users who are connected with the adress to see more detail information. How do I reach that goal? Tried to do it with a if clause, but didnĀ“t work, since I get an array of more then just one user (since multiple users can connect to one adress (adress of orders - not their own).
EDIT: I used an foreach loop to find out which users are in it and use an if/else in my view. But I think this is not best practice :/

Get user uid from name (Drupal 7)

I can't figure out how to get an user's UID knowing the user's name.
The user's name will be entered by a variable. I just need to pick up the UID in another variable.
I've found this code, which would be perfect, but it doesn't work on Drupal 7:
$account = user_load(array('name' => check_plain($name)));
Can anybody help me?
Thank you very much!!
try
$user = user_load_by_name($username);
$user_id = $user->uid;
or you can use
function get_uid($username)
{
// Function that returns the uid based on the username given
$user = db_fetch_object(db_query("SELECT uid FROM users WHERE name=':username'", array(":username" => $username)));
return $user->uid;
}
One way to look up the user is to use the entity_load('user');. Here is an example how to do it:
// Add the user you want to find here
$user_to_lookup = 'test';
$users = entity_load('user');
$found_user = null;
foreach ($users as $user) {
if ($user->name == $user_to_lookup ) {
$found_user = $user;
}
}
The user object is stored in $found_user now. Note that its an stdClass so you need to use the arrow notation to access the properties. For example to access mail write $found_user->mail.

CakePHP, GET Parameters and routing

I am fairly new to cakephp but I have a question relating to urls and parameters. I would like to be able to have a url that looks like a standard url e.g:
http://www.mysite.com/controller/myaction?arg=value&arg2=val
I would like that url to map to an action in my controller as follows:
function myaction($arg = null, $arg2 = null)
{
// do work
}
I realize that cakephp has routing as described here, however, honestly this seems over engineered and results in a url string that is nonstandard.
In my current situation the url is being generated and invoked by an external (billing) system that knows nothing about cake and doesn't support the cake url format.
You can have your URL in any form. It's just CakePHP allows you to retrieve the variable passed through GET from the variable $this->params['url']
function myaction()
{
if(isset($this->params['url']['arg']))
$arg = $this->params['url']['arg'];
if(isset($this->params['url']['arg2']))
$arg2 = $this->params['url']['arg2'];
}
Solution in AppController for CakePHP 2.x
class AppController extends Controller {
....
/***
* Recupera los Named envias por URL
* si es null $key emtraga el array completo de named
*
* #param String $key
*
* #return mixed
*/
protected function getNamed($key=null){
// Is null..?
if(is_string($key)==true){
// get key in array
return Hash::get($this->request->param('named'), $key);
}else{
// all key in array
return $this->request->param('named');
}
}
...
}
I have a similar problem. Not because I have an external system, but because I don't like to put all parameters into the URL-path. In my example, I have some search queries that are assembled and passed to the controller. IMHO, these queries should be GET parameters and not part of the URL-path.
One advantage of using GET parameters is that the order of the given parameters is not important, in contrast to passing params via the URL path.
To solve this problem in a generic way, I'm replacing all method arguments with the value of the GET-param, if one with the same name is given:
class MyController extends AppController
{
function test($var1 = null, $var2 = "content2")
{
foreach (get_defined_vars() as $key => $value) {
if (isset($this->params['url'][$key])) {
$getvalue = $this->params['url'][$key];
$$key = $getvalue;
CakeLog::write("debug", "Setting:$key to $getvalue");
}
}
CakeLog::write("debug", print_r(get_defined_vars(), true));
}
}
Now I can access this controller method and pass parameters via GET like this:
http://myapp/mycontroller/test?var1=foo&var2=bar

Resources