I have an application with a third party plugin that handles ACL management, works fine, but I am having some issues with a isAuthorized function. The user is being passed into the function and when I debug the variable I can see all of the correct information in the dataset, but when the script executes the find query it returns empty. Here is the thing, the model I am executing the query on is apart of the plugin I am using. So I am executing a find within my application on a model that lies within my plugin. To me it isn't ideal, nonetheless I am working with a plugin that wasn't built application specific. In order to execute the find the Author added
App::uses('User', 'AuthAcl.Model');
so the find could be possible. Now that said, I tweaked one thing in the conditions part of the statement because I was getting Column 'id' in field list is ambiguous error from SQL. I started to get that error because I added some relationships to the application.
I say all that to say this - since I am loading the model via App Uses shouldn't I be able to execute a find like so
$this->User->Find('First');
I have tried that and it says I'm executing on a non object. Here is the code for that script. I need input. When I execute my script without debugging it locks me out the application, and by reading the code and debugging it I think this happens because the find is returning empty. And on another note - please bear with me - I didn't write this code, and I am in the phase of learning to understand other developers code. I am using CAKEPHP 2.3 Thanks guys!
public function isAuthorized($user = null) {
App::uses('User', 'AuthAcl.Model');
App::uses('Group', 'AuthAcl.Model');
$authFlag = false;
$this->set('login_user',$user);
$userModel = new User();
$group = new Group();
//die(debug($user));
$rs = $this->$userModel->find('first',array('conditions'=>array('user.id' => $user['id'])));
die(debug($rs));
$action = 'controllers';
if (!empty($this->plugin)){
$action .= '/'.$this->plugin;
}
$action .= '/'.$this->name;
$action .= '/'.$this->action;
if (!empty($rs['Group'])){
foreach ($rs['Group'] as $group){
$authFlag = $this->Acl->check(array('Group' => array('id' => $group['id'])), $action);
if ($authFlag == true){
break;
}
}
}
if ($authFlag == false && !empty($user)){
$authFlag = $this->Acl->check(array('User' => array('id' => $user['id'])), $action);
//die(debug($authFlag));
}
if ($authFlag == false && !empty($user)){
$this->redirect(array('controller' => 'accessDenied', 'action' => 'index','plugin' =>'auth_acl'));
}
if (!empty($user)){
$user = $userModel->find('first',array('conditions' => array('user.id' => $user['id'])));
$this->Session->write('auth_user',$user);
$this->request->data['auth_plugin'] = $this->plugin;
$this->request->data['auth_controller'] = $this->name;
$this->request->data['auth_action'] = $this->action;
}
return $authFlag;
}
}
Related
public function onSystemCron(&$logs, &$lastRun, $force)
{
$clear_tmp = true;
$clear_logs = [];
$log_files = $this->_application->Filter('system_admin_system_logs', []);
foreach ($log_files as $log_name => $log) {
$clear_logs[$log_name] = empty($log['days']) ? 365 : $log['days'];
}
if (!isset($lastRun[$this->_name])) {
$lastRun[$this->_name] = [];
} elseif (!is_array($lastRun[$this->_name])) {
$lastRun[$this->_name] = [
'tmp' => $lastRun[$this->_name]
];
}
if (!$force) {
if (!empty($lastRun[$this->_name]['tmp'])
&& time() - $lastRun[$this->_name]['tmp'] < 604800
) {
// Less than a week since last run so do not clear tmp
$clear_tmp = false;
}
<?php
namespace -\System\Tool;
class RunCronTool extends AbstractTool
{
protected function _systemToolInfo()
{
return [
'label' => __('Run cron', 'directories'),
'description' => __('Use this tool to manually run cron.', 'directories'),
'weight' => 15,
];
}
public function systemToolRunTask($task, array $settings, $iteration, $total, array &$storage, array &$logs)
{
$this->_application->callHelper('System_Cron', [&$logs, true]);
return 1;
}
}
I have an issue with a WordPress plugin. It offers a button which will force run cron. Usually, making use of this button is not necessary. I tested my WP Cron and it's working fine, so the plugin is the problem. Any data which is in relation to the plugin does not get updated by WP cron. So I'm forced to click this button manually.
So, is there any solution to automate the function of the button?
I mean, I have to open the plugin settings and click on a button to run Cron. Is there any chance to automate this process?
Can provide more information if needed.
Many thanks.
Yes, I have no idea what I'm doing thanks.
When the OS wants to "kick" WordPress's cron system, it does an HTTP(S) GET to example.com/wp-cron.php .
It's possible to do this from php code, like so.
if ( ! wp_doing_cron() ) {
$url = get_site_url( null, 'wp-cron.php' );
$req = new \WP_Http();
$req->get( $url );
}
Do this last in a page view. I do it from the shutdown hook. It won't hang your page because wp-cron.php uses fastcgi_finish_request() to respond immediately to its client.
This lets you run cron from your code if DISABLE_WP_CRON is true or in other circumstances where it won't get called on its own.
But be careful. Don't use this unless you really need it. It's a bad idea to work around a site owner's need to set DISABLE_WP_CRON.
I'm trying to pull data from an API and when the information is pulled into the fieldsets within my CMS, I want to ensure that whatever has been pulled from the API is validated properly with the rules I currently have set up within my CMS (eg. an image can be no bigger that 1920x1080 in dimensions).
Here is my code:
use App\Utilities\BardUtil;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Http;
use Statamic\Eloquent\Entries\EntryModel;
use Statamic\Events\EntrySaved;
use Statamic\Facades\Entry;
public function handle(EntrySaved $event): void
{
$entry = $event->entry->model();
if ($entry->collection != 'companies') {
return;
}
$data = collect($entry->data);
if (!isset($data['tickers'][0])) {
return;
}
$tickerId = $data['tickers'][0];
$ticker = EntryModel::find($tickerId);
if ($ticker && $ticker->title) {
$tickerTitle = $ticker->title;
$response = Http::get('apicallurlexample');
$fields = $event->entry->blueprint()->fields();
$items = $response->json('results.0');
$items['companyName'] = $items['exchangeName'];
$data = $data->merge($items);
$data['slug'] = $entry->slug;
$data['date'] = $entry->date;
$fields = $fields->addValues($data->toArray());
$collection = $event->entry->collection();
$site = $event->entry->site();
$rules = Entry::updateRules($collection, $site);
$replacements = [
'id' => $entry->id,
'collection' => $collection,
'site' => $site,
];
$fields
->validator()
->withRules($rules)
->withReplacements($replacements)
->validate();
$event->entry->data($fields->values()->all());
$event->entry->saveQuietly();
}
}
I think the issue lies within the following code:
$fields
->validator()
->withRules($rules)
->withReplacements($replacements)
->validate();
What's happening when I save the company details is that it displays all the validation errors, even if the data hasn't went against any of the rules. Any help would be appreciated and thanks in advance.
Sorry for the rather late reply but thought I'd update this thread anyways for others who find this later.
Statamic only uses the validation rules you define in your blueprint/fieldset when saving entries/terms/etc in the Control Panel.
When you save data manually (eg. via PHP or directly editing the Markdown files), no validation checks are ran on it. You'll need to manually do any kind of validation in your code, before the entry is created in Statamic.
I am building an app using Front Controller design pattern and there is just one page index.php through which all user requests pass as parameters (versus different pages/controllers in regular design).
How can I connect these parameters to application logic?
e.g. I have two different actions:
index.php?action=userLogin&username=admin&password=qwerty //process user login
index.php?action=displayUsersTable //show registered users
Currently I have an array with all actions the system accepts (along with expected arguments) and I compare action param from URL to the key of this array and then check the required arguments for this action.
//1 = optional, 2=required
$systemActions = [
"userLogin" => [
"login" => 2,
"password" => 2
],
"displayUsersTable" => []
];
Obviously this going to become a monster array as the system grows.
Is there better approach to bind parameters sent to front controller to system actions?
As the code is "fixed" (i.e. not driven from a database) then there is no need to pump into an array (and all the processing/memory overhead that it requires. So yes, it can be improved.
But there are many options depending on how much the project will grow.
Simplest
The simplest would be simple "if" statements, or a switch. I'd start there to keep it simple.
More Complex
You say other projects have different pages / controllers - but there is a reason. And as you're asking for improvements, especially if you're expecting the project to grow to such as extent that you're looking for optimizations, then you really should consider these reasons (and split into files).
At the other end of the scale, you can split all the calls into files/classes and auto-load the files/classes.
This way you only execute the code you need (smaller file sizes), is very modular and easy to work on collaboratively. And if you add a new action, you don't need to modify the index or array - you only modify the action file you're working on.
Example (vastly simplified from a project I'm currently working on with this approach):
1) Create a "baseAction" base class the all actions will extend from. You can add common features such as cleaning/pre-processing parameters, logging, validating headers etc.
abstract class baseAction {
protected $aExpectedParams = [];
protected $aParams = [];
protected $validParams = true;
function __construct() {
foreach (self::$aExpectedParams as $name=>$aParam) {
if (isset($_GET[$name]))
if ($aParam['type'] == 'string') {
self::$aParams[$name] = $_GET[$name];
} elseif ($aParam['type'] == 'int') {
self::$aParams[$name] = (int)$_GET[$name];
}
} elseif ($aParam['required']) {
self::$validParams = false;
}
}
}
// This is the called function
abstract function execute();
}
2) Create the "action" classes, by extending the base Action. Save these in individual files (so others can collaborate on the project without interfering).
// put in 'actions/userLogin.php
class userLogin extends baseAction {
protected $aExpectedParams = [
'login' => ['type' => 'string', 'required' => true]
'password' => ['type' => 'string', 'required' => true] // NOTE: you should never actually pass password unencrypted through "get" as they'll get stuck in user logs!
];
public function execute() {
// Do Whatever
}
}
.
// put in 'actions/displayUsersTable.php
class displayUsersTable extends baseAction {
public function execute() {
// Do Whatever
}
}
3) Create an autoloader to pull in those individual files.
function myAutoloader($className) {
if (file_exists(__DIR__ . '/actions/' . $className . '.php')) {
require_once(__DIR__ . '/actions/' . $className . '.php');
}
}
spl_autoload_register ('myAutoloader');
4) Then your index.php is as clean as
$action = $_GET['action'] ?? '';
if (strlen($action) > 0 && class_exists($action) && method_exists($action, 'execute')) {
$oAction = new $action();
$oAction->execute();
} else {
// Oopsie
}
(Notes on this last snippet: the "class_exists" triggers the auto-loader. the "method_exists" is to check someone hasn't requested a common php class such as "object"; if you're being safer you should namespace this or add extra validation. This is just an example!)
apologies for the possible n00b question but here we go. I'm currently writing a service class in symfony2 which collects data using ajax. The data basically consists of two timestamps sent upon form submit. What I then want to do is pass this to my controller and write it to a custom parameters.yml file so I can store the values in this file and update this file each time a user submits the form. I am getting an error like this :
Impossible to call set() on a frozen ParameterBag
And some searching on Google tells me that I cannot modify the Container once it has been compiled. The line in particular which is causing this is :
$this->container->setParameter('quicksign.start.off', $startOff);
Okay time to show my code. Here is my controller :
public function updateServiceSigAction() {
$logger = $this->get('logger');
$request = $this->get('request');
$errors = array();
if (WebserviceController::POST_ONLY && $request->getMethod() != 'POST') {
$errors[] = "Not allowed !";
return $this->sendResponse($errors);
}
$params = $request->request->all();
if (count($params) == 0) {
$errors[] = "Missing parameters !";
return $this->sendResponse($errors);
} else {
$servicesig_services = $this->get('servicesigservice');
$errors = $servicesig_services->updateServiceSig($params, false);
}
return $this->sendResponse($errors, array(), true);
}
And here is the relevant method of my service class :
public function updateServiceSig($params, $need_to_flush = true) {
$errors = array();
$startOff = $params['date_debut'];
$endOff = $params['date_fin'];
if (empty($startOff) || empty($endOff)) {
$errors[] = "Missing parameters from query !";
} else {
$this->container->setParameter('quicksign.start.off', $startOff);
$this->container->setParameter('quicksign.end.off', $endOff);
}
return $errors;
}
Maybe I should do this before compiling the container ? But I don't know where exactly the container is being compiled...
Or maybe I should do it another way...?
So here's how I got it done :
use Symfony\Component\Yaml\Dumper; //I'm includng the yml dumper. Then :
$ymlDump = array( 'parameters' => array(
'quicksign.active' => 'On',
'quicksign.start.off' => $startOff,
'quicksign.end.off' => $endOff ),
);
$dumper = new Dumper();
$yaml = $dumper->dump($ymlDump);
$path = WEB_DIRECTORY . '/../app/config/parameters.sig.yml';
file_put_contents($path, $yaml);
Where WEB_DIRECTORY is defined in the app.php file -> however, you should use
%kernel.root_dir%
in the service configuration.
From my understanding you are using the parameters.yml file wrong. The official documentation states:
One use for this is to inject the values into your services. This allows you to configure different versions of services between applications or multiple services based on the same class but configured differently within a single application.
So the file is not for storing a services state but to configure the initial state. You use it if multiple applications use the same source-code. An example would be a staging and a production environment, or multiple services in one application like two ORMs that need different connection parameters. With that said you should probably use an entity to store your timestamps in it.
If you really need a file you can use e.g. Symfony's YAML component to manage a custom .yml file.
I am using CakePHP v1.2 for my web application hosted here: http://lol-land.in
The application was working fine till Yesterday, but it suddenly started to get stuck in some redirection loops. What makes it weirder is the fact that the problem is with just one controller: posts. And even in that most of the functions are working. But http://lol-land.in/posts is redirecting to lol-land.in/posts/view/133 which is in turn redirecting to itself.
Actually 110 of the 117 posts of the form /posts/view/ are stuck in this 302 redirection.
Can anyone please tell me what could have caused this?
[CakePHP 1.3 and PHP5]
Edit: Adding View Logic
function view($id = null) {
$this->log("View Logic Entry", LOG_DEBUG);
// These Log entires are missing
$this->layout = 'postview';
if (!$id) {
$this->Session->setFlash(__('Invalid Post.', true));
$this->log("Redirect due to missing id", LOG_DEBUG);
$this->redirect(array('action'=>'index'));
}
$log = $this->Session->read('Auth.User');
$logid = $log['id'];
$temp = $this->Post->read(null, $id);
$ratings = $temp['Rating'];
$this->set(compact('up', 'down', 'userrated', 'userrateid'));
$coms = $temp['Comment'];
$comuser = array();
for ($i=0; $i<count($coms); $i++) {
$comuser[$i] = $coms[$i]['user_id'];
}
$comuser = $this->Post->User->find('list', array( 'fields'=>array('User.id', 'User.username'),
'conditions'=>array("User.id" => $comuser)
));
$this->set(compact('comuser'));
$this->pageTitle = $temp['Post']['title'];
$this->set('post', $temp);
$alltypes = $this->Post->Type->find('list', array('fields'=> array('Type.id', 'Type.typename')));
$selectedtab = -1;
$this->set(compact('alltypes', 'selectedtab' ));
//Calling updateFBStats
// Removed because unnecessary.
}
Chances are you are either 1) using circular references with the Auth component OR 2) the function in your controller is redirecting do to something within the method. Can you show the code of posts_controller.php function view() ?