GithubHelp home page GithubHelp logo

dereuromark / cakephp-ajax Goto Github PK

View Code? Open in Web Editor NEW
58.0 58.0 25.0 4.07 MB

AJAX for CakePHP: A plugin to ease handling AJAX requests.

License: MIT License

PHP 100.00%
ajax cakephp cakephp-plugin php

cakephp-ajax's Introduction

Freelance PHP Expert ๐Ÿ‘‹

For 20+ years in the PHP world, open source contributor and ecommerce builder. Framework specialist and tooling/automation guru. Mainly backend, but essentially fullstack.

๐Ÿ’ฌ You got a problem to solve? You want some help on a project or a new feature built? Lets find a way to get it solved. Hit me up.

cakephp-ajax's People

Contributors

adamharley avatar andream98 avatar dereuromark avatar gi-jones avatar joshrhykerd avatar oxicode avatar sarrala avatar zuluru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cakephp-ajax's Issues

Compatibility with 3.1 "_serialize = true" feature?

Looks like _respondAsAjax needs a bit of a tweak to properly support the new option of setting _serialize to true to serialize all view variables? It's currently assuming that $this->Controller->viewVars['_serialize'] is an array. I'd say that just checking if that is === true and exiting early if so would work. Alternately, only doing the serializeKeys portion if it's !== true, if you prefer to have only one exit point from functions.

Incompatibility with CRUD plugin

So I've been trying to make this work in conjunction with https://github.com/FriendsOfCake/crud, but any time I have an action CRUD enabled the content is left out of the AJAX response.

I've tracked it down to this bit of code in View/AjaxView.php

if (isset($this->viewVars['success'])) {
   $dataToSerialize['success'] = $this->viewVars['success'];
   $view = false;
}
if ($view !== false && !isset($this->viewVars['_redirect']) && $this->_getViewFileName($view)) {
   $dataToSerialize['content'] = parent::render($view, $layout);
}

As you can see from https://crud.readthedocs.io/en/latest/actions/index.html#serialize, CRUD will always set a success viewVar when a request works. Which then means that the Ajax plugin skips rendering.
Is there any particular reason for this behaviour? I'm not sure I understand why you would not want to render content, by definition, on a successful request?

Ajax request without view created throwing execption

hi there,

I started to use this nice one Plugin but I didn't find out how to do an Ajax Request but not have to create ajax/view.ctp. I wondering if it's possible to make an Ajax Request wihtout content field in json returned and not have to create ajax/view.ctp at each ajax request through the Plugin.

Even when calling in Ajax an url having json extension, the plugin wants me to create a view.

How to load plugin Helper within AjaxView

Hi,

Using Ajax Component, I'd like to use Helper within AjaxView but I can't success at it.
There is some Helper that I use commonly in my AppView Class that I'd like to use in AjaxView class. Those Helpers comes from Plugin.

How can I mention to AjaxView to load some Helper ?

Doesn't work with new Authorization plugin

The new middleware-based plugin architecture does not trigger the beforeRedirect event, thus breaking the Ajax component. I built a workaround (my own "unauthorized" handler registered with the Authorization service) that triggers the event manually for now, but it seems the event needs to be triggered on the component registry's event manager, not the global one. I couldn't find a clean way to access the component registry in the handler, so I added a very ugly hack to make it available via a static property of my AppController class:

$event = new Event('Controller.beforeRedirect', null, [$url, $response]);
AppController::$__components->getEventManager()->dispatch($event);
if ($event->isStopped()) {
    $response = $event->result;
}

Maybe we need a middleware version of the functionality? Seems like a straight-forward implementation, just adjusting the response some as the stack unwinds.

Disable component for some actions

Hi,

Using the Ajax Component in most my controllers and actions, I'd like to disable it for some actions where I want to use a classic jsonView via an Ajax request to get some datas. Component want me to create a view in /ajax/myAction.ctp as well ...

How can I disable the component for some actions only ?

Thanks

_message has the flash definition data instead of the final message when using custom flash elements

In most cases, this component is working brilliantly for me, it saves so much code in my controllers! I've come across one situation where I need to do special formatting of my flash message using helpers (e.g. the Time helper to format a date and time according to user preferences), and so I'm using a custom flash element, like:

$this->Flash->my_custom_element(null, ['params' => ['variable' => $variable]]);

And then src/Element/Flash/my_custom_element.ctp looks something like this:

echo $this->element('BootstrapUI.Flash/default', [
    'message' => __('Here is the custom message about {0}',
        $this->Time->date($params['variable']->created)),
    'params' => [
        'class' => ['warning', 'alert', 'alert-dismissible', 'fade', 'in'],
        'escape' => false,
        'attributes' => ['role' => 'alert'],
    ],
]);

When this comes to my Ajax response handler, the _message parameter has an object with keys like so:

element: "Flash/my_custom_element"
key: "flash"
message: null
params: Object
    variable: Object
        (all the $variable data is here)

