Concrete5 8.2.1 Using Core classes outside of concrete

429 views Asked by At

I am trying to use the Concrete Core Classes to create a user outside of the main folder structure.

For example I had a main folder called

Project One
-- concrete
-- application
-- packages
... etc etc

and another folder called user-upload. In here I have an import-users.php script.

I have a single page which has a form with a file upload element. This takes a CSV and tries to send it to the import-users.php script ready to loop through and create a new user for each row in the CSV. But I keep getting the following error when trying to use the classes:

Fatal error: Class 'Core' not found in path/user_upload/import-users.php on line 6 Call Stack: 0.2009 254592 1. {main}() path/user_upload/import-users.php:0

How can I use the class outside of the concrete5 installation?? Examples would be extremely helpful

Edit 1 Script to upload the CSV

$('#user_upload_submit').click(function () {

    var fileInput = document.getElementById('usersfile');
    var file = fileInput.files[0];
    var formData = new FormData();
    formData.append('file', file);

    $.ajax({
        type: "POST",
        url: new_path+"user_upload/import-users.php",
        data: formData,
        contentType: false,
        processData: false,
        success: function (msg) {
            $('#user_result').html(msg); 
        },
        error: function (jqXHR, exception) {
            var msg = '';
            if (jqXHR.status === 0) {
                msg = 'Not connect.\n Verify Network.';
            } else if (jqXHR.status == 404) {
                msg = 'Requested page not found. [404]';
            } else if (jqXHR.status == 500) {
                msg = 'Internal Server Error [500].';
            } else if (exception === 'parsererror') {
                msg = 'Requested JSON parse failed.';
            } else if (exception === 'timeout') {
                msg = 'Time out error.';
            } else if (exception === 'abort') {
                msg = 'Ajax request aborted.';
            } else {
                msg = 'Uncaught Error.\n' + jqXHR.responseText;
            }
            alert(msg);
        }

    });
});
1

There are 1 answers

7
Michele Locati On BEST ANSWER

First of all, you should add a validation token to every request you send to the server, and the server-side script should validate the received token.

Then, you should handle the submit in the single page controller.

Let's assume your single page is available at the /test path. The View of your single page (where you put the HTML and JavaScript) must be saved as /application/single_pages/test.php. The controller of the single page (where you put the PHP code that handles the requests) must be saved as /application/controllers/single_page/test.php.

In the /application/single_pages/test.php you have to add a validation token to the data to be sent, and you have to call the URL of a controller method (let's call it handleSubmit).

This can be done with this code:

<script>
<?php
$token = Core::make('token');
?>
$('#user_upload_submit').click(function () {
    // ...
    var formData = new FormData();
    formData.append(<?= json_encode($token::DEFAULT_TOKEN_NAME) ?>, <?= json_encode($token->generate()) ?>);
    formData.append('file', file);
    $.ajax({
        url: <?= json_encode($view->action('handleSubmit')) ?>,
        data: formData,
        // ...
    });
});
</script>

Then, your controller file (/application/controllers/single_page/test.php) can be something like this:

<?php

namespace Application\Controller\SinglePage;

use Concrete\Core\Error\UserMessageException;
use Concrete\Core\Http\ResponseFactoryInterface;
use Concrete\Core\Page\Controller\PageController;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class Test extends PageController
{
    public function handleSubmit()
    {
        $token = $this->app->make('token');
        if (!$token->validate()) {
            throw new UserMessageException($token->getErrorMessage());
        }
        $file = $this->request->files->get('file');
        if (!($file instanceof UploadedFile)) {
            throw new UserMessageException(t('File not received.'));
        }
        if (!$file->isValid()) {
            throw new UserMessageException($file->getErrorMessage());
        }
        // Process the file. It's path is $file->getPathname();
        // ...

        // Send the final response
        return $this->app->make(ResponseFactoryInterface::class)->json(true);
    }
}

The namespace of the controller and its class name must reflect the URL of the single page.

Examples:

  1. Your single page is available as /test

    • Full path to the view: /application/single_pages/test.php
    • Full path to the controller: /application/controllers/single_page/test.php
    • Namespace of the controller: Application\Controller\SinglePage
    • Class name of the controller: Test
  2. Your single page is available as /foo/bar/baz

    • Full path to the view: /application/single_pages/foo/bar/baz.php
    • Full path to the controller: /application/controllers/single_page/foo/bar/baz.php
    • Namespace of the controller: Application\Controller\SinglePage\Foo\Bar
    • Class name of the controller: Baz