This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

mjanes
mjanes

I've been trying to figure this out for a while and read extensively on the forums but I was unable to find a solution that worked. I am trying to save the url of a file using the file upload function on the backend. I am aware you do not need this if using the file within october but I am trying to use this database across multiple domains and the files need to have a path to the s3 bucket that is not related to october.

When I go to add a new record this is the view:

Test

After I upload the file I need to populate the url field or the database with the path to the file.

I know october can show this url because if you click on the field after a file has been uploaded it shows a popup with a link to the attachment url:

Test

This is what I would like to achieve:

Test

This feels like it should be really simple but I could not find a supported way to do this based on the documentation. I thought about using javascript to grab the file name after upload but that felt sub-optimal so I wanted to see if there was a better way. Thanks in advance for any insight!

mjauvin
mjauvin

Did you try changing the "storage.uploads.disk" to "s3" in config/cms.php ?

Also, make sure you correctly configure "disks.s3" settings in config/filesystems.php

mjanes
mjanes

I have no issues uploading the file and can access them just fine but I want to save the url into the database when I create the record so they can be referenced outside of the application.

mjauvin
mjauvin

Oh, so you want to access the files through a URL served by the October based website?

mjanes
mjanes

I want to be able to access the file outside of october which requires a full url (or at least the extension of where it was placed on the s3 bucket) as there is no relationship between the record and the file outside of the application.

mjauvin
mjauvin

You can always extend the File model with an model.afterSave event as below:

\System\Models\File::extend(function ($model) {
    $model->bindEvent('model.afterSave', function () use ($model) {
        $url = $model->getPath();
        // do something with URL
    });
}); 

Last updated

mjauvin
mjauvin

I had the wrong method in my previous post (updated), should have been getPath()

mjanes
mjanes

Thank you for that. Looks like it would work but I am not sure where to implement it. My model view and controller are below. Where would I add this to get it into the form field?

Model:

<?php namespace Test\test\Models;

use Model;

/**
 * Model
 */
class Test extends Model
{
     use \October\Rain\Database\Traits\Validation;

    /*
     * Disable timestamps by default.
     * Remove this line if timestamps are defined in the database table.
     */
    public $timestamps = false;

    /**
      * @var string The database table used by the model.
     */
    public $table = 'test';

     /**
     * @var array Validation rules
     */
    public $rules = [
    ];

    public $attachOne = [
        'upload' => 'System\Models\File'
    ];
}

View

<?php Block::put('breadcrumb') ?>
    <ul>
        <li><a href="<?= Backend::url('test/test/test') ?>">Test</a></li>
        <li><?= e($this->pageTitle) ?></li>
    </ul>
<?php Block::endPut() ?>

<?php if (!$this->fatalError): ?>

    <?= Form::open(['class' => 'layout']) ?>

        <div class="layout-row">
            <?= $this->formRender() ?>
        </div>

        <div class="form-buttons">
            <div class="loading-indicator-container">
                <button
                type="submit"
                data-request="onSave"
                data-request-data="redirect:0"
                data-hotkey="ctrl+s, cmd+s"
                data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
                class="btn btn-primary">
                    <?= e(trans('backend::lang.form.save')) ?>
                </button>
                <button
                type="button"
                data-request="onSave"
                data-request-data="close:1"
                data-hotkey="ctrl+enter, cmd+enter"
                data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
                class="btn btn-default">
                <?= e(trans('backend::lang.form.save_and_close')) ?>
                </button>
                <button
                type="button"
                class="oc-icon-trash-o btn-icon danger pull-right"
                data-request="onDelete"
                data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
                data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
               </button>

                <span class="btn-text">
                    <?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('test/test/test') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
                </span>
            </div>
        </div>
    <?= Form::close() ?>

<?php else: ?>
    <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
    <p><a href="<?= Backend::url('test/test/test') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>

Controller:

<?php namespace Test\test\Controllers;

use Backend\Classes\Controller;
use BackendMenu;

class Test extends Controller
{
    public $implement = [        'Backend\Behaviors\ListController',      'Backend\Behaviors\FormController',        'Backend\Behaviors\ReorderController'    ];

    public $listConfig = 'config_list.yaml';
    public $formConfig = 'config_form.yaml';
    public $reorderConfig = 'config_reorder.yaml';

    public function __construct()
    {
        parent::__construct();
        BackendMenu::setContext('Test.test', 'test');
    }
}
mjauvin
mjauvin

Just add the code snippet I provided in your Plugin's boot() method

mjauvin
mjauvin

Not sure which form field you mean, but wherever you get an instance of your Test model, you should be able to call $model->upload->getPath() to fetch the URL to the file.

But the code snippet I provided could be used to save the full URL to an alternate database.

mjanes
mjanes

Perfect. That works and I can enter the url into the database if I define the record id manually but now I need to figure out how to get the current id of a record I am updating or the id of a record I am creating. I tried using Route::get for a record that was being updated but that did not seem to work. Is that on the right track or is there an easier way to get the id of (1) from the url: /test/update/1.

mjauvin
mjauvin

You could add an update_onSave and create_onSave method and get the record id with post('id')

mjauvin
mjauvin

Use this in your Model:

public function beforeSave()
{   
   $url = $this->upload->getPath();
   $id = $this->id;
   // do whatever you want here
}

1-13 of 13

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.