Unable to save image path to database

Hi all

I’m hoping someone can help me please. I have a PHP model and controller that upload image files to a folder from a html form and it works perfectly, even renaming the file. However, I now want to store the path to the image and some other info in the database and that’s where I am stuck. The image gets renamed and uploaded but nothing saved to db. I get this error message:

‘Too few arguments to function controllers\Profiles\bits\AvatarCtrlr::uploadAction(), 0 passed and exactly 1 expected’

Here is my code thus far:
FROM THE MODEL:

public static function uploadAvatar($data)  {      
        try {
            // File Route.
            $fileRoute = "/avatars/";            
            $fieldname = "avatarPic";            
            // Get filename.
            $filename = explode(".", $_FILES[$fieldname]["name"]);            
            // Validate uploaded files.
            // Do not use $_FILES["file"]["type"] as it can be easily forged.
            $finfo = finfo_open(FILEINFO_MIME_TYPE);            
            // Get temp file name.
            $tmpName = $_FILES[$fieldname]["tmp_name"];            
            // Get mime type.
            $mimeType = finfo_file($finfo, $tmpName);            
            // Get extension. You must include fileinfo PHP extension.
            $extension = end($filename);            
            // Allowed extensions.
            $allowedExts = array("gif", "jpeg", "jpg", "png", "svg", "blob");            
            // Allowed mime types.
            $allowedMimeTypes = array("image/gif", "image/jpeg", "image/pjpeg", "image/x-png", "image/png", "image/svg+xml");            
            // Validate image.
            if (!in_array(strtolower($mimeType), $allowedMimeTypes) || !in_array(strtolower($extension), $allowedExts)) {
            throw new \Exception("File does not meet the validation.");
            }            
            // Generate new random name.
            $name = sha1(microtime()) . "." . $extension;
            $fullNamePath = "./images/users". $fileRoute . $name;            
            // Check server protocol and load resources accordingly.
            if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] != "off") {
            $protocol = "https://";
            } else {
            $protocol = "http://";
            }            
            // Save file in the uploads folder.
            move_uploaded_file($tmpName, $fullNamePath);            
            // Generate response.
            $response = new \StdClass;
            $response->link = $protocol.$_SERVER["HTTP_HOST"].dirname($_SERVER["PHP_SELF"]).$fileRoute . $name;            
            // Send response.
            echo stripslashes(json_encode($response));
            $db = static::getDBProfiles($fullNamePath);
            $sql = 'INSERT INTO profileAvatars (avatarUID, avatarAlias, avatarPath, avatarCreated)
            VALUES (:avatarUID, :avatarAlias, :avatarPath, :avatarCreated)';
            $stmt = $db->prepare($sql);
            $stmt->bindValue(':avatarUID', $data['avatarUID'], PDO::PARAM_INT);
            $stmt->bindValue(':avatarAlias', $data['avatarAlias'], PDO::PARAM_STR);
            $stmt->bindValue(':avatarPath', $data['avatarPath'], PDO::PARAM_LOB);
            $stmt->bindValue(':avatarCreated', date('Y-m-d H:i:s', time()), PDO::PARAM_STR);  
            return $stmt->execute();            
            } catch (PDOException $e) {
            // Send error response.
            echo $e->getMessage();
            http_response_code(404);
            }
    }    

FROM THE CONTROLLER:

public function uploadAction() {
        if (AvatarModel::uploadAvatar($_POST)) {
            Flash::addMessage('You have successfully created a New Avatar');
            $this->redirect('/avatars');
        } else {
            View::renderTemplate('global/profiles/bits/avatars/new.html');
        }
    }

Thank you

I personally just create a method to insert my data -

  public function create(): bool
    {
        /*
         * Set up the query using prepared statements with named placeholders.
         */
        $sql = 'INSERT INTO ' . $this->table . ' (' . implode(", ", array_keys($this->params)) . ')';
        $sql .= ' VALUES ( :' . implode(', :', array_keys($this->params)) . ')';
        /*
         * Prepare the Database Table:
         */
        $stmt = $this->pdo->prepare($sql); 

        // Bind the corresponding values (including the new PDF fields)
        foreach ($this->params as $key => $value) {
            if ($key === 'id') {
                continue; // Don't include the id
            }
            if ($value === null) {
                $stmt->bindValue(':' . $key, null, PDO::PARAM_NULL);
            } else {
                $stmt->bindValue(':' . $key, $value);
            }
        }

        // Execute the statement and return true if successful, otherwise false
        return $stmt->execute();
    }

and I have created my own error handler →

// Import the ErrorHandler and Database classes from the clearwebconcepts namespace.
use clearwebconcepts\{
    ErrorHandler,
    Database,
    ImageContentManager,
    LoginRepository
};

If I had to guess it is this $stmt->bindValue(':avatarCreated', date('Y-m-d H:i:s', time()), PDO::PARAM_STR); that is causing the problem?

For the date I would simple do something like this $data['date_updated'] = $data['date_added'] = $today->format("Y-m-d H:i:s");

