I need to rename and save a file upload when saving an item in a custom component. The problem is that the JFile::makeSafe function seems like is not converting the filename as you can see below.

So I have overridden the save function in the models/test.php like this :

  public function save($data) {
    JRequest::checkToken() or die('Invalid Token');
    $date = JFactory::getDate()->format('Y-m-d h:m:s');

    if (empty($data['created'])) {
      $data['created'] = $date;

    if (!empty($data['file'])) {
      $data['file'] = JFile::makeSafe($data['file']);
      $src = $data['file'];
      $dest = JPATH_COMPONENT_ADMINISTRATOR . '/uploads/' . $data['client_id'] . '/' . $data['id'] . '_' . $data['file'];

      if (strtolower(JFile::getExt($data['file'])) == 'doc' || strtolower(JFile::getExt($data['file'])) == 'docx') {
        JLog::add('File Destination: ' . $dest, JLog::DEBUG, 'com_test-save item');
        if (JFile::upload($src, $dest)) {

      JLog::add('Data to save: ' . print_r($data, TRUE), JLog::DEBUG, 'com_test-save item');

    return parent::save($data);

The log :

2018-07-20T09:02:38+00:00       DEBUG com_testt-saveitem   Filename before JFile::makeSafe : My FILE TO UPLOAD.docx
2018-07-20T09:02:38+00:00       DEBUG com_test-saveitem   Filename AFTER JFile::makeSafe : My FILE TO UPLOAD.docx
2018-07-20T09:02:38+00:00       DEBUG com_test-saveitem   File Destination: /Projects/myProjects/joomla/administrator/components/com_test/uploads/240/2_My FILE TO UPLOAD.docx
2018-07-20T09:02:38+00:00       DEBUG com_test-saveitem   Data to save: Array
    [id] => 2
    [title] => test
    [alias] => test
    [catid] => 0
    [client_id] => 240
    [published] => 0
    [created] => 2018-07-20 06:07:43
    [file] => My FILE TO UPLOAD.docx
    [tags] => 

And when I save the item, I get the following warning :

    Warning: Failed to move file: My FILE TO UPLOAD.docx to /Projects/myProjects/joomla/administrator/components/com_test/uploads/240/2_My FILE TO UPLOAD.docx

The models/forms/test.xml

<?xml version="1.0" encoding="utf-8"?>
    <field name="id" type="text" default="0" label="JGLOBAL_FIELD_ID_LABEL"
           readonly="true" class="readonly"
    <field name="title" type="text" class="inputbox"
           size="40" label="JGLOBAL_TITLE"
           description="COM_TEST_FIELD_TITLE_DESC" required="true" />
    <field name="alias" type="text" class="inputbox"
           size="40" label="JFIELD_ALIAS_LABEL"
           description="COM_TEST_FIELD_ALIAS_DESC" />
    <field name="access" type="accesslevel" label="JFIELD_ACCESS_LABEL"
           description="JFIELD_ACCESS_DESC" class="span12 small" size="1" />
    <field name="catid" type="category" extension="com_test" class="inputbox" default="" label="COM_TEST_FIELD_CATID_LABEL" 
      <option value="0">JOPTION_SELECT_CATEGORY</option>
    <field name="client_id" type="user"
           required="true" />
    <field name="published" type="list" label="JSTATUS" description="JFIELD_PUBLISHED_DESC" class="inputbox small" size="1" default="1" >
      <option value="1">JPUBLISHED</option>
      <option value="0">JUNPUBLISHED</option>
      <option value="2">JARCHIVED</option>
      <option value="-2">JTRASHED</option>
      name="cache_handler" type="cachehandler" default="" label="COM_TEST_FIELD_CACHE_HANDLER_LABEL"
      description="COM_TEST_FIELD_CACHE_HANDLER_DESC" filter="word">
      <field name="catid" type="category" extension="com_test"
             label="JCATEGORY" description="COM_TEST_FIELD_CATEGORY_DESC"
      filter="user_utc" />
      <field name="file" type="file" label="Enter some text" description="Choose an image from your computer with maximum 100KB" 
             size="40" accept=".doc, .docx" />
  • Are you sure it's not becuase you're appending $data['id'] to the file name in the destination?
    – Lodder
    Jul 20 '18 at 15:31
  • Yes, If you take a look to the JLog commands there is on just before the JFile::makeSafe and one right after it and print exactly the same output. But just to be sure I tried to remove the $data['id'] from the destination with exactly the same result.
    – mixahlos
    Jul 20 '18 at 16:24
  • You might like to DRY out the one line to be: if (in_array(strtolower(JFile::getExt($data['file'])), ['doc', 'docx'])) {
    – mickmackusa
    Aug 15 '19 at 8:59

Well, the JFile::makeSafe() method doesn't do the conversion that I thought it did. I thought that it would remove spaces from the filename as well.

The description in the Joomla docs is not very clear.

Makes file name safe to use.

So I used strtolower() and str_replace() to modify the filename.

  • If your question is resolved, please accept your own answer so that the system stops bumping it.
    – mickmackusa
    Aug 15 '19 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.