Custom Processor/Connector for CMP returning 401 Access Denied?

I’m trying to learn how to develop a class-based processor in MODX3 for a CMP I’m building. My connector is very simple:

<?php
require_once dirname(__FILE__, 4) . '/config.core.php';
require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
require_once MODX_CONNECTORS_PATH . 'index.php';

$path = MODX_CORE_PATH . 'components/fbecevents/processors/';
$modx->request->handleRequest([
    'processors_path' => $path,
    'location' => '',
]);

My processor is also fairly simple:

<?php
class ModifyEventProcessor extends modProcessor {
    public function checkPermissions() {
        return $this->modx->user->hasSessionContext('mgr');
    }

    public function process() {
        require_once dirname(__FILE__, 4) . '/config.core.php';
		require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
		require_once MODX_CONNECTORS_PATH . 'index.php';

		$namespace = "FBECEvents\\Model\\";
		$corePath = $modx->getOption('core_path') . 'components/fbecevents/';
		$output = array('success' => 0, 'message' => '');

		$update = $this->getProperty('update', '');
		$acted = true;
		$id = $this->getProperty('id', 0);
		$event = $modx->getObject($namespace.'fbecEvent', $id);

		if($event){
			switch ($update) {
				case 'toggleProp':
						$event->set($this->getProperty('prop'), filter_var($this->getProperty('state'), FILTER_VALIDATE_BOOLEAN));
						break;
				
				case 'changeReviewState':
						$event->set('review_status', $this->getProperty('state'));
						break;
						
				case 'updateField':
						$event->set($this->getProperty('field'), $this->getProperty('value'));
						break;
					
				default:
					$acted = false;
			}

			if(!$acted)
				$output['message'] = 'Invalid update. No changes made. ';
			elseif($event->save()){
				$output['success'] = 1;
				$output['message'] .= 'Event ('.$event->get('event_name').':'.$event->get('id').') saved. ';
			}else
				$output['message'] = 'Error saving event '.$event->get('event_name')." ($id)";
		}else
			$output['message'] = 'Event not found: '.$id;

		return $this->outputArray($output);
    }
}
return 'ModifyEventProcessor';

At first I was doing this directly in the connector.php file, which worked fine but I decided I wanted to do it the proper way. So I moved all the code into the process() function in this modifyEvent.class.php file, which I’ve cobbled together from examples on the Internet and suggestions from Claude. But when I make a call to the connector, all I ever get back is this:

{"success":false,"message":"Access denied.","total":0,"data":[],"object":{"code":401}}

What am I doing wrong?

TIA!

How do you make the call?
If you don’t use Ext.js (MODx.Ajax.request()), I believe you have to supply the “modAuth” parameter.

Your code still looks a lot like MODX 2.x (with no namespaces).

Also, you don’t need a custom connector. You can call a custom processor using the default MODX-connector, if you supply the fully-qualified class name as the “action” parameter.

Ah, yeah; I’m using vanilla JS. I don’t know how to work with ExtJS lol
Where do I get the value for modAuth?

Does it? That’s probably because I’ve been looking at stuff like Processors - Extending MODX | MODX Documentation

I am using a namespace for my custom model ($namespace = "FBECEvents\\Model\\";) but I guess that’s not exactly what you mean? If you could point me to a tutorial for the 3x way of doing it, or a simple example of it, I’d be very appreciative.

Oh yeah? That could be handy. Do I just call /connectors/index.php instead of /assets/components/fbecevents/connector.php and pass something like components/fbecevents/processors/modifyEvent for the action parameter?

Thanks!

Here is a simple example:

I assume you have a bootstrap.php to add your custom model. Put the processors in the same “src” folder.

Here is an example with Ext.js (using MODx.Ajax.request to make an AJAX request). MODx.config.connector_url contains the default MODX connector URL.

If you want to use fetch instead, you have to add a HTTP_MODAUTH parameter (something like this):

fetch(MODx.config.connector_url + '?' + new URLSearchParams({
	action: 'SimpleExtra\\Processors\\Sample',
	HTTP_MODAUTH: MODx.siteId
})

or a modAuth header (something like this):

fetch(MODx.config.connector_url + '?' + new URLSearchParams({
		action: 'SimpleExtra\\Processors\\Sample'
	}),
	{
		method: "GET",
		headers: {
			'modAuth': MODx.siteId
		}
	}
)

This is very helpful; thank you! I’m making progress but I think I have something wrong with my pathing. The error I’m getting now is Requested processor not found. I’m passing action: FBECEvents\Processors\ModifyEvent . Here’s a screenshot of my directory structure:

And here’s what my processor looks like now:

namespace FBECEvents\Processors;

use MODX\Revolution\Processors\Processor;

class ModifyEvent extends Processor {

...etc

I’m not sure what the fully-qualified path to my processor is.

Thank you again for your help!

Assuming you have a standard bootstrap.php file that uses the “src” folder as the path for addPackage(), you have to put your processors in the “src” folder as well (so that the autoloader works).

Then the folder structure inside “src” defines the namespace of a class:

  • Your custom class fbecEvent is inside the Model folder, so the fully qualified name is FBECEvents\Model\fbecEvent.
  • If you put the processor inside a Processors folder, then the namespace is FBECEvents\Processors and the fully qualified name of your class is FBECEvents\Processors\ModifyEvent.

Also make sure that the processor file has the same name as your class (check the capitalization) and ends in .php instead of .class.php.

1 Like

Ah, now we’re cooking with gas! You, sir, are a gentleman and a scholar.

Thank you so much!

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.