Questions about an Addon “Data Flow”

Yes, sorry for being so unclear.
What I was trying to archieve was a way to add a “Video URL” to a colum in the Database Table (the Video or file will be uploaded to the server)
I’ve been doing this while looking at the addon “price_per_unit”, cause it seemed to do something similar (adding more data to the products table) because documentation was not so clear about what to do in my case.

  1. I registered the load_products_extra_data hook, as it seemed to be what I wanted, just get an extra field.

  2. Coded the function fn_add_videos_load_products_extra_data to make it load the field (This is where I felt like I could take another turn, cause I dont think this does anything)

function fn_add_videos_load_products_extra_data(array &$extra_fields, array $products, array $product_ids, array $params)
{
    if (!in_array('video_path', $params['extend'])) {
        return;
    }
    $extra_fields['?:products']['fields'][] = 'video_path';
}
  1. Coded the TPL update_product_availability.pre. I made it to add another field to the Product Create form, at the moment its just a simple form, that uploads a file to the server.
{component name="configurable_page.section" entity="products" tab="detailed" section="add_videos"}
    <hr>
    {include file="common/subheader.tpl" title="Video vertical" target="#add_videos"}

    <div id="add_videos" class="collapse in">
        <h5>Video actual: {if $video_name}{$video_name}{else}Ninguno{/if}
            </h5>
        <div class="controls">
            <form enctype="multipart/form-data" method="post">
            <label for="file">Filename:</label>&nbsp;&nbsp;
            <input type="file" name="file" id="file"><br>
            </form>
        </div>
    </div>
{/component} {* detailed :: add_videos *}

Then here it comes what I dont know what is wrong/what to do.
The controller. products.post.php
When the dispatch mode its “update”, this works fine, uploads the file and everything.

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    if($mode == "update" && !empty($_REQUEST['product_id'])){
        if((isset($_FILES["file"])) && ($_FILES["file"]["size"] > 0))
        {
         $fileName = $_FILES["file"]["name"];//the files name takes from the HTML form
         $fileTmpLoc = $_FILES["file"]["tmp_name"];//file in the PHP tmp folder
         $fileErrorMsg = $_FILES["file"]["error"];//0 for false and 1 for true
         $target_path = "./videos/" . basename( $_FILES["file"]["name"]); 
   
         $moveResult = move_uploaded_file($fileTmpLoc, $target_path);

      
         
        $data = array(
            "video_path" => $target_path
         );
         
         db_query("UPDATE ?:products SET ?u WHERE product_id = ?i", $data, $_REQUEST["product_id"]);

        }
    }
}

The problem would be when I try to make it work when the dispatch mode is “add” (creating a new product)