Seems that when you call $this->Controller->request->session()->consume, you get back an array in such cases instead of just a message, and something further needs to be done to use the element to format this before setting it into _message.

Not sure if it makes a difference that I'm using the Friends Of Cake BootstrapUI plugin to nicely format flash output, but that works fine with all my "standard" flash messages (e.g. $this->Flash->info(__('Message goes here.'));) Also, using this for non-Ajax requests renders the flash element correctly, so I know that much of it is okay.

Problems using this plugin

Hello, I've recently downloaded this plugin to have its AJAX candy in my CakePHP 4.3 app, but I cannot manage to make it work like in the CakePHP Sandbox app's examples.

Here's what I've done up until now:

  1. I've installed the plugin via composer
  2. I've included it in the app by loading it inside my src/Application.php::bootstrap() method
  3. I've loaded the Ajax.AjaxComponent inside the controller and whitelisted a single delete method
...

public function initialize(): void
{
	parent::initialize();

	if (in_array($this->request->getParam('action'), ['delete'])) {
		$this->loadComponent('Ajax.Ajax');
	}
}

...
  1. I've created a button inside a table's rows that deletes the row that it's in via a JS fetch() call to the delete method mentioned above, here is its code (I converted the example jQuery to vanilla JS):
document.querySelectorAll('[data-ajax-delete="true"]').forEach((deleteButton) => {
  document.querySelector(`#${deleteButton.id}`).removeAttribute("onclick");
  deleteButton.addEventListener("click", async (event) => {
        event.preventDefault();

        let confirmMessage = deleteButton.confirm;
        if (confirmMessage && !confirm(confirmMessage)) {
          return false;
        }

        let form = deleteButton.previousElementSibling,
          url = form.action + ".json",
          tr = deleteButton.closest("tr");

        const response = await fetch(url, {
          method: "DELETE",
          headers: {
            "Content-type": "application/x-www-form-urlencoded",
          },
        });

        response.json().then(data => {
          console.log(data)
        })

        return false;
      });
});

But the result is not what I expected, as there are a few problems that I don't know if are related to a bad implementation on my part. In fact when the button is pressed, and the delete method gets called, the row gets effectively deleted but there are a few problems that I'm facing:

  1. The FormProtectionComponent errors out ('_Token' was not found in request data) only if the delete method contains a redirect, even when I've excluded the delete method from being checked by FormProtection
public function beforeFilter(EventInterface $event)
{
	parent::beforeFilter($event);

	$this->FormProtection->setConfig('unlockedActions', ['delete']);
}
  1. When I remove the redirect the error is gone but there isn't any data in the response object, this is what my delete method looks like:
public function delete(?string $id)
{
	$this->request->allowMethod(['delete']);
	$thingToDelete = $this->Things->get($id);

	if ($this->Things->delete($thingToDelete)) {
		$result = true;
		$this->Flash->success(__d('Crm', 'The custom variable has been deleted.'));
	} else {
		$result = false;
		$this->Flash->error(__d('Crm', 'The custom variable could not be deleted. Please, try again.'));
	}

	$this->set(compact('result'));
	$this->viewBuilder()->setOption('serialize', ['result']);
}

and this is the response object that I get after I press the button:

image

as you can see, only variables that I manually set inside the delete method get set in the response, in contrary to what I've seen inside the examples where everything gets passed down (Flash, redirect etc.)

Did I mess something up?

Deprecation notice

Notice: Deprecated (16384): Response::type() is deprecated. Use getType() or withType() instead. - /vendor/dereuromark/cakephp-ajax/src/View/AjaxView.php, line: 80
You can disable deprecation warnings by setting Error.errorLevel to E_ALL & ~E_USER_DEPRECATED in your config/app.php

Why do you only show _message after a redirect?

Hello,
any particular reason? For example in my action i do the login and set a flash message via success() I would like to see that message always (not only if i set a redirect).

Thanks

Feature: json error

Would be nice to have something like:

$result = json_encode($response);
if (json_last_error() != JSON_ERROR_NONE) {
    return json_encode(['error' => json_last_error_msg()]);
}
return $result;

@ AjaxView::render

What do you think about it?

Composer update failed

Hi Mark

I have your cakephp-ajax in my test environment. Yesterdad i was doing a composer update on cakephp, and it failed on cakephp-ajax

this is the result. What could hava happend ?