I personally avoid using static methods as much as possible and I personally Intervention Library - use Intervention\Image\ImageManagerStatic as Image; as it makes handling images much easier.

if (($_SERVER['REQUEST_METHOD'] === 'POST') && isset($_FILES['image'])) {
    $data = $_POST['cms'];
    $data['content'] = trim($data['content']);
    $errors = array();
    $exif_data = [];
    $file_name = $_FILES['image']['name']; // Temporary file:
    $file_size = $_FILES['image']['size'];
    $file_tmp = $_FILES['image']['tmp_name'];
    $thumb_tmp = $_FILES['image']['tmp_name'];
    $file_type = $_FILES['image']['type'];
    $file_ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));


    /*
     * Set EXIF data info of image for database table that is
     * if it contains the info otherwise set to null.
     */
    if ($file_ext === 'jpeg' || $file_ext === 'jpg') {

        $exif_data = exif_read_data($file_tmp);


        if (array_key_exists('Make', $exif_data) && array_key_exists('Model', $exif_data)) {
            $data['Model'] = $exif_data['Make'] . ' ' . $exif_data['Model'];
        }

        if (array_key_exists('ExposureTime', $exif_data)) {
            $data['ExposureTime'] = $exif_data['ExposureTime'] . "s";
        }

        if (array_key_exists('ApertureFNumber', $exif_data['COMPUTED'])) {
            $data['Aperture'] = $exif_data['COMPUTED']['ApertureFNumber'];
        }

        if (array_key_exists('ISOSpeedRatings', $exif_data)) {
            $data['ISO'] = "ISO " . $exif_data['ISOSpeedRatings'];
        }

        if (array_key_exists('FocalLengthIn35mmFilm', $exif_data)) {
            $data['FocalLength'] = $exif_data['FocalLengthIn35mmFilm'] . "mm";
        }

    } else {
        $data['Model'] = null;
        $data['ExposureTime'] = null;
        $data['Aperture'] = null;
        $data['ISO'] = null;
        $data['FocalLength'] = null;
    }

    $data['content'] = trim($data['content']);

    $extensions = array("jpeg", "jpg", "png");

    if (in_array($file_ext, $extensions, true) === false) {
        $errors[] = "extension not allowed, please choose a JPEG or PNG file.";
    }

    if ($file_size >= 58720256) {
        $errors[] = 'File size must be less than or equal to 42 MB';
    }

    /*
     * Create unique name for image.
     */
    $image_random_string = bin2hex(random_bytes(16));
    $image_path = 'assets/image_path/img-entry-' . $image_random_string . '-2048x1365' . '.' . $file_ext;
    $thumb_path = 'assets/thumb_path/thumb-entry-' . $image_random_string . '-600x400' . '.' . $file_ext;


    move_uploaded_file($file_tmp, $image_path);
    move_uploaded_file($thumb_tmp, $thumb_path);


    // Load the image
    $image = Image::make($image_path);

    // Resize the image
    $image->resize(2048, 1365, function ($constraint) {
        $constraint->aspectRatio();
        $constraint->upsize();
    });

    // Save the new image
    $image->save($image_path, 100);

    // Load the image with Intervention Image
    $image = Image::make($image_path);

    // Resize the image while maintaining the aspect ratio
    $image->resize(600, 400, function ($constraint) {
        $constraint->aspectRatio();
        $constraint->upsize();
    });

    // Save the thumbnail
    $image->save($thumb_path, 100);


    $data['image_path'] = $image_path;
    $data['thumb_path'] = $thumb_path;


    /*
     * If no errors save ALL the information to the
     * database table.
     */
    if (empty($errors) === true) {
        // Save to Database Table CMS
        $timezone = new DateTimeZone('America/Detroit'); // Use your timezone here
        $today = new DateTime('now', $timezone);
        $data['date_updated'] = $data['date_added'] = $today->format("Y-m-d H:i:s");
        $cms = new ImageContentManager($pdo, $data);
        $result = $cms->create();

        if ($result) {
            header('Content-Type: application/json');
            echo json_encode(['status' => 'success']);
            exit();
        }
    } else {
        if (is_ajax_request()) {
            // Send a JSON response with errors for AJAX requests
            header('Content-Type: application/json');
            echo json_encode(['status' => 'error', 'errors' => $errors]);
        }
    }

}

Thank you Strider64. Your code looks very interesting. I will go through it, try it and get back to you in the next few days.

Regards

The error message you see does not match with the code you have provided.

The error indicates, that public function uploadAction() expects 1 argument, but it doesn’t.
Are you sure that the application is using the correct file / code in the controller?

To me this looks like it maybe has an older version of that file cached or so.
This might be true as well for getting only half of the job done, if the DB part is simply missing in the older version.

Did you switch on OPCache maybe as it is often recommended for performance?
If so, you have to actively clear the cache or set it up in a way that it tracks timestamps of the files correctly.

Sponsor our Newsletter | Privacy Policy | Terms of Service