That is mostly the same code, but change the lines $mode == "update" && !empty($_REQUEST['product_id'] to $mode == "add" && !empty($_POST['product_id']

As I understand, when I add the “.post” to the file name, means that it takes place after the product has been inserted into the database, so updating by “product_id” should work.

Another thing I tried is trying to append video_path to the request and Replacing into with the data of the request, still nothing.

I hope I was clearer this time, sorry.
Thanks in advance.

EDIT: Edited the whole post as a suggestion of making it clearer.

Unfortunately, I didn’t understand what you were trying to achieve and how it currently works. Could you please explain this in more detail?

Yes, sorry for being so unclear.
What I was trying to archieve was a way to add a “Video URL” to a colum in the Database Table (the Video or file will be uploaded to the server)
I’ve been doing this while looking at the addon “price_per_unit”, cause it seemed to do something similar (adding more data to the products table) because documentation was not so clear about what to do in my case.

  1. I registered the load_products_extra_data hook, as it seemed to be what I wanted, just get an extra field.

  2. Coded the function fn_add_videos_load_products_extra_data to make it load the field (This is where I felt like I could take another turn, cause I dont think this does anything)

function fn_add_videos_load_products_extra_data(array &$extra_fields, array $products, array $product_ids, array $params)
{
    if (!in_array('video_path', $params['extend'])) {
        return;
    }
    $extra_fields['?:products']['fields'][] = 'video_path';
}
  1. Coded the TPL update_product_availability.pre. I made it to add another field to the Product Create form, at the moment its just a simple form, that uploads a file to the server.
{component name="configurable_page.section" entity="products" tab="detailed" section="add_videos"}
    <hr>
    {include file="common/subheader.tpl" title="Video vertical" target="#add_videos"}

    <div id="add_videos" class="collapse in">
        <h5>Video actual: {if $video_name}{$video_name}{else}Ninguno{/if}
            </h5>
        <div class="controls">
            <form enctype="multipart/form-data" method="post">
            <label for="file">Filename:</label>&nbsp;&nbsp;
            <input type="file" name="file" id="file"><br>
            </form>
        </div>
    </div>
{/component} {* detailed :: add_videos *}

Then here it comes what I dont know what is wrong/what to do.
The controller. products.post.php
When the dispatch mode its “update”, this works fine, uploads the file and everything.

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    if($mode == "update" && !empty($_REQUEST['product_id'])){
        if((isset($_FILES["file"])) && ($_FILES["file"]["size"] > 0))
        {
         $fileName = $_FILES["file"]["name"];//the files name takes from the HTML form
         $fileTmpLoc = $_FILES["file"]["tmp_name"];//file in the PHP tmp folder
         $fileErrorMsg = $_FILES["file"]["error"];//0 for false and 1 for true
         $target_path = "./videos/" . basename( $_FILES["file"]["name"]); 
   
         $moveResult = move_uploaded_file($fileTmpLoc, $target_path);

      
         
        $data = array(
            "video_path" => $target_path
         );
         
         db_query("UPDATE ?:products SET ?u WHERE product_id = ?i", $data, $_REQUEST["product_id"]);

        }
    }
}

The problem would be when I try to make it work when the dispatch mode is “add” (creating a new product)

That is mostly the same code, but change the lines $mode == "update" && !empty($_REQUEST['product_id'] to $mode == "add" && !empty($_POST['product_id']

As I understand, when I add the “.post” to the file name, means that it takes place after the product has been inserted into the database, so updating by “product_id” should work.

Another thing I tried is trying to append video_path to the request and Replacing into with the data of the request, still nothing.

I hope I was clearer this time, sorry.
Thanks in advance.

Ok, I’ve managed to create a new product with the new field value, BUT now it creates TWO entries, one the default one made by the controller and then another one with my values, so then I tried Replacing the values that the default controller is posting in my DB

I dont know how to procceed at this point, so I would really appreciate any help, I think Im struggling to comprehend how all this work and if there is more to “pre” and “post” than just “before” or “after” the default controller.

My code:

/addons/add_videos/backend/controllers/products.post.php

if($mode == "update" ){
        if((isset($_FILES["file"])) && ($_FILES["file"]["size"] > 0))
        {
        //Handling the file
         $fileName = $_FILES["file"]["name"];//the files name takes from the HTML form
         $fileTmpLoc = $_FILES["file"]["tmp_name"];//file in the PHP tmp folder
         $fileType = $_FILES["file"]["type"];//the type of file 
         $fileSize = $_FILES["file"]["size"];//file size in bytes
         $fileErrorMsg = $_FILES["file"]["error"];//0 for false and 1 for true
         $target_path = "./videos/" . basename( $_FILES["file"]["name"]); 
            
         //Uploads File to server
         $moveResult = move_uploaded_file($fileTmpLoc, $target_path);

        //This is the array of product data without the path to the video
        $no_vid = $datos;
        //product_data array with video path
        $datos["video_path"] = $target_path;

        //If it doesnt have product_id means its a new entry
        if(!empty($_REQUEST['product_id'])){
            db_query("UPDATE ?:products SET ?u WHERE product_id = ?i", $data, $_REQUEST["product_id"]);

        }else{
            //Here Im trying to replace whatever the default controller did with my new data. Would Update work better?
            db_query("UPDATE ?:products ?e WHERE ?w", $datos, $no_vid);

        }
        }   
    }   
 
}

This works when updating an existing product, creating a new one with this field is the problem.

But this add-on add_videos, is it developed by you, or some external developer?
In general, if you want to add a new field to products, you don’t need controllers at all - you need a database field, and a template connected to detailed_content_post.tpl hook.

Here’s an example from one of our add-ons:

<div class="control-group {$no_hide_input_if_shared_product}">
    <label for="product_ss_collection_date_hour_from" class="control-label">{__("ss_collection_date_hour_from")}:</label>
    <div class="controls">
        <input class="input-mini" form="form" type="text" name="product_data[ss_collection_date_hour_from]" id="product_ss_collection_date_hour_from" size="55" value="{$product_data.ss_collection_date_hour_from}" />
    </div>
</div>

It’s just a simple input in product configuration.

Best regards,
Robert

Hi!

I can see the issue here that the Update mode in the controller will work twice, since it is called twice: for the POST request and then, for the GET request. So you simply need to wrap this code into the condition that will only work fro the POST requests:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
...
}

I hope it will help you.

1 Like

Hi!
@soft-solid
Yes, the addon is being developed by me, maybe its because the way Smarty works its alien to me, but I dont understand how does it save the value of the form to the database.
In my case, it has to upload a video to the server AND a the value of the route to the DB.
Normally, in other frameworks I’ve worked with I would have to call the controller to handle all this data, but I dont know what I actually have to do with Smarty/CS-Cart.

And thanks @CS-Cart_team for the answer, will try later, for now I made a work around just getting the last entry in the DB and updating it if the Company_ID and the TimeStamp is the same to the current Vendor and Time, and its working… except when Im in the Vendor Page.

Still working on it, thanks to both for the tips!

1 Like

Hello

You are welcome :slight_smile:

Best regards
Robert