regards,
Tom

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 14 updates, 0 removals
  - Updating symfony/process (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating symfony/finder (v3.2.3 => v3.2.4) Loading from cache
  - Updating symfony/filesystem (v3.2.3 => v3.2.4) Loading from cache
  - Updating symfony/debug (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating symfony/console (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating cakephp/chronos (1.0.4 => 1.1.0) Downloading: 100%         
  - Updating cakephp/cakephp (3.3.14 => 3.3.15) Downloading: 100%         
  - Updating cakephp/debug_kit (3.8.0 => 3.9.0) Downloading: 100%         
  - Updating nikic/php-parser (v3.0.3 => v3.0.4) Downloading: 100%         
  - Updating symfony/var-dumper (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating league/flysystem (1.0.34 => 1.0.35) Downloading: 100%         
  - Updating symfony/config (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating symfony/yaml (v3.2.3 => v3.2.4) Downloading: 100%         
  - Updating dereuromark/cakephp-ajax dev-master (1058903 => 985c009)    Update failed (Failed to execute git show-ref --head -d

sh: 1: git: not found
)
    Would you like to try reinstalling the package instead [yes]? yes
  - Removing dereuromark/cakephp-ajax (dev-master)

                                            
  [RuntimeException]                        
  Failed to execute git show-ref --head -d  
  sh: 1: git: not found       

Flash messages are not shown in the view

Hello,
I found a problem with Flash messages. I have seen that plugin is using consume() method to get messages from sessions. This is a problem when we try to print Flash->render(...) in the view. The content will never has the messages. Any workaround?

Integration issues with Authentication plugin

I experienced strange behavior with this plugin, and I was unable to determine why. or the solution. I assumed you could have encountered this before.

I have a controller method changeTheme that changes user preferences.

When using a normal POST, (with a page redirect) everything goes fine.
But, when I call the same method through AJAX, I got an error (probably before Ajax Component, since its a HTML error)
saying

Error: Authorization\AuthorizationService::can(): Argument #1 ($user) must be of type ?Authorization\IdentityInterface, Authentication\Identity given, called in /var/www/html/vendor/cakedc/auth/src/Traits/IsAuthorizedTrait.php on line 63

When I remove the line $this->Authentication->setIdentity($user); everything work as expected.

Maybe this is related with the order plugins are loaded, or something like that, but I dont know internals of both your plugin and Authorization one to confirm that.

My method is:

    public function changeTheme() {

        if ($this->getRequest()->is(['patch', 'post', 'put'])) {

            $table = $this->fetchTable();

            // get logged User ID
            $identity = $this->getRequest()->getAttribute('identity');
            $identity = $identity ?? [];
            $loggedUserId = $identity['id'] ?? null;

            if (!$loggedUserId) {
                $this->Flash->error(__d('cake_d_c/users', 'User was not found'));
                return $this->redirect($this->getRequest()->referer());
            }

            // get the current user and set a view variable
            $user = $table->get($loggedUserId, ['contain' => $this->contain]);
            $user = $table->patchEntity($user, $this->getRequest()->getData());

            if ($table->save($user)) {
                $this->Authentication->setIdentity($user);
                $this->Flash->success(__('Your theme has been saved'));
            } else {
                $this->Flash->error(__('Your theme mode could not be saved'));
            }
        }


        return $this->redirect($this->getRequest()->referer());
    }

Do you have any thoughts?

issues after update from cakePHP 3.0 to cakePHP 3.1

Hi Mark

After running the update on composer I got the following issues:

  1. during update
    issue: update ok by composer but /src folder was empty.
    solution: remove manually the folder and settings on composer.json, composer.lock and vendor/cakephp-plugins.php
    PS: same issue happened with PHPMailer

  2. before on every action I was using
    $this->viewClass = 'Ajax.Ajax';

but then after update I got this error message:

2015-09-27 08:53:24 Error: [Cake\View\Exception\MissingTemplateException] Template file "ajax/.ctp" is missing.
Request URL: /users/checkusername
Stack Trace:
#0 .../dereuromark/cakephp-ajax/src/View/AjaxView.php(98): Cake\View\View->_getViewFileName(NULL)
#1 .../cakephp/cakephp/src/Controller/Controller.php(598): Ajax\View\AjaxView->render(NULL, NULL)
#2 .../cakephp/cakephp/src/Routing/Dispatcher.php(120): Cake\Controller\Controller->render()
#3 .../cakephp/cakephp/src/Routing/Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\UsersController))
#4 .../Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#5 {main}

I solved changing:
$this->viewClass = 'Ajax.Ajax'; to => $this->viewClass = 'Ajax';
But, then I also need to move all *.ctp files from /Action/ajax folder to to /Action folder.

I got it running but if there is anything that I'm doing wrong it would be nice to know to avoid me to review and test all code everytime I upgrade.

Danke, Eduardo

Create PR for CAKE3.0

Hi Mark!

This is not exactly the issue, but can you tell me please why this is not the part of Cake3 core? Cake includes AjaxView for example but it is doing only half of the job

Not using the subdirectory for view file

Mark,

I am using this plugin in my app and I needed to skip the subdirectory for view file like this src\Template\ajax\ACTION_NAME.ctp as I am using a new controller for ajax requests.

So, I changed the code here https://github.com/dereuromark/cakephp-ajax/blob/master/src/View/AjaxView.php#L68-L70 and set it to -
$this->subDir = null;

Now, I am not sure if this make a good feature and if yes, how to make this option configurable so that it can be put in the repository. What are you comments on it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.